diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a8d9009a76d5..c3dbf2661a3f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -624,6 +624,43 @@ out: | |||
624 | ath9k_ps_restore(sc); | 624 | ath9k_ps_restore(sc); |
625 | } | 625 | } |
626 | 626 | ||
627 | static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
628 | { | ||
629 | static int count; | ||
630 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
631 | |||
632 | if (pll_sqsum >= 0x40000) { | ||
633 | count++; | ||
634 | if (count == 3) { | ||
635 | /* Rx is hung for more than 500ms. Reset it */ | ||
636 | ath_dbg(common, ATH_DBG_RESET, | ||
637 | "Possible RX hang, resetting"); | ||
638 | ath_reset(sc, true); | ||
639 | count = 0; | ||
640 | } | ||
641 | } else | ||
642 | count = 0; | ||
643 | } | ||
644 | |||
645 | void ath_hw_pll_work(struct work_struct *work) | ||
646 | { | ||
647 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
648 | hw_pll_work.work); | ||
649 | u32 pll_sqsum; | ||
650 | |||
651 | if (AR_SREV_9485(sc->sc_ah)) { | ||
652 | |||
653 | ath9k_ps_wakeup(sc); | ||
654 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
655 | ath9k_ps_restore(sc); | ||
656 | |||
657 | ath_hw_pll_rx_hang_check(sc, pll_sqsum); | ||
658 | |||
659 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | |||
627 | void ath9k_tasklet(unsigned long data) | 664 | void ath9k_tasklet(unsigned long data) |
628 | { | 665 | { |
629 | struct ath_softc *sc = (struct ath_softc *)data; | 666 | struct ath_softc *sc = (struct ath_softc *)data; |
@@ -1932,6 +1969,12 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1932 | "Bss Info ASSOC %d, bssid: %pM\n", | 1969 | "Bss Info ASSOC %d, bssid: %pM\n", |
1933 | bss_conf->aid, common->curbssid); | 1970 | bss_conf->aid, common->curbssid); |
1934 | ath_beacon_config(sc, vif); | 1971 | ath_beacon_config(sc, vif); |
1972 | /* | ||
1973 | * Request a re-configuration of Beacon related timers | ||
1974 | * on the receipt of the first Beacon frame (i.e., | ||
1975 | * after time sync with the AP). | ||
1976 | */ | ||
1977 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
1935 | /* Reset rssi stats */ | 1978 | /* Reset rssi stats */ |
1936 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 1979 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
1937 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1980 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
@@ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2219 | int timeout = 200; /* ms */ | 2262 | int timeout = 200; /* ms */ |
2220 | int i, j; | 2263 | int i, j; |
2221 | 2264 | ||
2222 | ath9k_ps_wakeup(sc); | ||
2223 | mutex_lock(&sc->mutex); | 2265 | mutex_lock(&sc->mutex); |
2224 | |||
2225 | cancel_delayed_work_sync(&sc->tx_complete_work); | 2266 | cancel_delayed_work_sync(&sc->tx_complete_work); |
2226 | 2267 | ||
2227 | if (drop) | 2268 | if (drop) |
@@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2244 | goto out; | 2285 | goto out; |
2245 | } | 2286 | } |
2246 | 2287 | ||
2288 | ath9k_ps_wakeup(sc); | ||
2247 | if (!ath_drain_all_txq(sc, false)) | 2289 | if (!ath_drain_all_txq(sc, false)) |
2248 | ath_reset(sc, false); | 2290 | ath_reset(sc, false); |
2249 | 2291 | ath9k_ps_restore(sc); | |
2250 | ieee80211_wake_queues(hw); | 2292 | ieee80211_wake_queues(hw); |
2251 | 2293 | ||
2252 | out: | 2294 | out: |
2253 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | 2295 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); |
2254 | mutex_unlock(&sc->mutex); | 2296 | mutex_unlock(&sc->mutex); |
2255 | ath9k_ps_restore(sc); | ||
2256 | } | 2297 | } |
2257 | 2298 | ||
2258 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | 2299 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) |