mac80211: Do not generate CQM events based on first Beacon frames
authorJouni Malinen <j@w1.fi>
Fri, 27 Aug 2010 19:22:00 +0000 (22:22 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 31 Aug 2010 18:20:40 +0000 (14:20 -0400)
The signal strength value in a single RX frame is not that reliable,
so it is better to delay start of CQM events until there is a real
average signal strength from more than a single Beacon frame
available.

Signed-off-by: Jouni Malinen <j@w1.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c

index 9af50fbcd48b1f9bdf9276585adf9cbb43198ab1..16f7fb164c2d158cffaa0153e44b194bfd74c1b2 100644 (file)
@@ -368,6 +368,13 @@ struct ieee80211_if_managed {
         */
        int ave_beacon_signal;
 
+       /*
+        * Number of Beacon frames used in ave_beacon_signal. This can be used
+        * to avoid generating less reliable cqm events that would be based
+        * only on couple of received frames.
+        */
+       unsigned int count_beacon_signal;
+
        /*
         * Last Beacon frame signal strength average (ave_beacon_signal / 16)
         * that triggered a cqm event. 0 indicates that no event has been
index 7915726d791e0dc8cf604670b7e472818fe13997..0cb822cc12e9c52618ddb18d5503db43765b9f11 100644 (file)
  */
 #define IEEE80211_SIGNAL_AVE_WEIGHT    3
 
+/*
+ * How many Beacon frames need to have been used in average signal strength
+ * before starting to indicate signal change events.
+ */
+#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
+
 #define TMR_RUNNING_TIMER      0
 #define TMR_RUNNING_CHANSW     1
 
@@ -1555,13 +1561,16 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
                ifmgd->ave_beacon_signal = rx_status->signal * 16;
                ifmgd->last_cqm_event_signal = 0;
+               ifmgd->count_beacon_signal = 1;
        } else {
                ifmgd->ave_beacon_signal =
                        (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
                         (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
                         ifmgd->ave_beacon_signal) / 16;
+               ifmgd->count_beacon_signal++;
        }
        if (bss_conf->cqm_rssi_thold &&
+           ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
            !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
                int sig = ifmgd->ave_beacon_signal / 16;
                int last_event = ifmgd->last_cqm_event_signal;