|
@@ -3306,82 +3306,14 @@ static const u64 care_about_ies =
|
|
|
(1ULL << WLAN_EID_HT_OPERATION) |
|
|
|
(1ULL << WLAN_EID_EXT_CHANSWITCH_ANN);
|
|
|
|
|
|
-static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
- struct ieee80211_mgmt *mgmt, size_t len,
|
|
|
- struct ieee80211_rx_status *rx_status)
|
|
|
+static void ieee80211_handle_beacon_sig(struct ieee80211_sub_if_data *sdata,
|
|
|
+ struct ieee80211_if_managed *ifmgd,
|
|
|
+ struct ieee80211_bss_conf *bss_conf,
|
|
|
+ struct ieee80211_local *local,
|
|
|
+ struct ieee80211_rx_status *rx_status)
|
|
|
{
|
|
|
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
|
- struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
|
|
- size_t baselen;
|
|
|
- struct ieee802_11_elems elems;
|
|
|
- struct ieee80211_local *local = sdata->local;
|
|
|
- struct ieee80211_chanctx_conf *chanctx_conf;
|
|
|
- struct ieee80211_channel *chan;
|
|
|
- struct sta_info *sta;
|
|
|
- u32 changed = 0;
|
|
|
- bool erp_valid;
|
|
|
- u8 erp_value = 0;
|
|
|
- u32 ncrc;
|
|
|
- u8 *bssid;
|
|
|
- u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
|
|
-
|
|
|
- sdata_assert_lock(sdata);
|
|
|
-
|
|
|
- /* Process beacon from the current BSS */
|
|
|
- baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
|
|
|
- if (baselen > len)
|
|
|
- return;
|
|
|
-
|
|
|
- rcu_read_lock();
|
|
|
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
|
|
- if (!chanctx_conf) {
|
|
|
- rcu_read_unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
|
|
|
- rcu_read_unlock();
|
|
|
- return;
|
|
|
- }
|
|
|
- chan = chanctx_conf->def.chan;
|
|
|
- rcu_read_unlock();
|
|
|
-
|
|
|
- if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
|
|
|
- ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
|
|
|
- ieee802_11_parse_elems(mgmt->u.beacon.variable,
|
|
|
- len - baselen, false, &elems);
|
|
|
-
|
|
|
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
|
|
|
- if (elems.tim && !elems.parse_error) {
|
|
|
- const struct ieee80211_tim_ie *tim_ie = elems.tim;
|
|
|
- ifmgd->dtim_period = tim_ie->dtim_period;
|
|
|
- }
|
|
|
- ifmgd->have_beacon = true;
|
|
|
- ifmgd->assoc_data->need_beacon = false;
|
|
|
- if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
|
|
|
- sdata->vif.bss_conf.sync_tsf =
|
|
|
- le64_to_cpu(mgmt->u.beacon.timestamp);
|
|
|
- sdata->vif.bss_conf.sync_device_ts =
|
|
|
- rx_status->device_timestamp;
|
|
|
- if (elems.tim)
|
|
|
- sdata->vif.bss_conf.sync_dtim_count =
|
|
|
- elems.tim->dtim_count;
|
|
|
- else
|
|
|
- sdata->vif.bss_conf.sync_dtim_count = 0;
|
|
|
- }
|
|
|
- /* continue assoc process */
|
|
|
- ifmgd->assoc_data->timeout = jiffies;
|
|
|
- ifmgd->assoc_data->timeout_started = true;
|
|
|
- run_again(sdata, ifmgd->assoc_data->timeout);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!ifmgd->associated ||
|
|
|
- !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
|
|
|
- return;
|
|
|
- bssid = ifmgd->associated->bssid;
|
|
|
-
|
|
|
/* Track average RSSI from the Beacon frames of the current AP */
|
|
|
+
|
|
|
if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
|
|
|
ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
|
|
|
ewma_beacon_signal_init(&ifmgd->ave_beacon_signal);
|
|
@@ -3468,6 +3400,86 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
sig, GFP_KERNEL);
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
+ struct ieee80211_mgmt *mgmt, size_t len,
|
|
|
+ struct ieee80211_rx_status *rx_status)
|
|
|
+{
|
|
|
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
|
+ struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
|
|
+ size_t baselen;
|
|
|
+ struct ieee802_11_elems elems;
|
|
|
+ struct ieee80211_local *local = sdata->local;
|
|
|
+ struct ieee80211_chanctx_conf *chanctx_conf;
|
|
|
+ struct ieee80211_channel *chan;
|
|
|
+ struct sta_info *sta;
|
|
|
+ u32 changed = 0;
|
|
|
+ bool erp_valid;
|
|
|
+ u8 erp_value = 0;
|
|
|
+ u32 ncrc;
|
|
|
+ u8 *bssid;
|
|
|
+ u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
|
|
+
|
|
|
+ sdata_assert_lock(sdata);
|
|
|
+
|
|
|
+ /* Process beacon from the current BSS */
|
|
|
+ baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
|
|
|
+ if (baselen > len)
|
|
|
+ return;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
|
|
+ if (!chanctx_conf) {
|
|
|
+ rcu_read_unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
|
|
|
+ rcu_read_unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ chan = chanctx_conf->def.chan;
|
|
|
+ rcu_read_unlock();
|
|
|
+
|
|
|
+ if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
|
|
|
+ ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
|
|
|
+ ieee802_11_parse_elems(mgmt->u.beacon.variable,
|
|
|
+ len - baselen, false, &elems);
|
|
|
+
|
|
|
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
|
|
|
+ if (elems.tim && !elems.parse_error) {
|
|
|
+ const struct ieee80211_tim_ie *tim_ie = elems.tim;
|
|
|
+ ifmgd->dtim_period = tim_ie->dtim_period;
|
|
|
+ }
|
|
|
+ ifmgd->have_beacon = true;
|
|
|
+ ifmgd->assoc_data->need_beacon = false;
|
|
|
+ if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
|
|
|
+ sdata->vif.bss_conf.sync_tsf =
|
|
|
+ le64_to_cpu(mgmt->u.beacon.timestamp);
|
|
|
+ sdata->vif.bss_conf.sync_device_ts =
|
|
|
+ rx_status->device_timestamp;
|
|
|
+ if (elems.tim)
|
|
|
+ sdata->vif.bss_conf.sync_dtim_count =
|
|
|
+ elems.tim->dtim_count;
|
|
|
+ else
|
|
|
+ sdata->vif.bss_conf.sync_dtim_count = 0;
|
|
|
+ }
|
|
|
+ /* continue assoc process */
|
|
|
+ ifmgd->assoc_data->timeout = jiffies;
|
|
|
+ ifmgd->assoc_data->timeout_started = true;
|
|
|
+ run_again(sdata, ifmgd->assoc_data->timeout);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ifmgd->associated ||
|
|
|
+ !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
|
|
|
+ return;
|
|
|
+ bssid = ifmgd->associated->bssid;
|
|
|
+
|
|
|
+ if (!(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
|
|
|
+ ieee80211_handle_beacon_sig(sdata, ifmgd, bss_conf,
|
|
|
+ local, rx_status);
|
|
|
|
|
|
if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {
|
|
|
mlme_dbg_ratelimited(sdata,
|