ath9k: shorten the calibration interval during strong interference
authorFelix Fietkau <nbd@openwrt.org>
Mon, 2 Aug 2010 13:53:15 +0000 (15:53 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 16 Aug 2010 19:26:39 +0000 (15:26 -0400)
When the noise floor limits are being bypassed because of strong
interference, sensitivity is also reduced.
In order to recover from this as quickly as possible, trigger a
long periodic calibration every second instead of every 30 seconds,
until the NF median is within limits again. This is especially important
if the interference lasts for a while, since it takes multiple clean
NF calibrations to bring the median back to normal.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/main.c

index 07f26ee7a7235ac0f3c48c7966630ce849217cfc..def0cd308fdda630ecaf251df3f84c8fbb3ba5f7 100644 (file)
@@ -423,6 +423,7 @@ int ath_beaconq_config(struct ath_softc *sc);
 #define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
 #define ATH_ANI_POLLINTERVAL_OLD  100     /* 100 ms */
 #define ATH_ANI_POLLINTERVAL_NEW  1000    /* 1000 ms */
+#define ATH_LONG_CALINTERVAL_INT  1000    /* 1000 ms */
 #define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
 #define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
 
index 2ab3df22fbb587a0f73e2acaef51c6b7545a3981..a3b0ea90439d129924331d09d81689408ca16078 100644 (file)
@@ -396,7 +396,12 @@ void ath_ani_calibrate(unsigned long data)
        bool shortcal = false;
        bool aniflag = false;
        unsigned int timestamp = jiffies_to_msecs(jiffies);
-       u32 cal_interval, short_cal_interval;
+       u32 cal_interval, short_cal_interval, long_cal_interval;
+
+       if (ah->caldata && ah->caldata->nfcal_interference)
+               long_cal_interval = ATH_LONG_CALINTERVAL_INT;
+       else
+               long_cal_interval = ATH_LONG_CALINTERVAL;
 
        short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
                ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
@@ -408,7 +413,7 @@ void ath_ani_calibrate(unsigned long data)
        ath9k_ps_wakeup(sc);
 
        /* Long calibration runs independently of short calibration. */
-       if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+       if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
                longcal = true;
                ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
                common->ani.longcal_timer = timestamp;