aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-10-29 13:41:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-11-11 17:08:59 -0500
commit194b7c13b4c516db94db8ee004342f8935922739 (patch)
tree1000344cb5c9fd9eac85bed537ddcd476f64d1aa /drivers/net/wireless/ath/ath9k/main.c
parentf14543ee4d0681df1377b976cba704557ba220d3 (diff)
ath9k: fix listening to idle requests
The way idle configuration detection was implemented as busted due to the fact that it assumed the ath9k virtual wiphy, the aphy, would be marked as inactive if it was not used but it turns out an aphy is always active if its the only wiphy present. We need to distinguish between aphy activity and idleness so we now add an idle bool for the aphy and mark it as such based on the passed IEEE80211_CONF_CHANGE_IDLE from mac80211. Previous to all_wiphys_idle would never be true when using only one device so we never really were using IEEE80211_CONF_CHANGE_IDLE -- we never turned the radio off or on upon IEEE80211_CONF_CHANGE_IDLE changes as radio changes depended on all_wiphys_idle being true either to turn the radio on or off. Since it was always false for one device this code was doing nothing. Cc: Jouni.Malinen <Jouni.Malinen@atheros.com> Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9fefc51aec17..bdce0ab99ded 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2688,22 +2688,37 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2688 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 2688 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2689 struct ieee80211_conf *conf = &hw->conf; 2689 struct ieee80211_conf *conf = &hw->conf;
2690 struct ath_hw *ah = sc->sc_ah; 2690 struct ath_hw *ah = sc->sc_ah;
2691 bool all_wiphys_idle = false, disable_radio = false; 2691 bool disable_radio;
2692 2692
2693 mutex_lock(&sc->mutex); 2693 mutex_lock(&sc->mutex);
2694 2694
2695 /* Leave this as the first check */ 2695 /*
2696 * Leave this as the first check because we need to turn on the
2697 * radio if it was disabled before prior to processing the rest
2698 * of the changes. Likewise we must only disable the radio towards
2699 * the end.
2700 */
2696 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 2701 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
2702 bool enable_radio;
2703 bool all_wiphys_idle;
2704 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
2697 2705
2698 spin_lock_bh(&sc->wiphy_lock); 2706 spin_lock_bh(&sc->wiphy_lock);
2699 all_wiphys_idle = ath9k_all_wiphys_idle(sc); 2707 all_wiphys_idle = ath9k_all_wiphys_idle(sc);
2708 ath9k_set_wiphy_idle(aphy, idle);
2709
2710 if (!idle && all_wiphys_idle)
2711 enable_radio = true;
2712
2713 /*
2714 * After we unlock here its possible another wiphy
2715 * can be re-renabled so to account for that we will
2716 * only disable the radio toward the end of this routine
2717 * if by then all wiphys are still idle.
2718 */
2700 spin_unlock_bh(&sc->wiphy_lock); 2719 spin_unlock_bh(&sc->wiphy_lock);
2701 2720
2702 if (conf->flags & IEEE80211_CONF_IDLE){ 2721 if (enable_radio) {
2703 if (all_wiphys_idle)
2704 disable_radio = true;
2705 }
2706 else if (all_wiphys_idle) {
2707 ath_radio_enable(sc); 2722 ath_radio_enable(sc);
2708 ath_print(common, ATH_DBG_CONFIG, 2723 ath_print(common, ATH_DBG_CONFIG,
2709 "not-idle: enabling radio\n"); 2724 "not-idle: enabling radio\n");
@@ -2779,6 +2794,10 @@ skip_chan_change:
2779 if (changed & IEEE80211_CONF_CHANGE_POWER) 2794 if (changed & IEEE80211_CONF_CHANGE_POWER)
2780 sc->config.txpowlimit = 2 * conf->power_level; 2795 sc->config.txpowlimit = 2 * conf->power_level;
2781 2796
2797 spin_lock_bh(&sc->wiphy_lock);
2798 disable_radio = ath9k_all_wiphys_idle(sc);
2799 spin_unlock_bh(&sc->wiphy_lock);
2800
2782 if (disable_radio) { 2801 if (disable_radio) {
2783 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); 2802 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
2784 ath_radio_disable(sc); 2803 ath_radio_disable(sc);