Skip to content

Commit

Permalink
ath5k: keep beacon RSSI average
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Bruno Randolf authored and John W. Linville committed Mar 31, 2010
1 parent 6a8a3f6 commit b4ea449
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
35 changes: 35 additions & 0 deletions drivers/net/wireless/ath/ath5k/ath5k.h
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,15 @@ struct ath5k_nfcal_hist
s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
};

/**
* struct avg_val - Helper structure for average calculation
* @avg: contains the actual average value
* @avg_weight: is used internally during calculation to prevent rounding errors
*/
struct ath5k_avg_val {
int avg;
int avg_weight;
};

/***************************************\
HARDWARE ABSTRACTION LAYER STRUCTURE
Expand Down Expand Up @@ -1096,6 +1105,9 @@ struct ath5k_hw {

struct ath5k_nfcal_hist ah_nfcal_hist;

/* average beacon RSSI in our BSS (used by ANI) */
struct ath5k_avg_val ah_beacon_rssi_avg;

/* noise floor from last periodic calibration */
s32 ah_noise_floor;

Expand Down Expand Up @@ -1305,4 +1317,27 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
return retval;
}

#define AVG_SAMPLES 8
#define AVG_FACTOR 1000

/**
* ath5k_moving_average - Exponentially weighted moving average
* @avg: average structure
* @val: current value
*
* This implementation make use of a struct ath5k_avg_val to prevent rounding
* errors.
*/
static inline struct ath5k_avg_val
ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
{
struct ath5k_avg_val new;
new.avg_weight = avg.avg_weight ?
(((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
(val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
(val * (AVG_FACTOR));
new.avg = new.avg_weight / (AVG_FACTOR);
return new;
}

#endif
21 changes: 21 additions & 0 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,25 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
}
}

static void
ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
{
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);

/* only beacons from our BSSID */
if (!ieee80211_is_beacon(mgmt->frame_control) ||
memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
return;

ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
rssi);

/* in IBSS mode we should keep RSSI statistics per neighbour */
/* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
}

/*
* Compute padding position. skb must contains an IEEE 802.11 frame
*/
Expand Down Expand Up @@ -2022,6 +2041,8 @@ ath5k_tasklet_rx(unsigned long data)

ath5k_debug_dump_skb(sc, skb, "RX ", 0);

ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi);

/* check beacons in IBSS mode */
if (sc->opmode == NL80211_IFTYPE_ADHOC)
ath5k_check_ibss_tsf(sc, skb, rxs);
Expand Down

0 comments on commit b4ea449

Please sign in to comment.