aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorBruno Randolf <br1@einfach.org>2010-03-25 01:49:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:39:09 -0400
commitb4ea449df90684035985a77763fd1d2ff0eb9dad (patch)
tree4b156d174efda2a11ca7fba59a59617ab3b7de14 /drivers/net/wireless
parent6a8a3f6b2ac02fb8542f2b36b0ecd9c48f7d9a7e (diff)
ath5k: keep beacon RSSI average
Keep an exponentially weighted moving average of the beacon RSSI in our BSS. It will be used by the ANI implementation. The averaging algorithm is copied from rt2x00, Thanks :) Signed-off-by: Bruno Randolf <br1@einfach.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h35
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c21
2 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6334294f5f13..cefd28d5deee 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -992,6 +992,15 @@ struct ath5k_nfcal_hist
992 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ 992 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
993}; 993};
994 994
995/**
996 * struct avg_val - Helper structure for average calculation
997 * @avg: contains the actual average value
998 * @avg_weight: is used internally during calculation to prevent rounding errors
999 */
1000struct ath5k_avg_val {
1001 int avg;
1002 int avg_weight;
1003};
995 1004
996/***************************************\ 1005/***************************************\
997 HARDWARE ABSTRACTION LAYER STRUCTURE 1006 HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1096,6 +1105,9 @@ struct ath5k_hw {
1096 1105
1097 struct ath5k_nfcal_hist ah_nfcal_hist; 1106 struct ath5k_nfcal_hist ah_nfcal_hist;
1098 1107
1108 /* average beacon RSSI in our BSS (used by ANI) */
1109 struct ath5k_avg_val ah_beacon_rssi_avg;
1110
1099 /* noise floor from last periodic calibration */ 1111 /* noise floor from last periodic calibration */
1100 s32 ah_noise_floor; 1112 s32 ah_noise_floor;
1101 1113
@@ -1305,4 +1317,27 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1305 return retval; 1317 return retval;
1306} 1318}
1307 1319
1320#define AVG_SAMPLES 8
1321#define AVG_FACTOR 1000
1322
1323/**
1324 * ath5k_moving_average - Exponentially weighted moving average
1325 * @avg: average structure
1326 * @val: current value
1327 *
1328 * This implementation make use of a struct ath5k_avg_val to prevent rounding
1329 * errors.
1330 */
1331static inline struct ath5k_avg_val
1332ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
1333{
1334 struct ath5k_avg_val new;
1335 new.avg_weight = avg.avg_weight ?
1336 (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
1337 (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
1338 (val * (AVG_FACTOR));
1339 new.avg = new.avg_weight / (AVG_FACTOR);
1340 return new;
1341}
1342
1308#endif 1343#endif
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index f60d84f9c55f..ba2fad23a7a5 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1803,6 +1803,25 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1803 } 1803 }
1804} 1804}
1805 1805
1806static void
1807ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
1808{
1809 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1810 struct ath5k_hw *ah = sc->ah;
1811 struct ath_common *common = ath5k_hw_common(ah);
1812
1813 /* only beacons from our BSSID */
1814 if (!ieee80211_is_beacon(mgmt->frame_control) ||
1815 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
1816 return;
1817
1818 ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
1819 rssi);
1820
1821 /* in IBSS mode we should keep RSSI statistics per neighbour */
1822 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
1823}
1824
1806/* 1825/*
1807 * Compute padding position. skb must contains an IEEE 802.11 frame 1826 * Compute padding position. skb must contains an IEEE 802.11 frame
1808 */ 1827 */
@@ -2022,6 +2041,8 @@ accept:
2022 2041
2023 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 2042 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
2024 2043
2044 ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi);
2045
2025 /* check beacons in IBSS mode */ 2046 /* check beacons in IBSS mode */
2026 if (sc->opmode == NL80211_IFTYPE_ADHOC) 2047 if (sc->opmode == NL80211_IFTYPE_ADHOC)
2027 ath5k_check_ibss_tsf(sc, skb, rxs); 2048 ath5k_check_ibss_tsf(sc, skb, rxs);