]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[PATCH] ipw2200: Exponential averaging for signal and noise Level
authorZhu Yi <yi.zhu@intel.com>
Thu, 13 Apr 2006 09:19:02 +0000 (17:19 +0800)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 24 Apr 2006 20:15:54 +0000 (16:15 -0400)
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>
drivers/net/wireless/ipw2200.c
drivers/net/wireless/ipw2200.h

index bca89cff85a63ccaf0204b349b7ab700de369dbe..a879edba5fac0f772ec8c876d380425ed3456362 100644 (file)
@@ -3771,6 +3771,13 @@ static void inline average_init(struct average *avg)
        memset(avg, 0, sizeof(*avg));
 }
 
+#define DEPTH_RSSI 8
+#define DEPTH_NOISE 16
+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];
@@ -3800,8 +3807,8 @@ static void ipw_reset_stats(struct ipw_priv *priv)
        priv->quality = 0;
 
        average_init(&priv->average_missed_beacons);
-       average_init(&priv->average_rssi);
-       average_init(&priv->average_noise);
+       priv->exp_avg_rssi = -60;
+       priv->exp_avg_noise = -85 + 0x100;
 
        priv->last_rate = 0;
        priv->last_missed_beacons = 0;
@@ -4008,7 +4015,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
        IPW_DEBUG_STATS("Tx quality   : %3d%% (%u errors, %u packets)\n",
                        tx_quality, tx_failures_delta, tx_packets_delta);
 
-       rssi = average_value(&priv->average_rssi);
+       rssi = priv->exp_avg_rssi;
        signal_quality =
            (100 *
             (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
@@ -4023,7 +4030,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
        else if (signal_quality < 1)
                signal_quality = 0;
 
-       IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
+       IPW_ERROR("Signal level : %3d%% (%d dBm)\n",
                        signal_quality, rssi);
 
        quality = min(beacon_quality,
@@ -4577,11 +4584,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
        case HOST_NOTIFICATION_NOISE_STATS:{
                        if (notif->size == sizeof(u32)) {
-                               priv->last_noise =
-                                   (u8) (le32_to_cpu(notif->u.noise.value) &
-                                         0xff);
-                               average_add(&priv->average_noise,
-                                           priv->last_noise);
+                               priv->exp_avg_noise =
+                                   exponential_average(priv->exp_avg_noise,
+                                   (u8) (le32_to_cpu(notif->u.noise.value) & 0xff),
+                                   DEPTH_NOISE);
                                break;
                        }
 
@@ -7837,9 +7843,9 @@ static void ipw_rx(struct ipw_priv *priv)
                                if (network_packet && priv->assoc_network) {
                                        priv->assoc_network->stats.rssi =
                                            stats.rssi;
-                                       average_add(&priv->average_rssi,
-                                                   stats.rssi);
-                                       priv->last_rx_rssi = stats.rssi;
+                                       priv->exp_avg_rssi =
+                                           exponential_average(priv->exp_avg_rssi,
+                                           stats.rssi, DEPTH_RSSI);
                                }
 
                                IPW_DEBUG_RX("Frame: len=%u\n",
@@ -9579,8 +9585,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
        }
 
        wstats->qual.qual = priv->quality;
-       wstats->qual.level = average_value(&priv->average_rssi);
-       wstats->qual.noise = average_value(&priv->average_noise);
+       wstats->qual.level = priv->exp_avg_rssi;
+       wstats->qual.noise = priv->exp_avg_noise;
        wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
            IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
 
index 4b9804900702875fc4d302dce052593b868df828..1f2cab3f9944fcd0db916a6f23f883a430c61003 100644 (file)
@@ -1153,11 +1153,9 @@ struct ipw_priv {
        u32 config;
        u32 capability;
 
-       u8 last_rx_rssi;
-       u8 last_noise;
        struct average average_missed_beacons;
-       struct average average_rssi;
-       struct average average_noise;
+       s16 exp_avg_rssi;
+       s16 exp_avg_noise;
        u32 port_type;
        int rx_bufs_min;          /**< minimum number of bufs in Rx queue */
        int rx_pend_max;          /**< maximum pending buffers for one IRQ */