392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. From: Emmanuel Grumbach <[email protected]>
  2. Date: Fri, 31 Aug 2018 11:31:12 +0300
  3. Subject: [PATCH] mac80211: don't Tx a deauth frame if the AP forbade Tx
  4. If the driver fails to properly prepare for the channel
  5. switch, mac80211 will disconnect. If the CSA IE had mode
  6. set to 1, it means that the clients are not allowed to send
  7. any Tx on the current channel, and that includes the
  8. deauthentication frame.
  9. Make sure that we don't send the deauthentication frame in
  10. this case.
  11. In iwlwifi, this caused a failure to flush queues since the
  12. firmware already closed the queues after having parsed the
  13. CSA IE. Then mac80211 would wait until the deauthentication
  14. frame would go out (drv_flush(drop=false)) and that would
  15. never happen.
  16. Signed-off-by: Emmanuel Grumbach <[email protected]>
  17. Signed-off-by: Luca Coelho <[email protected]>
  18. Signed-off-by: Johannes Berg <[email protected]>
  19. ---
  20. --- a/net/mac80211/mlme.c
  21. +++ b/net/mac80211/mlme.c
  22. @@ -1267,6 +1267,16 @@ ieee80211_sta_process_chanswitch(struct
  23. cbss->beacon_interval));
  24. return;
  25. drop_connection:
  26. + /*
  27. + * This is just so that the disconnect flow will know that
  28. + * we were trying to switch channel and failed. In case the
  29. + * mode is 1 (we are not allowed to Tx), we will know not to
  30. + * send a deauthentication frame. Those two fields will be
  31. + * reset when the disconnection worker runs.
  32. + */
  33. + sdata->vif.csa_active = true;
  34. + sdata->csa_block_tx = csa_ie.mode;
  35. +
  36. ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
  37. mutex_unlock(&local->chanctx_mtx);
  38. mutex_unlock(&local->mtx);
  39. @@ -2437,6 +2447,7 @@ static void __ieee80211_disconnect(struc
  40. struct ieee80211_local *local = sdata->local;
  41. struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  42. u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
  43. + bool tx;
  44. sdata_lock(sdata);
  45. if (!ifmgd->associated) {
  46. @@ -2444,6 +2455,8 @@ static void __ieee80211_disconnect(struc
  47. return;
  48. }
  49. + tx = !sdata->csa_block_tx;
  50. +
  51. /* AP is probably out of range (or not reachable for another reason) so
  52. * remove the bss struct for that AP.
  53. */
  54. @@ -2451,7 +2464,7 @@ static void __ieee80211_disconnect(struc
  55. ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
  56. WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
  57. - true, frame_buf);
  58. + tx, frame_buf);
  59. mutex_lock(&local->mtx);
  60. sdata->vif.csa_active = false;
  61. ifmgd->csa_waiting_bcn = false;
  62. @@ -2462,7 +2475,7 @@ static void __ieee80211_disconnect(struc
  63. }
  64. mutex_unlock(&local->mtx);
  65. - ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
  66. + ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
  67. WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
  68. sdata_unlock(sdata);