diff options
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.patch | 78 |
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); |