aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c49
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
627static 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
645void 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
627void ath9k_tasklet(unsigned long data) 664void 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
2252out: 2294out:
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
2258static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) 2299static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)