324-ath9k-Improve-flush-in-mcc-mode.patch 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. From: Sujith Manoharan <[email protected]>
  2. Date: Fri, 17 Oct 2014 07:40:29 +0530
  3. Subject: [PATCH] ath9k: Improve flush() in mcc mode
  4. The flush timeout in MCC mode is very small, since
  5. we are constrained by the time slice for each
  6. channel context, but since only the HW queues are
  7. flushed when switching contexts, it is acceptable.
  8. Since the SW queues are also emptied in the mac80211 flush()
  9. callback, a larger duration is needed. Add an override
  10. argument to __ath9k_flush() and set it when flush()
  11. is called in MCC mode. This allows the driver to
  12. drain both the SW and HW queues.
  13. Signed-off-by: Sujith Manoharan <[email protected]>
  14. ---
  15. --- a/drivers/net/wireless/ath/ath9k/ath9k.h
  16. +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
  17. @@ -719,7 +719,7 @@ void ath_update_survey_nf(struct ath_sof
  18. void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
  19. void ath_ps_full_sleep(unsigned long data);
  20. void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
  21. - bool sw_pending);
  22. + bool sw_pending, bool timeout_override);
  23. /**********/
  24. /* BTCOEX */
  25. --- a/drivers/net/wireless/ath/ath9k/channel.c
  26. +++ b/drivers/net/wireless/ath/ath9k/channel.c
  27. @@ -1232,11 +1232,11 @@ void ath_chanctx_set_next(struct ath_sof
  28. ath9k_chanctx_stop_queues(sc, sc->cur_chan);
  29. queues_stopped = true;
  30. - __ath9k_flush(sc->hw, ~0, true, false);
  31. + __ath9k_flush(sc->hw, ~0, true, false, false);
  32. if (ath_chanctx_send_ps_frame(sc, true))
  33. __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO),
  34. - false, false);
  35. + false, false, false);
  36. send_ps = true;
  37. spin_lock_bh(&sc->chan_lock);
  38. --- a/drivers/net/wireless/ath/ath9k/main.c
  39. +++ b/drivers/net/wireless/ath/ath9k/main.c
  40. @@ -2031,14 +2031,33 @@ static void ath9k_flush(struct ieee80211
  41. u32 queues, bool drop)
  42. {
  43. struct ath_softc *sc = hw->priv;
  44. + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
  45. +
  46. + if (ath9k_is_chanctx_enabled()) {
  47. + if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
  48. + goto flush;
  49. + /*
  50. + * If MCC is active, extend the flush timeout
  51. + * and wait for the HW/SW queues to become
  52. + * empty. This needs to be done outside the
  53. + * sc->mutex lock to allow the channel scheduler
  54. + * to switch channel contexts.
  55. + *
  56. + * The vif queues have been stopped in mac80211,
  57. + * so there won't be any incoming frames.
  58. + */
  59. + __ath9k_flush(hw, queues, drop, true, true);
  60. + return;
  61. + }
  62. +flush:
  63. mutex_lock(&sc->mutex);
  64. - __ath9k_flush(hw, queues, drop, true);
  65. + __ath9k_flush(hw, queues, drop, true, false);
  66. mutex_unlock(&sc->mutex);
  67. }
  68. void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
  69. - bool sw_pending)
  70. + bool sw_pending, bool timeout_override)
  71. {
  72. struct ath_softc *sc = hw->priv;
  73. struct ath_hw *ah = sc->sc_ah;
  74. @@ -2059,7 +2078,10 @@ void __ath9k_flush(struct ieee80211_hw *
  75. }
  76. spin_lock_bh(&sc->chan_lock);
  77. - timeout = sc->cur_chan->flush_timeout;
  78. + if (timeout_override)
  79. + timeout = HZ / 5;
  80. + else
  81. + timeout = sc->cur_chan->flush_timeout;
  82. spin_unlock_bh(&sc->chan_lock);
  83. ath_dbg(common, CHAN_CTX,