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>
This commit is contained in:
parent
3be63ff0ae
commit
898c914a08
|
@ -121,6 +121,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
|
||||||
|
|
||||||
void ath9k_ps_wakeup(struct ath_softc *sc)
|
void ath9k_ps_wakeup(struct ath_softc *sc)
|
||||||
{
|
{
|
||||||
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
||||||
|
@ -129,18 +130,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
|
||||||
|
|
||||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
|
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While the hardware is asleep, the cycle counters contain no
|
||||||
|
* 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);
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath9k_ps_restore(struct ath_softc *sc)
|
void ath9k_ps_restore(struct ath_softc *sc)
|
||||||
{
|
{
|
||||||
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
||||||
if (--sc->ps_usecount != 0)
|
if (--sc->ps_usecount != 0)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
spin_lock(&common->cc_lock);
|
||||||
|
ath_hw_cycle_counters_update(common);
|
||||||
|
spin_unlock(&common->cc_lock);
|
||||||
|
|
||||||
if (sc->ps_idle)
|
if (sc->ps_idle)
|
||||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
|
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
|
||||||
else if (sc->ps_enabled &&
|
else if (sc->ps_enabled &&
|
||||||
|
@ -196,6 +212,7 @@ static void ath_update_survey_stats(struct ath_softc *sc)
|
||||||
struct ath_cycle_counters *cc = &common->cc_survey;
|
struct ath_cycle_counters *cc = &common->cc_survey;
|
||||||
unsigned int div = common->clockrate * 1000;
|
unsigned int div = common->clockrate * 1000;
|
||||||
|
|
||||||
|
if (ah->power_mode == ATH9K_PM_AWAKE)
|
||||||
ath_hw_cycle_counters_update(common);
|
ath_hw_cycle_counters_update(common);
|
||||||
|
|
||||||
if (cc->cycles > 0) {
|
if (cc->cycles > 0) {
|
||||||
|
|
Loading…
Reference in New Issue