aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-10-12 08:02:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-15 15:48:44 -0400
commit898c914a0871ea7e5557b77156d4358c0f15d98a (patch)
tree7c3fb4a99f3a0f6154b7f52a20f21b3ea9e61597 /drivers/net/wireless
parent3be63ff0ae196b371728ba8fc8aca12eafcae218 (diff)
ath9k: do not track cycle counter updates in powersave mode
While the chip is in powersave mode, the cycle counter updates do not contain useful values. While the chip is in full sleep, the rx_clear signal stays high, indicating a busy medium. To ensure sane values, update cycle counters before going into powersave, and clear them right after switching back to awake. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index bcd3892dca8d..74ff51d4c339 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -121,6 +121,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
121 121
122void ath9k_ps_wakeup(struct ath_softc *sc) 122void ath9k_ps_wakeup(struct ath_softc *sc)
123{ 123{
124 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
124 unsigned long flags; 125 unsigned long flags;
125 126
126 spin_lock_irqsave(&sc->sc_pm_lock, flags); 127 spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -129,18 +130,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
129 130
130 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 131 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
131 132
133 /*
134 * While the hardware is asleep, the cycle counters contain no
135 * useful data. Better clear them now so that they don't mess up
136 * survey data results.
137 */
138 spin_lock(&common->cc_lock);
139 ath_hw_cycle_counters_update(common);
140 memset(&common->cc_survey, 0, sizeof(common->cc_survey));
141 spin_unlock(&common->cc_lock);
142
132 unlock: 143 unlock:
133 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 144 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
134} 145}
135 146
136void ath9k_ps_restore(struct ath_softc *sc) 147void ath9k_ps_restore(struct ath_softc *sc)
137{ 148{
149 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
138 unsigned long flags; 150 unsigned long flags;
139 151
140 spin_lock_irqsave(&sc->sc_pm_lock, flags); 152 spin_lock_irqsave(&sc->sc_pm_lock, flags);
141 if (--sc->ps_usecount != 0) 153 if (--sc->ps_usecount != 0)
142 goto unlock; 154 goto unlock;
143 155
156 spin_lock(&common->cc_lock);
157 ath_hw_cycle_counters_update(common);
158 spin_unlock(&common->cc_lock);
159
144 if (sc->ps_idle) 160 if (sc->ps_idle)
145 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); 161 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
146 else if (sc->ps_enabled && 162 else if (sc->ps_enabled &&
@@ -196,7 +212,8 @@ static void ath_update_survey_stats(struct ath_softc *sc)
196 struct ath_cycle_counters *cc = &common->cc_survey; 212 struct ath_cycle_counters *cc = &common->cc_survey;
197 unsigned int div = common->clockrate * 1000; 213 unsigned int div = common->clockrate * 1000;
198 214
199 ath_hw_cycle_counters_update(common); 215 if (ah->power_mode == ATH9K_PM_AWAKE)
216 ath_hw_cycle_counters_update(common);
200 217
201 if (cc->cycles > 0) { 218 if (cc->cycles > 0) {
202 survey->filled |= SURVEY_INFO_CHANNEL_TIME | 219 survey->filled |= SURVEY_INFO_CHANNEL_TIME |