diff options
author | Andrew Zaborowski | 2017-02-10 04:50:22 +0100 |
---|---|---|
committer | Johannes Berg | 2017-03-06 09:21:38 +0100 |
commit | 2c3c5f8c0cfa8e88a4c34d7651b5712c558ab9b7 (patch) | |
tree | 6447679da45f6515369ec382311af2050fa033ad /net/mac80211 | |
parent | 4a4b8169501b18c3450ac735a7e277b24886a651 (diff) |
mac80211: Add set_cqm_rssi_range_config
Support .set_cqm_rssi_range_config if the beacons are available for
processing in mac80211. There's no reason that this couldn't be
offloaded by mac80211-based drivers but there's no driver method for
that added in this patch.
Signed-off-by: Andrew Zaborowski <andrew.zaborowski@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 28 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 24 |
2 files changed, 52 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ac879bb17870..9c7490cb2243 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2630,6 +2630,33 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, bss_conf->cqm_rssi_thold = rssi_thold; bss_conf->cqm_rssi_hyst = rssi_hyst; + bss_conf->cqm_rssi_low = 0; + bss_conf->cqm_rssi_high = 0; + sdata->u.mgd.last_cqm_event_signal = 0; + + /* tell the driver upon association, unless already associated */ + if (sdata->u.mgd.associated && + sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI) + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM); + + return 0; +} + +static int ieee80211_set_cqm_rssi_range_config(struct wiphy *wiphy, + struct net_device *dev, + s32 rssi_low, s32 rssi_high) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_vif *vif = &sdata->vif; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + + if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER) + return -EOPNOTSUPP; + + bss_conf->cqm_rssi_low = rssi_low; + bss_conf->cqm_rssi_high = rssi_high; + bss_conf->cqm_rssi_thold = 0; + bss_conf->cqm_rssi_hyst = 0; sdata->u.mgd.last_cqm_event_signal = 0; /* tell the driver upon association, unless already associated */ @@ -3639,6 +3666,7 @@ const struct cfg80211_ops mac80211_config_ops = { .mgmt_tx = ieee80211_mgmt_tx, .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, + .set_cqm_rssi_range_config = ieee80211_set_cqm_rssi_range_config, .mgmt_frame_register = ieee80211_mgmt_frame_register, .set_antenna = ieee80211_set_antenna, .get_antenna = ieee80211_get_antenna, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 6e90301154d5..23986934d7af 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3430,6 +3430,30 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } } + if (bss_conf->cqm_rssi_low && + ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) { + int sig = -ewma_beacon_signal_read(&ifmgd->ave_beacon_signal); + int last_event = ifmgd->last_cqm_event_signal; + int low = bss_conf->cqm_rssi_low; + int high = bss_conf->cqm_rssi_high; + + if (sig < low && + (last_event == 0 || last_event >= low)) { + ifmgd->last_cqm_event_signal = sig; + ieee80211_cqm_rssi_notify( + &sdata->vif, + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + sig, GFP_KERNEL); + } else if (sig > high && + (last_event == 0 || last_event <= high)) { + ifmgd->last_cqm_event_signal = sig; + ieee80211_cqm_rssi_notify( + &sdata->vif, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + sig, GFP_KERNEL); + } + } + if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) { mlme_dbg_ratelimited(sdata, "cancelling AP probe due to a received beacon\n"); |