From: Bruno Randolf <b...@einfach.org>
--- drivers/net/wireless/ath/ath5k/ath5k.h | 2 ++ drivers/net/wireless/ath/ath5k/base.c | 29 ++++++++++++++++++++++++----- drivers/net/wireless/ath/ath5k/base.h | 1 + 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 8b5383e..d28b748 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -917,6 +917,7 @@ enum ath5k_int { enum ath5k_calibration_mask { AR5K_FULL_CALIBRATION = 0x01, AR5K_SHORT_CALIBRATION = 0x02, + AR5K_ANI_CALIBRATION = 0x04, }; /* @@ -1139,6 +1140,7 @@ struct ath5k_hw { /* Calibration timestamp */ unsigned long ah_cal_next_full; + unsigned long ah_cal_next_ani; /* Calibration mask */ u8 ah_cal_mask; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 32aebb6..2ffab83 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -364,6 +364,7 @@ static void ath5k_beacon_send(struct ath5k_softc *sc); static void ath5k_beacon_config(struct ath5k_softc *sc); static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); static void ath5k_tasklet_beacon(unsigned long data); +static void ath5k_tasklet_ani(unsigned long data); static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) { @@ -829,6 +830,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); + tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); ret = ath5k_eeprom_read_mac(ah, mac); if (ret) { @@ -2634,6 +2636,7 @@ ath5k_stop_hw(struct ath5k_softc *sc) tasklet_kill(&sc->restq); tasklet_kill(&sc->calib); tasklet_kill(&sc->beacontq); + tasklet_kill(&sc->ani_tasklet); ath5k_rfkill_hw_stop(sc->ah); @@ -2643,10 +2646,16 @@ ath5k_stop_hw(struct ath5k_softc *sc) static void ath5k_intr_calibration_poll(struct ath5k_hw *ah) { - if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { + if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) && + !(ah->ah_cal_mask & AR5K_FULL_CALIBRATION)) { + /* run ANI only when full calibration is not active */ + ah->ah_cal_next_ani = jiffies + + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); + tasklet_schedule(&ah->ah_sc->ani_tasklet); + } + else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { ah->ah_cal_next_full = jiffies + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); - ah->ah_cal_mask = AR5K_FULL_CALIBRATION; tasklet_schedule(&ah->ah_sc->calib); } /* we could use SWI to generate enough interrupts to meet our @@ -2746,8 +2755,7 @@ ath5k_tasklet_calibrate(unsigned long data) struct ath5k_hw *ah = sc->ah; /* Only full calibration for now */ - if (ah->ah_cal_mask != AR5K_FULL_CALIBRATION) - return; + ah->ah_cal_mask |= AR5K_FULL_CALIBRATION; /* Stop queues so that calibration * doesn't interfere with tx */ @@ -2770,11 +2778,22 @@ ath5k_tasklet_calibrate(unsigned long data) ieee80211_frequency_to_channel( sc->curchan->center_freq)); - ah->ah_cal_mask = 0; + ah->ah_cal_mask &= ~AR5K_FULL_CALIBRATION; /* Wake queues */ ieee80211_wake_queues(sc->hw); +} + + +static void +ath5k_tasklet_ani(unsigned long data) +{ + struct ath5k_softc *sc = (void *)data; + struct ath5k_hw *ah = sc->ah; + ah->ah_cal_mask |= AR5K_ANI_CALIBRATION; + ath5k_ani_periodic_calibration(ah); + ah->ah_cal_mask &= ~AR5K_ANI_CALIBRATION; } diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 9174523..49e8a56 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -232,6 +232,7 @@ struct ath5k_softc { bool enable_beacon; /* true if beacons are on */ struct ath5k_statistics stats; + struct tasklet_struct ani_tasklet; /* ANI calibration */ }; #define ath5k_hw_hasbssidmask(_ah) \ _______________________________________________ ath5k-devel mailing list ath5k-devel@lists.ath5k.org https://lists.ath5k.org/mailman/listinfo/ath5k-devel