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.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 91af57c48581..20c70ba45753 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -611,14 +611,12 @@ void ath9k_tasklet(unsigned long data)
611 u32 status = sc->intrstatus; 611 u32 status = sc->intrstatus;
612 u32 rxmask; 612 u32 rxmask;
613 613
614 ath9k_ps_wakeup(sc);
615
616 if (status & ATH9K_INT_FATAL) { 614 if (status & ATH9K_INT_FATAL) {
617 ath_reset(sc, true); 615 ath_reset(sc, true);
618 ath9k_ps_restore(sc);
619 return; 616 return;
620 } 617 }
621 618
619 ath9k_ps_wakeup(sc);
622 spin_lock(&sc->sc_pcu_lock); 620 spin_lock(&sc->sc_pcu_lock);
623 621
624 /* 622 /*
@@ -939,8 +937,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
939 937
940 spin_unlock_bh(&sc->sc_pcu_lock); 938 spin_unlock_bh(&sc->sc_pcu_lock);
941 ath9k_ps_restore(sc); 939 ath9k_ps_restore(sc);
942
943 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
944} 940}
945 941
946int ath_reset(struct ath_softc *sc, bool retry_tx) 942int ath_reset(struct ath_softc *sc, bool retry_tx)
@@ -953,6 +949,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
953 /* Stop ANI */ 949 /* Stop ANI */
954 del_timer_sync(&common->ani.timer); 950 del_timer_sync(&common->ani.timer);
955 951
952 ath9k_ps_wakeup(sc);
956 spin_lock_bh(&sc->sc_pcu_lock); 953 spin_lock_bh(&sc->sc_pcu_lock);
957 954
958 ieee80211_stop_queues(hw); 955 ieee80211_stop_queues(hw);
@@ -999,6 +996,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
999 996
1000 /* Start ANI */ 997 /* Start ANI */
1001 ath_start_ani(common); 998 ath_start_ani(common);
999 ath9k_ps_restore(sc);
1002 1000
1003 return r; 1001 return r;
1004} 1002}
@@ -1220,6 +1218,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1220 1218
1221 spin_lock_bh(&sc->sc_pcu_lock); 1219 spin_lock_bh(&sc->sc_pcu_lock);
1222 1220
1221 /* prevent tasklets to enable interrupts once we disable them */
1222 ah->imask &= ~ATH9K_INT_GLOBAL;
1223
1223 /* make sure h/w will not generate any interrupt 1224 /* make sure h/w will not generate any interrupt
1224 * before setting the invalid flag. */ 1225 * before setting the invalid flag. */
1225 ath9k_hw_disable_interrupts(ah); 1226 ath9k_hw_disable_interrupts(ah);
@@ -1242,6 +1243,12 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1242 1243
1243 spin_unlock_bh(&sc->sc_pcu_lock); 1244 spin_unlock_bh(&sc->sc_pcu_lock);
1244 1245
1246 /* we can now sync irq and kill any running tasklets, since we already
1247 * disabled interrupts and not holding a spin lock */
1248 synchronize_irq(sc->irq);
1249 tasklet_kill(&sc->intr_tq);
1250 tasklet_kill(&sc->bcon_tasklet);
1251
1245 ath9k_ps_restore(sc); 1252 ath9k_ps_restore(sc);
1246 1253
1247 sc->ps_idle = true; 1254 sc->ps_idle = true;
@@ -1706,7 +1713,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1706 1713
1707 if (changed & IEEE80211_CONF_CHANGE_POWER) { 1714 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1708 sc->config.txpowlimit = 2 * conf->power_level; 1715 sc->config.txpowlimit = 2 * conf->power_level;
1716 ath9k_ps_wakeup(sc);
1709 ath_update_txpow(sc); 1717 ath_update_txpow(sc);
1718 ath9k_ps_restore(sc);
1710 } 1719 }
1711 1720
1712 if (disable_radio) { 1721 if (disable_radio) {