diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b52f1cf8a60..c0c3464d3a8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -93,11 +93,13 @@ void ath9k_ps_wakeup(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; + enum ath9k_power_mode power_mode; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (++sc->ps_usecount != 1) goto unlock; + power_mode = sc->sc_ah->power_mode; ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); /* @@ -105,10 +107,12 @@ void ath9k_ps_wakeup(struct ath_softc *sc) * useful data. Better clear them now so that they don't mess up * survey data results. */ - spin_lock(&common->cc_lock); - ath_hw_cycle_counters_update(common); - memset(&common->cc_survey, 0, sizeof(common->cc_survey)); - spin_unlock(&common->cc_lock); + if (power_mode != ATH9K_PM_AWAKE) { + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + spin_unlock(&common->cc_lock); + } unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); @@ -240,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, * the relevant bits of the h/w. */ ath9k_hw_set_interrupts(ah, 0); - ath_drain_all_txq(sc, false); + stopped = ath_drain_all_txq(sc, false); spin_lock_bh(&sc->rx.pcu_lock); - stopped = ath_stoprecv(sc); + if (!ath_stoprecv(sc)) + stopped = false; /* XXX: do not flush receive queue here. We don't want * to flush data frames already in queue because of @@ -1217,6 +1222,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ah->imask |= ATH9K_INT_CST; sc->sc_flags &= ~SC_OP_INVALID; + sc->sc_ah->is_monitoring = false; /* Disable BMISS interrupt when we're not associated */ ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); @@ -1238,6 +1244,8 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } + pm_qos_update_request(&sc->pm_qos_req, 55); + mutex_unlock: mutex_unlock(&sc->mutex); @@ -1415,6 +1423,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) sc->sc_flags |= SC_OP_INVALID; + pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); + mutex_unlock(&sc->mutex); ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); @@ -1493,8 +1503,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ath9k_hw_set_interrupts(ah, ah->imask); if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_MONITOR) { + vif->type == NL80211_IFTYPE_ADHOC) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); } @@ -1511,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_vif *avp = (void *)vif->drv_priv; - int i; ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); @@ -1525,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { + /* Disable SWBA interrupt */ + sc->sc_ah->imask &= ~ATH9K_INT_SWBA; ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); ath9k_ps_restore(sc); + tasklet_kill(&sc->bcon_tasklet); } ath_beacon_return(sc, avp); sc->sc_flags &= ~SC_OP_BEACONS; - for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { - if (sc->beacon.bslot[i] == vif) { - printk(KERN_DEBUG "%s: vif had allocated beacon " - "slot\n", __func__); - sc->beacon.bslot[i] = NULL; - sc->beacon.bslot_aphy[i] = NULL; - } + if (sc->nbcnvifs) { + /* Re-enable SWBA interrupt */ + sc->sc_ah->imask |= ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_ps_restore(sc); } sc->nvifs--; @@ -1644,8 +1655,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { ath_print(common, ATH_DBG_CONFIG, - "HW opmode set to Monitor mode\n"); - sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; + "Monitor mode is enabled\n"); + sc->sc_ah->is_monitoring = true; + } else { + ath_print(common, ATH_DBG_CONFIG, + "Monitor mode is disabled\n"); + sc->sc_ah->is_monitoring = false; } } |