1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- From: Sujith Manoharan <[email protected]>
- Date: Fri, 17 Oct 2014 07:40:29 +0530
- Subject: [PATCH] ath9k: Improve flush() in mcc mode
- The flush timeout in MCC mode is very small, since
- we are constrained by the time slice for each
- channel context, but since only the HW queues are
- flushed when switching contexts, it is acceptable.
- Since the SW queues are also emptied in the mac80211 flush()
- callback, a larger duration is needed. Add an override
- argument to __ath9k_flush() and set it when flush()
- is called in MCC mode. This allows the driver to
- drain both the SW and HW queues.
- Signed-off-by: Sujith Manoharan <[email protected]>
- ---
- --- a/drivers/net/wireless/ath/ath9k/ath9k.h
- +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
- @@ -719,7 +719,7 @@ void ath_update_survey_nf(struct ath_sof
- void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
- void ath_ps_full_sleep(unsigned long data);
- void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
- - bool sw_pending);
- + bool sw_pending, bool timeout_override);
-
- /**********/
- /* BTCOEX */
- --- a/drivers/net/wireless/ath/ath9k/channel.c
- +++ b/drivers/net/wireless/ath/ath9k/channel.c
- @@ -1232,11 +1232,11 @@ void ath_chanctx_set_next(struct ath_sof
- ath9k_chanctx_stop_queues(sc, sc->cur_chan);
- queues_stopped = true;
-
- - __ath9k_flush(sc->hw, ~0, true, false);
- + __ath9k_flush(sc->hw, ~0, true, false, false);
-
- if (ath_chanctx_send_ps_frame(sc, true))
- __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO),
- - false, false);
- + false, false, false);
-
- send_ps = true;
- spin_lock_bh(&sc->chan_lock);
- --- a/drivers/net/wireless/ath/ath9k/main.c
- +++ b/drivers/net/wireless/ath/ath9k/main.c
- @@ -2031,14 +2031,33 @@ static void ath9k_flush(struct ieee80211
- u32 queues, bool drop)
- {
- struct ath_softc *sc = hw->priv;
- + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- +
- + if (ath9k_is_chanctx_enabled()) {
- + if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
- + goto flush;
-
- + /*
- + * If MCC is active, extend the flush timeout
- + * and wait for the HW/SW queues to become
- + * empty. This needs to be done outside the
- + * sc->mutex lock to allow the channel scheduler
- + * to switch channel contexts.
- + *
- + * The vif queues have been stopped in mac80211,
- + * so there won't be any incoming frames.
- + */
- + __ath9k_flush(hw, queues, drop, true, true);
- + return;
- + }
- +flush:
- mutex_lock(&sc->mutex);
- - __ath9k_flush(hw, queues, drop, true);
- + __ath9k_flush(hw, queues, drop, true, false);
- mutex_unlock(&sc->mutex);
- }
-
- void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
- - bool sw_pending)
- + bool sw_pending, bool timeout_override)
- {
- struct ath_softc *sc = hw->priv;
- struct ath_hw *ah = sc->sc_ah;
- @@ -2059,7 +2078,10 @@ void __ath9k_flush(struct ieee80211_hw *
- }
-
- spin_lock_bh(&sc->chan_lock);
- - timeout = sc->cur_chan->flush_timeout;
- + if (timeout_override)
- + timeout = HZ / 5;
- + else
- + timeout = sc->cur_chan->flush_timeout;
- spin_unlock_bh(&sc->chan_lock);
-
- ath_dbg(common, CHAN_CTX,
|