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
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.
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.
13 Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
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)
21 struct ath_softc *sc = hw->priv;
22 + struct ath_vif *avp = (void *)vif->drv_priv;
25 mutex_lock(&sc->mutex);
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);
32 + tsf = sc->cur_chan->tsf_val +
33 + ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
36 mutex_unlock(&sc->mutex);
38 @@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee802
41 struct ath_softc *sc = hw->priv;
42 + struct ath_vif *avp = (void *)vif->drv_priv;
44 mutex_lock(&sc->mutex);
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;
52 mutex_unlock(&sc->mutex);
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)
57 struct ath_softc *sc = hw->priv;
58 + struct ath_vif *avp = (void *)vif->drv_priv;
60 mutex_lock(&sc->mutex);
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;
70 mutex_unlock(&sc->mutex);