ath9k_hw: calculate a much better approximation of channel noise
authorFelix Fietkau <nbd@openwrt.org>
Thu, 28 Jul 2011 12:08:56 +0000 (14:08 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 8 Aug 2011 20:04:19 +0000 (16:04 -0400)
Currently ath9k presents the internal calibrated noise floor as channel
noise measurement, however this results in highly chip specific values
that are only useful as relative measurements but do not resemble any
real channel noise values.

In order to give a much better approximation of the real channel noise,
add the difference between the measured noise floor and the nominal
chip specific noise floor to the default minimum channel noise value,
which is currently used to calculate the signal strength from the RSSI
value. This may not be 100% accurate, but it's much better than what's
there before.

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

index a1250c586e40884989a853845e1c68230434f6c2..ac2da3cce7889f0430837660314a1d92073c26e8 100644 (file)
@@ -63,6 +63,19 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
        return ath9k_hw_get_nf_limits(ah, chan)->nominal;
 }
 
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       s8 noise = ATH_DEFAULT_NOISE_FLOOR;
+
+       if (chan && chan->noisefloor) {
+               s8 delta = chan->noisefloor -
+                          ath9k_hw_get_default_nf(ah, chan);
+               if (delta > 0)
+                       noise += delta;
+       }
+       return noise;
+}
+EXPORT_SYMBOL(ath9k_hw_getchan_noise);
 
 static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
                                              struct ath9k_hw_cal_data *cal,
@@ -378,6 +391,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
 
        if (!caldata) {
                chan->noisefloor = nf;
+               ah->noise = ath9k_hw_getchan_noise(ah, chan);
                return false;
        }
 
@@ -385,6 +399,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
        caldata->nfcal_pending = false;
        ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
        chan->noisefloor = h[0].privNF;
+       ah->noise = ath9k_hw_getchan_noise(ah, chan);
        return true;
 }
 
index 1bef41d1b1ffb250d38f490a395d6c79e033b019..05b9dbf818507535288360bfdff4379aa7bf9970 100644 (file)
@@ -108,6 +108,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
 void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
 void ath9k_hw_reset_calibration(struct ath_hw *ah,
                                struct ath9k_cal_list *currCal);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
 
 
 #endif /* CALIB_H */
index cb0b6aab7115623e5d2cc8c4278e0f2ad9d86cf5..db44e5b0c98b53cf75cb93f5b1cb1ff98b371c5c 100644 (file)
@@ -1486,6 +1486,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                memset(caldata, 0, sizeof(*caldata));
                ath9k_init_nfcal_hist_buffer(ah, chan);
        }
+       ah->noise = ath9k_hw_getchan_noise(ah, chan);
 
        if (bChannelChange &&
            (ah->chip_fullsleep != true) &&
index c2bbd02ec6bdfbdb74836a7ffd91540d64efb961..eb49dc19debefc495d61c316983426bbbf9b678e 100644 (file)
@@ -689,6 +689,7 @@ struct ath_hw {
        enum nl80211_iftype opmode;
        enum ath9k_power_mode power_mode;
 
+       s8 noise;
        struct ath9k_hw_cal_data *caldata;
        struct ath9k_pacal_info pacal_info;
        struct ar5416Stats stats;