nl80211/mac80211: Report signal average
authorBruno Randolf <br1@einfach.org>
Tue, 16 Nov 2010 01:58:48 +0000 (10:58 +0900)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 18 Nov 2010 19:22:20 +0000 (14:22 -0500)
Extend nl80211 to report an exponential weighted moving average (EWMA) of the
signal value. Since the signal value usually fluctuates between different
packets, an average can be more useful than the value of the last packet.

This uses the recently added generic EWMA library function.

Signed-off-by: Bruno Randolf <br1@einfach.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/linux/nl80211.h
include/net/cfg80211.h
net/mac80211/Kconfig
net/mac80211/cfg.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/wireless/nl80211.c

index 037b4e498890fc52579f3525c45a57abafd543d7..1ce3775e9e26e60b654617b0c884c6b78bb3d1b5 100644 (file)
@@ -1161,6 +1161,7 @@ enum nl80211_rate_info {
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
+ * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm)
  * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
  *     containing info as possible, see &enum nl80211_sta_info_txrate.
  * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station)
@@ -1178,6 +1179,7 @@ enum nl80211_sta_info {
        NL80211_STA_INFO_PLID,
        NL80211_STA_INFO_PLINK_STATE,
        NL80211_STA_INFO_SIGNAL,
+       NL80211_STA_INFO_SIGNAL_AVG,
        NL80211_STA_INFO_TX_BITRATE,
        NL80211_STA_INFO_RX_PACKETS,
        NL80211_STA_INFO_TX_PACKETS,
index 8fd9eebd0cc98d97e93d5e7b33d51cf270898156..69e2364889f131c791fedff7b3ae1895cae2333f 100644 (file)
@@ -424,6 +424,7 @@ struct station_parameters {
  * @STATION_INFO_TX_RETRIES: @tx_retries filled
  * @STATION_INFO_TX_FAILED: @tx_failed filled
  * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
+ * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
  */
 enum station_info_flags {
        STATION_INFO_INACTIVE_TIME      = 1<<0,
@@ -439,6 +440,7 @@ enum station_info_flags {
        STATION_INFO_TX_RETRIES         = 1<<10,
        STATION_INFO_TX_FAILED          = 1<<11,
        STATION_INFO_RX_DROP_MISC       = 1<<12,
+       STATION_INFO_SIGNAL_AVG         = 1<<13,
 };
 
 /**
@@ -485,6 +487,7 @@ struct rate_info {
  * @plid: mesh peer link id
  * @plink_state: mesh peer link state
  * @signal: signal strength of last received packet in dBm
+ * @signal_avg: signal strength average in dBm
  * @txrate: current unicast bitrate to this station
  * @rx_packets: packets received from this station
  * @tx_packets: packets transmitted to this station
@@ -505,6 +508,7 @@ struct station_info {
        u16 plid;
        u8 plink_state;
        s8 signal;
+       s8 signal_avg;
        struct rate_info txrate;
        u32 rx_packets;
        u32 tx_packets;
index 4d6f8653ec8819a7e69cdb9cb447b77c1e7e7047..798d9b9462e22e13b7929c8a0a4fe0040d4bc02e 100644 (file)
@@ -6,6 +6,7 @@ config MAC80211
        select CRYPTO_ARC4
        select CRYPTO_AES
        select CRC32
+       select AVERAGE
        ---help---
          This option enables the hardware independent IEEE 802.11
          networking stack.
index 0c544074479e22efda3a89cbf73fd02d7248a0b5..92c9cf6a7d1c732a78be99dc16b8b82aa04b2c4c 100644 (file)
@@ -343,8 +343,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 
        if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
            (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
-               sinfo->filled |= STATION_INFO_SIGNAL;
+               sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
                sinfo->signal = (s8)sta->last_signal;
+               sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
        }
 
        sinfo->txrate.flags = 0;
index d2fcd22ab06d5987b228c3e1fbe99f75da4b440d..9dd60a74181f82019945784224ee6fedc04a29cc 100644 (file)
@@ -1156,6 +1156,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
        sta->rx_fragments++;
        sta->rx_bytes += rx->skb->len;
        sta->last_signal = status->signal;
+       ewma_add(&sta->avg_signal, -status->signal);
 
        /*
         * Change STA power saving mode only at the end of a frame
index eff58571fd7eb11eef08996c689d605f00585b9a..f43fca8907f75e2f294b8793e00d0d7e506860bf 100644 (file)
@@ -244,6 +244,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        sta->local = local;
        sta->sdata = sdata;
 
+       ewma_init(&sta->avg_signal, 1000, 8);
+
        if (sta_prepare_rate_control(local, sta, gfp)) {
                kfree(sta);
                return NULL;
index 9265acadef32d862c11889c2d96575147fcec972..84062e2c782c0bacaa468a987798477bc8dec193 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 #include <linux/workqueue.h>
+#include <linux/average.h>
 #include "key.h"
 
 /**
@@ -224,6 +225,7 @@ enum plink_state {
  * @rx_fragments: number of received MPDUs
  * @rx_dropped: number of dropped MPDUs from this STA
  * @last_signal: signal of last received frame from this STA
+ * @avg_signal: moving average of signal of received frames from this STA
  * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
  * @tx_filtered_count: number of frames the hardware filtered for this STA
  * @tx_retry_failed: number of frames that failed retry
@@ -291,6 +293,7 @@ struct sta_info {
        unsigned long rx_fragments;
        unsigned long rx_dropped;
        int last_signal;
+       struct ewma avg_signal;
        __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
 
        /* Updated from TX status path only, no locking requirements */
index 6055538422262b1b53f7b4bf68b6ddfe5796439d..d06a40d17002e9b64591215b793838ae5918f6b7 100644 (file)
@@ -1872,6 +1872,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
        if (sinfo->filled & STATION_INFO_SIGNAL)
                NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
                           sinfo->signal);
+       if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
+               NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
+                          sinfo->signal_avg);
        if (sinfo->filled & STATION_INFO_TX_BITRATE) {
                txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
                if (!txrate)
This page took 0.039484 seconds and 5 git commands to generate.