summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-03-30 02:28:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:46:42 -0400
commit17e4ec147f4939ca8c81b41b4261ec7974531381 (patch)
tree8066952a1dbef6656ac1f6d6a869326576b5006e /net/mac80211/mlme.c
parent32fbccafed7e935432b601f0453c2b702a385a25 (diff)
mac80211: Track Beacon signal strength and implement cqm events
Calculate a running average of the signal strength reported for Beacon frames and indicate cqm events if the average value moves below or above the configured threshold value (and filter out repetitive events with by using the configured hysteresis). Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c686d1b90f9f..de7519eb2b5d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -46,6 +46,13 @@
46 */ 46 */
47#define IEEE80211_PROBE_WAIT (HZ / 2) 47#define IEEE80211_PROBE_WAIT (HZ / 2)
48 48
49/*
50 * Weight given to the latest Beacon frame when calculating average signal
51 * strength for Beacon frames received in the current BSS. This must be
52 * between 1 and 15.
53 */
54#define IEEE80211_SIGNAL_AVE_WEIGHT 3
55
49#define TMR_RUNNING_TIMER 0 56#define TMR_RUNNING_TIMER 0
50#define TMR_RUNNING_CHANSW 1 57#define TMR_RUNNING_CHANSW 1
51 58
@@ -732,6 +739,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
732 sdata->u.mgd.associated = cbss; 739 sdata->u.mgd.associated = cbss;
733 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); 740 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
734 741
742 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
743
735 /* just to be sure */ 744 /* just to be sure */
736 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 745 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
737 IEEE80211_STA_BEACON_POLL); 746 IEEE80211_STA_BEACON_POLL);
@@ -1347,6 +1356,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1347 struct ieee80211_rx_status *rx_status) 1356 struct ieee80211_rx_status *rx_status)
1348{ 1357{
1349 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1358 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1359 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1350 size_t baselen; 1360 size_t baselen;
1351 struct ieee802_11_elems elems; 1361 struct ieee802_11_elems elems;
1352 struct ieee80211_local *local = sdata->local; 1362 struct ieee80211_local *local = sdata->local;
@@ -1382,6 +1392,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1382 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) 1392 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1383 return; 1393 return;
1384 1394
1395 /* Track average RSSI from the Beacon frames of the current AP */
1396 ifmgd->last_beacon_signal = rx_status->signal;
1397 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
1398 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
1399 ifmgd->ave_beacon_signal = rx_status->signal;
1400 ifmgd->last_cqm_event_signal = 0;
1401 } else {
1402 ifmgd->ave_beacon_signal =
1403 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
1404 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
1405 ifmgd->ave_beacon_signal) / 16;
1406 }
1407 if (bss_conf->cqm_rssi_thold &&
1408 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1409 int sig = ifmgd->ave_beacon_signal / 16;
1410 int last_event = ifmgd->last_cqm_event_signal;
1411 int thold = bss_conf->cqm_rssi_thold;
1412 int hyst = bss_conf->cqm_rssi_hyst;
1413 if (sig < thold &&
1414 (last_event == 0 || sig < last_event - hyst)) {
1415 ifmgd->last_cqm_event_signal = sig;
1416 ieee80211_cqm_rssi_notify(
1417 &sdata->vif,
1418 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
1419 GFP_KERNEL);
1420 } else if (sig > thold &&
1421 (last_event == 0 || sig > last_event + hyst)) {
1422 ifmgd->last_cqm_event_signal = sig;
1423 ieee80211_cqm_rssi_notify(
1424 &sdata->vif,
1425 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
1426 GFP_KERNEL);
1427 }
1428 }
1429
1385 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 1430 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1386#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1431#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1387 if (net_ratelimit()) { 1432 if (net_ratelimit()) {