summaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-10-18 17:38:59 +0000
committerFelix Fietkau <nbd@openwrt.org>2014-10-18 17:38:59 +0000
commitf0d9e712e459332ec527802f7eaca104c47b14c2 (patch)
treeb03de3247dbdd3f785bda5318729be5ab75f5f95 /package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch
parent6d3fd947e4aa0430f592e9e3b0eb6b78cbe21f7b (diff)
downloadmaster-31e0f0ae-f0d9e712e459332ec527802f7eaca104c47b14c2.tar.gz
master-31e0f0ae-f0d9e712e459332ec527802f7eaca104c47b14c2.tar.bz2
master-31e0f0ae-f0d9e712e459332ec527802f7eaca104c47b14c2.zip
mac80211: update to 2014-10-08
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 42952
Diffstat (limited to 'package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch')
-rw-r--r--package/kernel/mac80211/patches/324-ath9k-Improve-flush-in-mcc-mode.patch95
1 files changed, 95 insertions, 0 deletions
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 <c_manoha@qca.qualcomm.com>
+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 <c_manoha@qca.qualcomm.com>
+---
+
+--- 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,