package/devel/binutils: Update to 2.27
[openwrt/staging/chunkeey.git] / package / kernel / mac80211 / patches / 313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch
1 From: Benjamin Berg <benjamin.berg@open-mesh.com>
2 Date: Mon, 4 Jul 2016 14:37:21 +0200
3 Subject: [PATCH] ath9k: Handle channel context in get_/set_/reset_tsf
4
5 The ath9k TSF handling routines need to be aware of the channel context that
6 is being modified. With this change the TSF related values that are stored
7 in each channel context will be correctly tracked and the harware will only
8 be updated if the modified context is currently the active one.
9
10 Without this change the TSF modifications done using these routines would
11 for example be lost during a hardware reset as done by ath_complete_reset.
12
13 Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
14 ---
15
16 --- a/drivers/net/wireless/ath/ath9k/main.c
17 +++ b/drivers/net/wireless/ath/ath9k/main.c
18 @@ -1823,11 +1823,18 @@ static void ath9k_bss_info_changed(struc
19 static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
20 {
21 struct ath_softc *sc = hw->priv;
22 + struct ath_vif *avp = (void *)vif->drv_priv;
23 u64 tsf;
24
25 mutex_lock(&sc->mutex);
26 ath9k_ps_wakeup(sc);
27 - tsf = ath9k_hw_gettsf64(sc->sc_ah);
28 + /* Get current TSF either from HW or kernel time. */
29 + if (sc->cur_chan == avp->chanctx) {
30 + tsf = ath9k_hw_gettsf64(sc->sc_ah);
31 + } else {
32 + tsf = sc->cur_chan->tsf_val +
33 + ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
34 + }
35 ath9k_ps_restore(sc);
36 mutex_unlock(&sc->mutex);
37
38 @@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee802
39 u64 tsf)
40 {
41 struct ath_softc *sc = hw->priv;
42 + struct ath_vif *avp = (void *)vif->drv_priv;
43
44 mutex_lock(&sc->mutex);
45 ath9k_ps_wakeup(sc);
46 - ath9k_hw_settsf64(sc->sc_ah, tsf);
47 + getrawmonotonic(&avp->chanctx->tsf_ts);
48 + if (sc->cur_chan == avp->chanctx)
49 + ath9k_hw_settsf64(sc->sc_ah, tsf);
50 + avp->chanctx->tsf_val = tsf;
51 ath9k_ps_restore(sc);
52 mutex_unlock(&sc->mutex);
53 }
54 @@ -1850,11 +1861,15 @@ static void ath9k_set_tsf(struct ieee802
55 static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
56 {
57 struct ath_softc *sc = hw->priv;
58 + struct ath_vif *avp = (void *)vif->drv_priv;
59
60 mutex_lock(&sc->mutex);
61
62 ath9k_ps_wakeup(sc);
63 - ath9k_hw_reset_tsf(sc->sc_ah);
64 + getrawmonotonic(&avp->chanctx->tsf_ts);
65 + if (sc->cur_chan == avp->chanctx)
66 + ath9k_hw_reset_tsf(sc->sc_ah);
67 + avp->chanctx->tsf_val = 0;
68 ath9k_ps_restore(sc);
69
70 mutex_unlock(&sc->mutex);