diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 73 |
2 files changed, 40 insertions, 35 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 998ae2c49ed..11fc69bee58 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -510,7 +510,7 @@ void ath_deinit_leds(struct ath_softc *sc); | |||
510 | #define SC_OP_BEACONS BIT(1) | 510 | #define SC_OP_BEACONS BIT(1) |
511 | #define SC_OP_RXAGGR BIT(2) | 511 | #define SC_OP_RXAGGR BIT(2) |
512 | #define SC_OP_TXAGGR BIT(3) | 512 | #define SC_OP_TXAGGR BIT(3) |
513 | #define SC_OP_FULL_RESET BIT(4) | 513 | #define SC_OP_OFFCHANNEL BIT(4) |
514 | #define SC_OP_PREAMBLE_SHORT BIT(5) | 514 | #define SC_OP_PREAMBLE_SHORT BIT(5) |
515 | #define SC_OP_PROTECT_ENABLE BIT(6) | 515 | #define SC_OP_PROTECT_ENABLE BIT(6) |
516 | #define SC_OP_RXFLUSH BIT(7) | 516 | #define SC_OP_RXFLUSH BIT(7) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6c1d9ef550d..8387ad5b489 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -154,6 +154,27 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
154 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 154 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
155 | } | 155 | } |
156 | 156 | ||
157 | static void ath_start_ani(struct ath_common *common) | ||
158 | { | ||
159 | struct ath_hw *ah = common->ah; | ||
160 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
161 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
162 | |||
163 | if (!(sc->sc_flags & SC_OP_ANI_RUN)) | ||
164 | return; | ||
165 | |||
166 | if (sc->sc_flags & SC_OP_OFFCHANNEL) | ||
167 | return; | ||
168 | |||
169 | common->ani.longcal_timer = timestamp; | ||
170 | common->ani.shortcal_timer = timestamp; | ||
171 | common->ani.checkani_timer = timestamp; | ||
172 | |||
173 | mod_timer(&common->ani.timer, | ||
174 | jiffies + | ||
175 | msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
176 | } | ||
177 | |||
157 | /* | 178 | /* |
158 | * Set/change channels. If the channel is really being changed, it's done | 179 | * Set/change channels. If the channel is really being changed, it's done |
159 | * by reseting the chip. To accomplish this we must first cleanup any pending | 180 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -172,6 +193,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
172 | if (sc->sc_flags & SC_OP_INVALID) | 193 | if (sc->sc_flags & SC_OP_INVALID) |
173 | return -EIO; | 194 | return -EIO; |
174 | 195 | ||
196 | del_timer_sync(&common->ani.timer); | ||
197 | cancel_work_sync(&sc->paprd_work); | ||
198 | cancel_work_sync(&sc->hw_check_work); | ||
199 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
200 | |||
175 | ath9k_ps_wakeup(sc); | 201 | ath9k_ps_wakeup(sc); |
176 | 202 | ||
177 | /* | 203 | /* |
@@ -191,7 +217,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
191 | * to flush data frames already in queue because of | 217 | * to flush data frames already in queue because of |
192 | * changing channel. */ | 218 | * changing channel. */ |
193 | 219 | ||
194 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | 220 | if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL)) |
195 | fastcc = false; | 221 | fastcc = false; |
196 | 222 | ||
197 | ath_print(common, ATH_DBG_CONFIG, | 223 | ath_print(common, ATH_DBG_CONFIG, |
@@ -212,8 +238,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
212 | } | 238 | } |
213 | spin_unlock_bh(&sc->sc_resetlock); | 239 | spin_unlock_bh(&sc->sc_resetlock); |
214 | 240 | ||
215 | sc->sc_flags &= ~SC_OP_FULL_RESET; | ||
216 | |||
217 | if (ath_startrecv(sc) != 0) { | 241 | if (ath_startrecv(sc) != 0) { |
218 | ath_print(common, ATH_DBG_FATAL, | 242 | ath_print(common, ATH_DBG_FATAL, |
219 | "Unable to restart recv logic\n"); | 243 | "Unable to restart recv logic\n"); |
@@ -225,6 +249,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
225 | ath_update_txpow(sc); | 249 | ath_update_txpow(sc); |
226 | ath9k_hw_set_interrupts(ah, ah->imask); | 250 | ath9k_hw_set_interrupts(ah, ah->imask); |
227 | 251 | ||
252 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { | ||
253 | ath_start_ani(common); | ||
254 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
255 | ath_beacon_config(sc, NULL); | ||
256 | } | ||
257 | |||
228 | ps_restore: | 258 | ps_restore: |
229 | ath9k_ps_restore(sc); | 259 | ath9k_ps_restore(sc); |
230 | return r; | 260 | return r; |
@@ -440,8 +470,7 @@ set_timer: | |||
440 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 470 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
441 | 471 | ||
442 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | 472 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); |
443 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && | 473 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) { |
444 | !(sc->sc_flags & SC_OP_SCANNING)) { | ||
445 | if (!sc->sc_ah->curchan->paprd_done) | 474 | if (!sc->sc_ah->curchan->paprd_done) |
446 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | 475 | ieee80211_queue_work(sc->hw, &sc->paprd_work); |
447 | else | 476 | else |
@@ -449,24 +478,6 @@ set_timer: | |||
449 | } | 478 | } |
450 | } | 479 | } |
451 | 480 | ||
452 | static void ath_start_ani(struct ath_common *common) | ||
453 | { | ||
454 | struct ath_hw *ah = common->ah; | ||
455 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
456 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
457 | |||
458 | if (!(sc->sc_flags & SC_OP_ANI_RUN)) | ||
459 | return; | ||
460 | |||
461 | common->ani.longcal_timer = timestamp; | ||
462 | common->ani.shortcal_timer = timestamp; | ||
463 | common->ani.checkani_timer = timestamp; | ||
464 | |||
465 | mod_timer(&common->ani.timer, | ||
466 | jiffies + | ||
467 | msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
468 | } | ||
469 | |||
470 | /* | 481 | /* |
471 | * Update tx/rx chainmask. For legacy association, | 482 | * Update tx/rx chainmask. For legacy association, |
472 | * hard code chainmask to 1x1, for 11n association, use | 483 | * hard code chainmask to 1x1, for 11n association, use |
@@ -478,7 +489,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) | |||
478 | struct ath_hw *ah = sc->sc_ah; | 489 | struct ath_hw *ah = sc->sc_ah; |
479 | struct ath_common *common = ath9k_hw_common(ah); | 490 | struct ath_common *common = ath9k_hw_common(ah); |
480 | 491 | ||
481 | if ((sc->sc_flags & SC_OP_SCANNING) || is_ht || | 492 | if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht || |
482 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { | 493 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { |
483 | common->tx_chainmask = ah->caps.tx_chainmask; | 494 | common->tx_chainmask = ah->caps.tx_chainmask; |
484 | common->rx_chainmask = ah->caps.rx_chainmask; | 495 | common->rx_chainmask = ah->caps.rx_chainmask; |
@@ -1580,6 +1591,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1580 | 1591 | ||
1581 | aphy->chan_idx = pos; | 1592 | aphy->chan_idx = pos; |
1582 | aphy->chan_is_ht = conf_is_ht(conf); | 1593 | aphy->chan_is_ht = conf_is_ht(conf); |
1594 | if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | ||
1595 | sc->sc_flags |= SC_OP_OFFCHANNEL; | ||
1596 | else | ||
1597 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | ||
1583 | 1598 | ||
1584 | if (aphy->state == ATH_WIPHY_SCAN || | 1599 | if (aphy->state == ATH_WIPHY_SCAN || |
1585 | aphy->state == ATH_WIPHY_ACTIVE) | 1600 | aphy->state == ATH_WIPHY_ACTIVE) |
@@ -1991,7 +2006,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
1991 | { | 2006 | { |
1992 | struct ath_wiphy *aphy = hw->priv; | 2007 | struct ath_wiphy *aphy = hw->priv; |
1993 | struct ath_softc *sc = aphy->sc; | 2008 | struct ath_softc *sc = aphy->sc; |
1994 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1995 | 2009 | ||
1996 | mutex_lock(&sc->mutex); | 2010 | mutex_lock(&sc->mutex); |
1997 | if (ath9k_wiphy_scanning(sc)) { | 2011 | if (ath9k_wiphy_scanning(sc)) { |
@@ -2009,10 +2023,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
2009 | aphy->state = ATH_WIPHY_SCAN; | 2023 | aphy->state = ATH_WIPHY_SCAN; |
2010 | ath9k_wiphy_pause_all_forced(sc, aphy); | 2024 | ath9k_wiphy_pause_all_forced(sc, aphy); |
2011 | sc->sc_flags |= SC_OP_SCANNING; | 2025 | sc->sc_flags |= SC_OP_SCANNING; |
2012 | del_timer_sync(&common->ani.timer); | ||
2013 | cancel_work_sync(&sc->paprd_work); | ||
2014 | cancel_work_sync(&sc->hw_check_work); | ||
2015 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
2016 | mutex_unlock(&sc->mutex); | 2026 | mutex_unlock(&sc->mutex); |
2017 | } | 2027 | } |
2018 | 2028 | ||
@@ -2024,15 +2034,10 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
2024 | { | 2034 | { |
2025 | struct ath_wiphy *aphy = hw->priv; | 2035 | struct ath_wiphy *aphy = hw->priv; |
2026 | struct ath_softc *sc = aphy->sc; | 2036 | struct ath_softc *sc = aphy->sc; |
2027 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2028 | 2037 | ||
2029 | mutex_lock(&sc->mutex); | 2038 | mutex_lock(&sc->mutex); |
2030 | aphy->state = ATH_WIPHY_ACTIVE; | 2039 | aphy->state = ATH_WIPHY_ACTIVE; |
2031 | sc->sc_flags &= ~SC_OP_SCANNING; | 2040 | sc->sc_flags &= ~SC_OP_SCANNING; |
2032 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2033 | ath_start_ani(common); | ||
2034 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
2035 | ath_beacon_config(sc, NULL); | ||
2036 | mutex_unlock(&sc->mutex); | 2041 | mutex_unlock(&sc->mutex); |
2037 | } | 2042 | } |
2038 | 2043 | ||