--- ipw2200.c_orig 2006-06-12 20:07:43.000000000 -0400 +++ ipw2200.c 2006-06-12 20:28:47.000000000 -0400 @@ -4025,49 +4025,24 @@ return "Unknown status value."; } -static void inline average_init(struct average *avg) -{ - memset(avg, 0, sizeof(*avg)); -} - #define DEPTH_RSSI 8 #define DEPTH_NOISE 16 +#define DEPTH_MISSED 2 static s16 exponential_average(s16 prev_avg, s16 val, u8 depth) { return ((depth - 1) * prev_avg + val) / depth; } -static void average_add(struct average *avg, s16 val) -{ - avg->sum -= avg->entries[avg->pos]; - avg->sum += val; - avg->entries[avg->pos++] = val; - if (unlikely(avg->pos == AVG_ENTRIES)) { - avg->init = 1; - avg->pos = 0; - } -} - -static s16 average_value(struct average *avg) -{ - if (!unlikely(avg->init)) { - if (avg->pos) - return avg->sum / avg->pos; - return 0; - } - - return avg->sum / AVG_ENTRIES; -} - static void ipw_reset_stats(struct ipw_priv *priv) { u32 len = sizeof(u32); priv->quality = 0; - average_init(&priv->average_missed_beacons); priv->exp_avg_rssi = -60; priv->exp_avg_noise = -85 + 0x100; + priv->exp_avg_missed = 0; + priv->max_missed_beacons = 0; priv->last_rate = 0; priv->last_missed_beacons = 0; @@ -4215,7 +4190,10 @@ } else { missed_beacons_percent = 0; } - average_add(&priv->average_missed_beacons, missed_beacons_percent); + priv->exp_avg_missed = exponential_average(priv->exp_avg_missed, + priv->max_missed_beacons, + DEPTH_MISSED); + priv->max_missed_beacons = 0; ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len); rx_err_delta = rx_err - priv->last_rx_err; @@ -4332,8 +4310,6 @@ * Roaming is disabled if disassociate_threshold <= roaming_threshold */ static void ipw_handle_missed_beacon(struct ipw_priv *priv, int missed_count) { - priv->notif_missed_beacons = missed_count; - if (missed_count > priv->disassociate_threshold && priv->status & STATUS_ASSOCIATED) { /* If associated and we've hit the missed @@ -4818,10 +4794,13 @@ if (le32_to_cpu(x->state) == HOST_NOTIFICATION_STATUS_BEACON_MISSING) - ipw_handle_missed_beacon(priv, - le32_to_cpu(x-> - number)); - + { + priv->notif_missed_beacons = le32_to_cpu(x->number); + priv->max_missed_beacons = max( + priv->max_missed_beacons, + (s16) priv->notif_missed_beacons); + ipw_handle_missed_beacon(priv, priv->notif_missed_beacons); + } break; } @@ -10581,7 +10560,7 @@ wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; - wstats->miss.beacon = average_value(&priv->average_missed_beacons); + wstats->miss.beacon = priv->exp_avg_missed; wstats->discard.retries = priv->last_tx_failures; wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable; --- ipw2200.h_orig 2006-06-12 20:07:55.000000000 -0400 +++ ipw2200.h 2006-06-12 20:30:25.000000000 -0400 @@ -1092,14 +1092,6 @@ u8 support_mode; }; -#define AVG_ENTRIES 8 -struct average { - s16 entries[AVG_ENTRIES]; - u8 pos; - u8 init; - s32 sum; -}; - #define MAX_SPEED_SCAN 100 #define IPW_IBSS_MAC_HASH_SIZE 31 @@ -1222,9 +1214,10 @@ u32 config; u32 capability; - struct average average_missed_beacons; s16 exp_avg_rssi; s16 exp_avg_noise; + s16 exp_avg_missed; + s16 max_missed_beacons; u32 port_type; int rx_bufs_min; /**< minimum number of bufs in Rx queue */ int rx_pend_max; /**< maximum pending buffers for one IRQ */