325-ath9k-Do-not-start-BA-when-scanning.patch 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. From: Sujith Manoharan <[email protected]>
  2. Date: Fri, 17 Oct 2014 07:40:30 +0530
  3. Subject: [PATCH] ath9k: Do not start BA when scanning
  4. mac80211 currently has a race which can be hit
  5. with this sequence:
  6. * Start a scan operation.
  7. * TX BA is initiated by ieee80211_start_tx_ba_session().
  8. * Driver sets up internal state and calls
  9. ieee80211_start_tx_ba_cb_irqsafe().
  10. * mac80211 adds a packet to sdata->skb_queue with
  11. type IEEE80211_SDATA_QUEUE_AGG_START.
  12. * ieee80211_iface_work() doesn't process the
  13. packet because scan is in progress.
  14. * ADDBA response timer expires and the sta/tid is
  15. torn down.
  16. * Driver receives BA stop notification and calls
  17. ieee80211_stop_tx_ba_cb_irqsafe().
  18. * This is also added to the queue by mac80211.
  19. * Now, scan finishes.
  20. At this point, the queued up packets might be processed
  21. if some other operation schedules the sdata work. Since
  22. the tids have been cleaned up already, warnings are hit.
  23. If this doesn't happen, the packets are left in the queue
  24. until the interface is torn down.
  25. Since initiating a BA session when scan is in progress
  26. leads to flaky connections, especially in MCC mode, we
  27. can drop the TX BA request. This improves connectivity
  28. with legacy clients in MCC mode.
  29. Signed-off-by: Sujith Manoharan <[email protected]>
  30. ---
  31. --- a/drivers/net/wireless/ath/ath9k/main.c
  32. +++ b/drivers/net/wireless/ath/ath9k/main.c
  33. @@ -1885,6 +1885,7 @@ static int ath9k_ampdu_action(struct iee
  34. u16 tid, u16 *ssn, u8 buf_size)
  35. {
  36. struct ath_softc *sc = hw->priv;
  37. + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
  38. bool flush = false;
  39. int ret = 0;
  40. @@ -1896,6 +1897,12 @@ static int ath9k_ampdu_action(struct iee
  41. case IEEE80211_AMPDU_RX_STOP:
  42. break;
  43. case IEEE80211_AMPDU_TX_START:
  44. + if (ath9k_is_chanctx_enabled()) {
  45. + if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
  46. + ret = -EBUSY;
  47. + break;
  48. + }
  49. + }
  50. ath9k_ps_wakeup(sc);
  51. ret = ath_tx_aggr_start(sc, sta, tid, ssn);
  52. if (!ret)