From bbd756364f2f343a754180c6ea821f26f1b98ad9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 28 Jul 2010 11:40:38 +0000 Subject: ath9k: fix various calibration related bugs and clean up the code SVN-Revision: 22408 --- .../patches/521-ath9k_no_offchannel_cal.patch | 201 +++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 package/mac80211/patches/521-ath9k_no_offchannel_cal.patch (limited to 'package/mac80211/patches/521-ath9k_no_offchannel_cal.patch') 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 0000000000..5f5d6087d0 --- /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; + } -- cgit v1.2.3