From 70cf15335eb35d562a4ec6d8860611c87f775cf2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 2 Aug 2010 15:53:14 +0200 Subject: ath9k: use AP beacon miss as a trigger for fast recalibration When beacons get stuck in AP mode, the most likely cause is interference. Such interference can often go on for a while, and too many consecutive beacon misses can lead to connected clients getting dropped. Since connected clients might not be subjected to the same interference if that happens to be very local, the AP should try to deal with it as good as it can. One way to do this is to trigger an NF calibration with automatic baseband update right after the beacon miss. In my tests with very strong interference, this allowed the AP to continue transmitting beacons after only 2-3 misses, which allows a normal client to stay connected. With some of the newer - really sensitive - chips, the maximum noise floor limit is very low, which can be problematic during very strong interference. To avoid an endless loop of stuck beacons -> nfcal -> periodic calibration -> stuck beacons, the beacon miss event also sets a flag, which allows the calibration code to bypass the chip specific maximum NF value. This flag is automatically cleared, as soon as the first NF median goes back below the limits for all chains. In my tests, this allowed an ath9k AP to survive very strong interference (measured NF: -68, or sometimes even higher) without losing connectivity to its clients. Even under these conditions, I was able to transmit several mbits/s through the interface. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/ath/ath9k/beacon.c') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 102f123..081192e 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -362,6 +362,7 @@ void ath_beacon_tasklet(unsigned long data) ath_print(common, ATH_DBG_BSTUCK, "missed %u consecutive beacons\n", sc->beacon.bmisscnt); + ath9k_hw_bstuck_nfcal(ah); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { ath_print(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); -- cgit v1.1