aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c73
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
157static 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
452static 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