select MAC80211_LEDS
        select LEDS_CLASS
        select NEW_LEDS
+       select AVERAGE
        ---help---
          This module adds support for wireless adapters based on
          Atheros 5xxx chipset.
 
 ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
                         bool ofdm_trigger)
 {
-       int rssi = ah->ah_beacon_rssi_avg.avg;
+       int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
 
        ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
                ofdm_trigger ? "ODFM" : "CCK");
 static void
 ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 {
-       int rssi = ah->ah_beacon_rssi_avg.avg;
+       int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
 
        ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
 
 
 
 #include <linux/io.h>
 #include <linux/types.h>
+#include <linux/average.h>
 #include <net/mac80211.h>
 
 /* RX/TX descriptor hw structs
        struct ath5k_nfcal_hist ah_nfcal_hist;
 
        /* average beacon RSSI in our BSS (used by ANI) */
-       struct ath5k_avg_val    ah_beacon_rssi_avg;
+       struct ewma             ah_beacon_rssi_avg;
 
        /* noise floor from last periodic calibration */
        s32                     ah_noise_floor;
        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
 
            memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
                return;
 
-       ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
-                                                     rssi);
+       ewma_add(&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 */
        ah->ah_cal_next_full = jiffies;
        ah->ah_cal_next_ani = jiffies;
        ah->ah_cal_next_nf = jiffies;
+       ewma_init(&ah->ah_beacon_rssi_avg, 1000, 8);
 
        /*
         * Change channels and update the h/w rate map if we're switching;
 
                        st->mib_intr);
        len += snprintf(buf+len, sizeof(buf)-len,
                        "beacon RSSI average:\t%d\n",
-                       sc->ah->ah_beacon_rssi_avg.avg);
+                       (int)ewma_read(&sc->ah->ah_beacon_rssi_avg));
 
 #define CC_PRINT(_struct, _field) \
        _struct._field, \