From b6fc0e4ebff719b1968833b6d9729395541a32b5 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 14 Jul 2009 20:22:53 -0400 Subject: [PATCH] --- yaml --- r: 159135 b: refs/heads/master c: 64839170be296e6348fbaf83fd103711978669b9 h: refs/heads/master i: 159133: c1dcb4825867c3e0ca5133209ef883b1cd86f8d4 159131: 29ea98f35b321c0749a78544154445e51a1fd2c6 159127: 9061e3510c14f9f002d1e87ade29d68e042cde51 159119: d23fb9bd783539d875b12a17cfdf6a800c62828f 159103: ea684a9033f1beb0408e5d5c6427bc54caeac70a v: v3 --- [refs] | 2 +- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 1 + trunk/drivers/net/wireless/ath/ath9k/main.c | 24 +++++++++++++++++++ .../drivers/net/wireless/ath/ath9k/virtual.c | 17 +++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 60c5184237ee..214948ed6c87 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 709ade9eb8ef06e03526115408e2fc93a9feabbd +refs/heads/master: 64839170be296e6348fbaf83fd103711978669b9 diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 157681241733..751885a5df47 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -691,6 +691,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, struct ath_wiphy *selected); bool ath9k_wiphy_scanning(struct ath_softc *sc); void ath9k_wiphy_work(struct work_struct *work); +bool ath9k_all_wiphys_idle(struct ath_softc *sc); void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val); unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index d14f8c9cef68..254e78786eee 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -2260,9 +2260,28 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_softc *sc = aphy->sc; struct ieee80211_conf *conf = &hw->conf; struct ath_hw *ah = sc->sc_ah; + bool all_wiphys_idle = false, disable_radio = false; mutex_lock(&sc->mutex); + /* Leave this as the first check */ + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + + spin_lock_bh(&sc->wiphy_lock); + all_wiphys_idle = ath9k_all_wiphys_idle(sc); + spin_unlock_bh(&sc->wiphy_lock); + + if (conf->flags & IEEE80211_CONF_IDLE){ + if (all_wiphys_idle) + disable_radio = true; + } + else if (all_wiphys_idle) { + ath_radio_enable(sc); + DPRINTF(sc, ATH_DBG_CONFIG, + "not-idle: enabling radio\n"); + } + } + if (changed & IEEE80211_CONF_CHANGE_PS) { if (conf->flags & IEEE80211_CONF_PS) { if (!(ah->caps.hw_caps & @@ -2330,6 +2349,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_POWER) sc->config.txpowlimit = 2 * conf->power_level; + if (disable_radio) { + DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n"); + ath_radio_disable(sc); + } + mutex_unlock(&sc->mutex); return 0; diff --git a/trunk/drivers/net/wireless/ath/ath9k/virtual.c b/trunk/drivers/net/wireless/ath/ath9k/virtual.c index 1ff429b027d7..e1d419e02b4a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/virtual.c +++ b/trunk/drivers/net/wireless/ath/ath9k/virtual.c @@ -660,3 +660,20 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, sc->wiphy_scheduler_int); } + +/* caller must hold wiphy_lock */ +bool ath9k_all_wiphys_idle(struct ath_softc *sc) +{ + unsigned int i; + if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) { + return false; + } + for (i = 0; i < sc->num_sec_wiphy; i++) { + struct ath_wiphy *aphy = sc->sec_wiphy[i]; + if (!aphy) + continue; + if (aphy->state != ATH_WIPHY_INACTIVE) + return false; + } + return true; +}