diff options
author | Zhu Yi <yi.zhu@intel.com> | 2006-04-13 05:19:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-04-24 16:15:54 -0400 |
commit | 00d21de5c685ab450ef376acdd1b733badb6b50d (patch) | |
tree | cafb8af00344d068943666f893a84260eaa84bed /drivers/net/wireless/ipw2200.c | |
parent | 45a62ab3d6f9d5963cb7c01fa76c950e42d037c2 (diff) |
[PATCH] ipw2200: Exponential averaging for signal and noise Level
This patch replaces sliding averaging by exponential averaging for
reporting the wireless statistics for signal and noise level for ipw2200.
See details from: http://www.ces.clemson.edu/linux/ipw2200_averages.shtml
Signed-off-by: Bill Moss <bmoss@clemson.edu>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index bca89cff85a6..a879edba5fac 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -3771,6 +3771,13 @@ static void inline average_init(struct average *avg) | |||
3771 | memset(avg, 0, sizeof(*avg)); | 3771 | memset(avg, 0, sizeof(*avg)); |
3772 | } | 3772 | } |
3773 | 3773 | ||
3774 | #define DEPTH_RSSI 8 | ||
3775 | #define DEPTH_NOISE 16 | ||
3776 | static s16 exponential_average(s16 prev_avg, s16 val, u8 depth) | ||
3777 | { | ||
3778 | return ((depth-1)*prev_avg + val)/depth; | ||
3779 | } | ||
3780 | |||
3774 | static void average_add(struct average *avg, s16 val) | 3781 | static void average_add(struct average *avg, s16 val) |
3775 | { | 3782 | { |
3776 | avg->sum -= avg->entries[avg->pos]; | 3783 | avg->sum -= avg->entries[avg->pos]; |
@@ -3800,8 +3807,8 @@ static void ipw_reset_stats(struct ipw_priv *priv) | |||
3800 | priv->quality = 0; | 3807 | priv->quality = 0; |
3801 | 3808 | ||
3802 | average_init(&priv->average_missed_beacons); | 3809 | average_init(&priv->average_missed_beacons); |
3803 | average_init(&priv->average_rssi); | 3810 | priv->exp_avg_rssi = -60; |
3804 | average_init(&priv->average_noise); | 3811 | priv->exp_avg_noise = -85 + 0x100; |
3805 | 3812 | ||
3806 | priv->last_rate = 0; | 3813 | priv->last_rate = 0; |
3807 | priv->last_missed_beacons = 0; | 3814 | priv->last_missed_beacons = 0; |
@@ -4008,7 +4015,7 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
4008 | IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n", | 4015 | IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n", |
4009 | tx_quality, tx_failures_delta, tx_packets_delta); | 4016 | tx_quality, tx_failures_delta, tx_packets_delta); |
4010 | 4017 | ||
4011 | rssi = average_value(&priv->average_rssi); | 4018 | rssi = priv->exp_avg_rssi; |
4012 | signal_quality = | 4019 | signal_quality = |
4013 | (100 * | 4020 | (100 * |
4014 | (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) * | 4021 | (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) * |
@@ -4023,7 +4030,7 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
4023 | else if (signal_quality < 1) | 4030 | else if (signal_quality < 1) |
4024 | signal_quality = 0; | 4031 | signal_quality = 0; |
4025 | 4032 | ||
4026 | IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", | 4033 | IPW_ERROR("Signal level : %3d%% (%d dBm)\n", |
4027 | signal_quality, rssi); | 4034 | signal_quality, rssi); |
4028 | 4035 | ||
4029 | quality = min(beacon_quality, | 4036 | quality = min(beacon_quality, |
@@ -4577,11 +4584,10 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4577 | 4584 | ||
4578 | case HOST_NOTIFICATION_NOISE_STATS:{ | 4585 | case HOST_NOTIFICATION_NOISE_STATS:{ |
4579 | if (notif->size == sizeof(u32)) { | 4586 | if (notif->size == sizeof(u32)) { |
4580 | priv->last_noise = | 4587 | priv->exp_avg_noise = |
4581 | (u8) (le32_to_cpu(notif->u.noise.value) & | 4588 | exponential_average(priv->exp_avg_noise, |
4582 | 0xff); | 4589 | (u8) (le32_to_cpu(notif->u.noise.value) & 0xff), |
4583 | average_add(&priv->average_noise, | 4590 | DEPTH_NOISE); |
4584 | priv->last_noise); | ||
4585 | break; | 4591 | break; |
4586 | } | 4592 | } |
4587 | 4593 | ||
@@ -7837,9 +7843,9 @@ static void ipw_rx(struct ipw_priv *priv) | |||
7837 | if (network_packet && priv->assoc_network) { | 7843 | if (network_packet && priv->assoc_network) { |
7838 | priv->assoc_network->stats.rssi = | 7844 | priv->assoc_network->stats.rssi = |
7839 | stats.rssi; | 7845 | stats.rssi; |
7840 | average_add(&priv->average_rssi, | 7846 | priv->exp_avg_rssi = |
7841 | stats.rssi); | 7847 | exponential_average(priv->exp_avg_rssi, |
7842 | priv->last_rx_rssi = stats.rssi; | 7848 | stats.rssi, DEPTH_RSSI); |
7843 | } | 7849 | } |
7844 | 7850 | ||
7845 | IPW_DEBUG_RX("Frame: len=%u\n", | 7851 | IPW_DEBUG_RX("Frame: len=%u\n", |
@@ -9579,8 +9585,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev) | |||
9579 | } | 9585 | } |
9580 | 9586 | ||
9581 | wstats->qual.qual = priv->quality; | 9587 | wstats->qual.qual = priv->quality; |
9582 | wstats->qual.level = average_value(&priv->average_rssi); | 9588 | wstats->qual.level = priv->exp_avg_rssi; |
9583 | wstats->qual.noise = average_value(&priv->average_noise); | 9589 | wstats->qual.noise = priv->exp_avg_noise; |
9584 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | | 9590 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | |
9585 | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; | 9591 | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; |
9586 | 9592 | ||