diff options
Diffstat (limited to 'package/kernel/mac80211/patches/311-ath9k-Fix-MCC-flush-timeout.patch')
-rw-r--r-- | package/kernel/mac80211/patches/311-ath9k-Fix-MCC-flush-timeout.patch | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/311-ath9k-Fix-MCC-flush-timeout.patch b/package/kernel/mac80211/patches/311-ath9k-Fix-MCC-flush-timeout.patch new file mode 100644 index 0000000..020ac1a --- /dev/null +++ b/package/kernel/mac80211/patches/311-ath9k-Fix-MCC-flush-timeout.patch @@ -0,0 +1,68 @@ +From: Sujith Manoharan <c_manoha@qca.qualcomm.com> +Date: Fri, 17 Oct 2014 07:40:16 +0530 +Subject: [PATCH] ath9k: Fix MCC flush timeout + +In MCC mode, the duration for a channel context +is half the beacon interval and having a large +flush timeout will adversely affect GO operation, +since the default value of 200ms will overshoot +the advertised NoA absence duration. + +The scheduler initiates a channel context switch +only when the slot duration for the current +context expires, so there is no possibility of +having a fixed timeout for flush. + +Since the channel_switch_time is added to the +absence duration when the GO sets up the NoA +attribute, this is the maximum time that we +have to flush the TX queues. The duration is very +small, but we don't have a choice in MCC mode. + +Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> +--- + +--- a/drivers/net/wireless/ath/ath9k/channel.c ++++ b/drivers/net/wireless/ath/ath9k/channel.c +@@ -199,6 +199,7 @@ static const char *chanctx_state_string( + void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) + { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ struct ath_chanctx *ictx; + struct ath_vif *avp; + bool active = false; + u8 n_active = 0; +@@ -206,6 +207,8 @@ void ath_chanctx_check_active(struct ath + if (!ctx) + return; + ++ ictx = ctx; ++ + list_for_each_entry(avp, &ctx->vifs, list) { + struct ieee80211_vif *vif = avp->vif; + +@@ -228,12 +231,23 @@ void ath_chanctx_check_active(struct ath + n_active++; + } + ++ spin_lock_bh(&sc->chan_lock); ++ + if (n_active <= 1) { ++ ictx->flush_timeout = HZ / 5; + clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags); ++ spin_unlock_bh(&sc->chan_lock); + return; + } +- if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) ++ ++ ictx->flush_timeout = usecs_to_jiffies(sc->sched.channel_switch_time); ++ ++ if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) { ++ spin_unlock_bh(&sc->chan_lock); + return; ++ } ++ ++ spin_unlock_bh(&sc->chan_lock); + + if (ath9k_is_chanctx_enabled()) { + ath_chanctx_event(sc, NULL, |