summaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2016-07-05 10:45:17 +0200
committerFelix Fietkau <nbd@nbd.name>2016-07-05 10:45:17 +0200
commit92d856f50a71d0376e491644894507458bc26050 (patch)
tree78191f330ece4bd2412b327135fb43a751af8aa0 /package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch
parent71753a8286dcb4dedbb6d4792b0fd5dd305c3338 (diff)
downloadmaster-31e0f0ae-92d856f50a71d0376e491644894507458bc26050.tar.gz
master-31e0f0ae-92d856f50a71d0376e491644894507458bc26050.tar.bz2
master-31e0f0ae-92d856f50a71d0376e491644894507458bc26050.zip
ath9k: add beacon related stability fixes
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch')
-rw-r--r--package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch70
1 files changed, 70 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch b/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch
new file mode 100644
index 0000000000..ef0afbea9c
--- /dev/null
+++ b/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch
@@ -0,0 +1,70 @@
+From: Benjamin Berg <benjamin.berg@open-mesh.com>
+Date: Mon, 4 Jul 2016 14:37:21 +0200
+Subject: [PATCH] ath9k: Handle channel context in get_/set_/reset_tsf
+
+The ath9k TSF handling routines need to be aware of the channel context that
+is being modified. With this change the TSF related values that are stored
+in each channel context will be correctly tracked and the harware will only
+be updated if the modified context is currently the active one.
+
+Without this change the TSF modifications done using these routines would
+for example be lost during a hardware reset as done by ath_complete_reset.
+
+Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1823,11 +1823,18 @@ static void ath9k_bss_info_changed(struc
+ static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ {
+ struct ath_softc *sc = hw->priv;
++ struct ath_vif *avp = (void *)vif->drv_priv;
+ u64 tsf;
+
+ mutex_lock(&sc->mutex);
+ ath9k_ps_wakeup(sc);
+- tsf = ath9k_hw_gettsf64(sc->sc_ah);
++ /* Get current TSF either from HW or kernel time. */
++ if (sc->cur_chan == avp->chanctx) {
++ tsf = ath9k_hw_gettsf64(sc->sc_ah);
++ } else {
++ tsf = sc->cur_chan->tsf_val +
++ ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
++ }
+ ath9k_ps_restore(sc);
+ mutex_unlock(&sc->mutex);
+
+@@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee802
+ u64 tsf)
+ {
+ struct ath_softc *sc = hw->priv;
++ struct ath_vif *avp = (void *)vif->drv_priv;
+
+ mutex_lock(&sc->mutex);
+ ath9k_ps_wakeup(sc);
+- ath9k_hw_settsf64(sc->sc_ah, tsf);
++ getrawmonotonic(&avp->chanctx->tsf_ts);
++ if (sc->cur_chan == avp->chanctx)
++ ath9k_hw_settsf64(sc->sc_ah, tsf);
++ avp->chanctx->tsf_val = tsf;
+ ath9k_ps_restore(sc);
+ mutex_unlock(&sc->mutex);
+ }
+@@ -1850,11 +1861,15 @@ static void ath9k_set_tsf(struct ieee802
+ static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ {
+ struct ath_softc *sc = hw->priv;
++ struct ath_vif *avp = (void *)vif->drv_priv;
+
+ mutex_lock(&sc->mutex);
+
+ ath9k_ps_wakeup(sc);
+- ath9k_hw_reset_tsf(sc->sc_ah);
++ getrawmonotonic(&avp->chanctx->tsf_ts);
++ if (sc->cur_chan == avp->chanctx)
++ ath9k_hw_reset_tsf(sc->sc_ah);
++ avp->chanctx->tsf_val = 0;
+ ath9k_ps_restore(sc);
+
+ mutex_unlock(&sc->mutex);