summaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/521-ath9k_no_offchannel_cal.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/521-ath9k_no_offchannel_cal.patch')
-rw-r--r--package/mac80211/patches/521-ath9k_no_offchannel_cal.patch201
1 files changed, 201 insertions, 0 deletions
diff --git a/package/mac80211/patches/521-ath9k_no_offchannel_cal.patch b/package/mac80211/patches/521-ath9k_no_offchannel_cal.patch
new file mode 100644
index 000000000..5f5d6087d
--- /dev/null
+++ b/package/mac80211/patches/521-ath9k_no_offchannel_cal.patch
@@ -0,0 +1,201 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -511,13 +511,12 @@ void ath_deinit_leds(struct ath_softc *s
+ #define SC_OP_BEACONS BIT(1)
+ #define SC_OP_RXAGGR BIT(2)
+ #define SC_OP_TXAGGR BIT(3)
+-#define SC_OP_FULL_RESET BIT(4)
+ #define SC_OP_PREAMBLE_SHORT BIT(5)
+ #define SC_OP_PROTECT_ENABLE BIT(6)
+ #define SC_OP_RXFLUSH BIT(7)
+ #define SC_OP_LED_ASSOCIATED BIT(8)
+ #define SC_OP_LED_ON BIT(9)
+-#define SC_OP_SCANNING BIT(10)
++#define SC_OP_OFFCHANNEL BIT(10)
+ #define SC_OP_TSF_RESET BIT(11)
+ #define SC_OP_BT_PRIORITY_DETECTED BIT(12)
+ #define SC_OP_BT_SCAN BIT(13)
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -155,6 +155,27 @@ void ath9k_ps_restore(struct ath_softc *
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+ }
+
++static void ath_start_ani(struct ath_common *common)
++{
++ struct ath_hw *ah = common->ah;
++ unsigned long timestamp = jiffies_to_msecs(jiffies);
++ struct ath_softc *sc = (struct ath_softc *) common->priv;
++
++ if (!(sc->sc_flags & SC_OP_ANI_RUN))
++ return;
++
++ if (sc->sc_flags & SC_OP_OFFCHANNEL)
++ return;
++
++ common->ani.longcal_timer = timestamp;
++ common->ani.shortcal_timer = timestamp;
++ common->ani.checkani_timer = timestamp;
++
++ mod_timer(&common->ani.timer,
++ jiffies +
++ msecs_to_jiffies((u32)ah->config.ani_poll_interval));
++}
++
+ /*
+ * Set/change channels. If the channel is really being changed, it's done
+ * by reseting the chip. To accomplish this we must first cleanup any pending
+@@ -173,6 +194,11 @@ int ath_set_channel(struct ath_softc *sc
+ if (sc->sc_flags & SC_OP_INVALID)
+ return -EIO;
+
++ del_timer_sync(&common->ani.timer);
++ cancel_work_sync(&sc->paprd_work);
++ cancel_work_sync(&sc->hw_check_work);
++ cancel_delayed_work_sync(&sc->tx_complete_work);
++
+ ath9k_ps_wakeup(sc);
+
+ /*
+@@ -192,7 +218,7 @@ int ath_set_channel(struct ath_softc *sc
+ * to flush data frames already in queue because of
+ * changing channel. */
+
+- if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
++ if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
+ fastcc = false;
+
+ ath_print(common, ATH_DBG_CONFIG,
+@@ -213,8 +239,6 @@ int ath_set_channel(struct ath_softc *sc
+ }
+ spin_unlock_bh(&sc->sc_resetlock);
+
+- sc->sc_flags &= ~SC_OP_FULL_RESET;
+-
+ if (ath_startrecv(sc) != 0) {
+ ath_print(common, ATH_DBG_FATAL,
+ "Unable to restart recv logic\n");
+@@ -226,6 +250,12 @@ int ath_set_channel(struct ath_softc *sc
+ ath_update_txpow(sc);
+ ath9k_hw_set_interrupts(ah, ah->imask);
+
++ if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) {
++ ath_start_ani(common);
++ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
++ ath_beacon_config(sc, NULL);
++ }
++
+ ps_restore:
+ ath9k_ps_restore(sc);
+ return r;
+@@ -440,8 +470,7 @@ set_timer:
+ cal_interval = min(cal_interval, (u32)short_cal_interval);
+
+ mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
+- !(sc->sc_flags & SC_OP_SCANNING)) {
++ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) {
+ if (!sc->sc_ah->curchan->paprd_done)
+ ieee80211_queue_work(sc->hw, &sc->paprd_work);
+ else
+@@ -449,24 +478,6 @@ set_timer:
+ }
+ }
+
+-static void ath_start_ani(struct ath_common *common)
+-{
+- struct ath_hw *ah = common->ah;
+- unsigned long timestamp = jiffies_to_msecs(jiffies);
+- struct ath_softc *sc = (struct ath_softc *) common->priv;
+-
+- if (!(sc->sc_flags & SC_OP_ANI_RUN))
+- return;
+-
+- common->ani.longcal_timer = timestamp;
+- common->ani.shortcal_timer = timestamp;
+- common->ani.checkani_timer = timestamp;
+-
+- mod_timer(&common->ani.timer,
+- jiffies +
+- msecs_to_jiffies((u32)ah->config.ani_poll_interval));
+-}
+-
+ /*
+ * Update tx/rx chainmask. For legacy association,
+ * hard code chainmask to 1x1, for 11n association, use
+@@ -478,7 +489,7 @@ void ath_update_chainmask(struct ath_sof
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+
+- if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
++ if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
+ (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
+ common->tx_chainmask = ah->caps.tx_chainmask;
+ common->rx_chainmask = ah->caps.rx_chainmask;
+@@ -1580,6 +1591,10 @@ static int ath9k_config(struct ieee80211
+
+ aphy->chan_idx = pos;
+ aphy->chan_is_ht = conf_is_ht(conf);
++ if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
++ sc->sc_flags |= SC_OP_OFFCHANNEL;
++ else
++ sc->sc_flags &= ~SC_OP_OFFCHANNEL;
+
+ if (aphy->state == ATH_WIPHY_SCAN ||
+ aphy->state == ATH_WIPHY_ACTIVE)
+@@ -1991,7 +2006,6 @@ static void ath9k_sw_scan_start(struct i
+ {
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+ mutex_lock(&sc->mutex);
+ if (ath9k_wiphy_scanning(sc)) {
+@@ -2007,11 +2021,6 @@ static void ath9k_sw_scan_start(struct i
+
+ aphy->state = ATH_WIPHY_SCAN;
+ ath9k_wiphy_pause_all_forced(sc, aphy);
+- sc->sc_flags |= SC_OP_SCANNING;
+- del_timer_sync(&common->ani.timer);
+- cancel_work_sync(&sc->paprd_work);
+- cancel_work_sync(&sc->hw_check_work);
+- cancel_delayed_work_sync(&sc->tx_complete_work);
+ mutex_unlock(&sc->mutex);
+ }
+
+@@ -2019,15 +2028,9 @@ static void ath9k_sw_scan_complete(struc
+ {
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+ mutex_lock(&sc->mutex);
+ aphy->state = ATH_WIPHY_ACTIVE;
+- sc->sc_flags &= ~SC_OP_SCANNING;
+- sc->sc_flags |= SC_OP_FULL_RESET;
+- ath_start_ani(common);
+- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+- ath_beacon_config(sc, NULL);
+ mutex_unlock(&sc->mutex);
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -292,7 +292,7 @@ static void ath_edma_start_recv(struct a
+
+ ath_opmode_init(sc);
+
+- ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING));
++ ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
+ }
+
+ static void ath_edma_stop_recv(struct ath_softc *sc)
+@@ -498,7 +498,7 @@ int ath_startrecv(struct ath_softc *sc)
+ start_recv:
+ spin_unlock_bh(&sc->rx.rxbuflock);
+ ath_opmode_init(sc);
+- ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING));
++ ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
+
+ return 0;
+ }