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