aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch')
-rw-r--r--package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch78
1 files changed, 78 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch b/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch
new file mode 100644
index 0000000000..74dd3d3775
--- /dev/null
+++ b/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch
@@ -0,0 +1,78 @@
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Fri, 31 Aug 2018 11:31:12 +0300
+Subject: [PATCH] mac80211: don't Tx a deauth frame if the AP forbade Tx
+
+If the driver fails to properly prepare for the channel
+switch, mac80211 will disconnect. If the CSA IE had mode
+set to 1, it means that the clients are not allowed to send
+any Tx on the current channel, and that includes the
+deauthentication frame.
+
+Make sure that we don't send the deauthentication frame in
+this case.
+
+In iwlwifi, this caused a failure to flush queues since the
+firmware already closed the queues after having parsed the
+CSA IE. Then mac80211 would wait until the deauthentication
+frame would go out (drv_flush(drop=false)) and that would
+never happen.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1267,6 +1267,16 @@ ieee80211_sta_process_chanswitch(struct
+ cbss->beacon_interval));
+ return;
+ drop_connection:
++ /*
++ * This is just so that the disconnect flow will know that
++ * we were trying to switch channel and failed. In case the
++ * mode is 1 (we are not allowed to Tx), we will know not to
++ * send a deauthentication frame. Those two fields will be
++ * reset when the disconnection worker runs.
++ */
++ sdata->vif.csa_active = true;
++ sdata->csa_block_tx = csa_ie.mode;
++
+ ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
+ mutex_unlock(&local->chanctx_mtx);
+ mutex_unlock(&local->mtx);
+@@ -2437,6 +2447,7 @@ static void __ieee80211_disconnect(struc
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
++ bool tx;
+
+ sdata_lock(sdata);
+ if (!ifmgd->associated) {
+@@ -2444,6 +2455,8 @@ static void __ieee80211_disconnect(struc
+ return;
+ }
+
++ tx = !sdata->csa_block_tx;
++
+ /* AP is probably out of range (or not reachable for another reason) so
+ * remove the bss struct for that AP.
+ */
+@@ -2451,7 +2464,7 @@ static void __ieee80211_disconnect(struc
+
+ ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+- true, frame_buf);
++ tx, frame_buf);
+ mutex_lock(&local->mtx);
+ sdata->vif.csa_active = false;
+ ifmgd->csa_waiting_bcn = false;
+@@ -2462,7 +2475,7 @@ static void __ieee80211_disconnect(struc
+ }
+ mutex_unlock(&local->mtx);
+
+- ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
++ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
+
+ sdata_unlock(sdata);