From f0d9e712e459332ec527802f7eaca104c47b14c2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 18 Oct 2014 17:38:59 +0000 Subject: mac80211: update to 2014-10-08 Signed-off-by: Felix Fietkau SVN-Revision: 42952 --- .../324-ath9k-Improve-flush-in-mcc-mode.patch | 95 ++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch (limited to 'package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch') diff --git a/package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch b/package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch new file mode 100644 index 0000000000..40e095b970 --- /dev/null +++ b/package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch @@ -0,0 +1,95 @@ +From: Sujith Manoharan +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 +--- + +--- 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, -- cgit v1.2.3