|
@@ -46,6 +46,13 @@
|
|
*/
|
|
*/
|
|
#define IEEE80211_PROBE_WAIT (HZ / 2)
|
|
#define IEEE80211_PROBE_WAIT (HZ / 2)
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Weight given to the latest Beacon frame when calculating average signal
|
|
|
|
+ * strength for Beacon frames received in the current BSS. This must be
|
|
|
|
+ * between 1 and 15.
|
|
|
|
+ */
|
|
|
|
+#define IEEE80211_SIGNAL_AVE_WEIGHT 3
|
|
|
|
+
|
|
#define TMR_RUNNING_TIMER 0
|
|
#define TMR_RUNNING_TIMER 0
|
|
#define TMR_RUNNING_CHANSW 1
|
|
#define TMR_RUNNING_CHANSW 1
|
|
|
|
|
|
@@ -732,6 +739,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|
sdata->u.mgd.associated = cbss;
|
|
sdata->u.mgd.associated = cbss;
|
|
memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
|
|
memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
|
|
|
|
|
|
|
|
+ sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
|
|
|
|
+
|
|
/* just to be sure */
|
|
/* just to be sure */
|
|
sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
|
|
sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
|
|
IEEE80211_STA_BEACON_POLL);
|
|
IEEE80211_STA_BEACON_POLL);
|
|
@@ -1347,6 +1356,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
struct ieee80211_rx_status *rx_status)
|
|
struct ieee80211_rx_status *rx_status)
|
|
{
|
|
{
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
|
|
+ struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
|
size_t baselen;
|
|
size_t baselen;
|
|
struct ieee802_11_elems elems;
|
|
struct ieee802_11_elems elems;
|
|
struct ieee80211_local *local = sdata->local;
|
|
struct ieee80211_local *local = sdata->local;
|
|
@@ -1382,6 +1392,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
|
|
if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ /* Track average RSSI from the Beacon frames of the current AP */
|
|
|
|
+ ifmgd->last_beacon_signal = rx_status->signal;
|
|
|
|
+ if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
|
|
|
|
+ ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
|
|
|
|
+ ifmgd->ave_beacon_signal = rx_status->signal;
|
|
|
|
+ ifmgd->last_cqm_event_signal = 0;
|
|
|
|
+ } else {
|
|
|
|
+ ifmgd->ave_beacon_signal =
|
|
|
|
+ (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
|
|
|
|
+ (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
|
|
|
|
+ ifmgd->ave_beacon_signal) / 16;
|
|
|
|
+ }
|
|
|
|
+ if (bss_conf->cqm_rssi_thold &&
|
|
|
|
+ !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
|
|
|
|
+ int sig = ifmgd->ave_beacon_signal / 16;
|
|
|
|
+ int last_event = ifmgd->last_cqm_event_signal;
|
|
|
|
+ int thold = bss_conf->cqm_rssi_thold;
|
|
|
|
+ int hyst = bss_conf->cqm_rssi_hyst;
|
|
|
|
+ if (sig < thold &&
|
|
|
|
+ (last_event == 0 || sig < last_event - hyst)) {
|
|
|
|
+ ifmgd->last_cqm_event_signal = sig;
|
|
|
|
+ ieee80211_cqm_rssi_notify(
|
|
|
|
+ &sdata->vif,
|
|
|
|
+ NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
|
|
|
|
+ GFP_KERNEL);
|
|
|
|
+ } else if (sig > thold &&
|
|
|
|
+ (last_event == 0 || sig > last_event + hyst)) {
|
|
|
|
+ ifmgd->last_cqm_event_signal = sig;
|
|
|
|
+ ieee80211_cqm_rssi_notify(
|
|
|
|
+ &sdata->vif,
|
|
|
|
+ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
|
|
|
|
+ GFP_KERNEL);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
|
|
if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
|
|
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
|
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
|
if (net_ratelimit()) {
|
|
if (net_ratelimit()) {
|