aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2006-04-13 05:19:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-04-24 16:15:54 -0400
commit00d21de5c685ab450ef376acdd1b733badb6b50d (patch)
treecafb8af00344d068943666f893a84260eaa84bed
parent45a62ab3d6f9d5963cb7c01fa76c950e42d037c2 (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>
-rw-r--r--drivers/net/wireless/ipw2200.c34
-rw-r--r--drivers/net/wireless/ipw2200.h6
2 files changed, 22 insertions, 18 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
3776static s16 exponential_average(s16 prev_avg, s16 val, u8 depth)
3777{
3778 return ((depth-1)*prev_avg + val)/depth;
3779}
3780
3774static void average_add(struct average *avg, s16 val) 3781static 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
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 4b9804900702..1f2cab3f9944 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1153,11 +1153,9 @@ struct ipw_priv {
1153 u32 config; 1153 u32 config;
1154 u32 capability; 1154 u32 capability;
1155 1155
1156 u8 last_rx_rssi;
1157 u8 last_noise;
1158 struct average average_missed_beacons; 1156 struct average average_missed_beacons;
1159 struct average average_rssi; 1157 s16 exp_avg_rssi;
1160 struct average average_noise; 1158 s16 exp_avg_noise;
1161 u32 port_type; 1159 u32 port_type;
1162 int rx_bufs_min; /**< minimum number of bufs in Rx queue */ 1160 int rx_bufs_min; /**< minimum number of bufs in Rx queue */
1163 int rx_pend_max; /**< maximum pending buffers for one IRQ */ 1161 int rx_pend_max; /**< maximum pending buffers for one IRQ */