77024a9d95
Backport most significant upstream fixes (excl. hwsim fixes) Refreshed all patches. Contains important fixes for CSA (Channel Switch Announcement) and A-MSDU frames. Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
78 lines
2.7 KiB
Diff
78 lines
2.7 KiB
Diff
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);
|