diff options
-rw-r--r-- | net/mac80211/ibss.c | 13 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 17 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 32 | ||||
-rw-r--r-- | net/mac80211/spectmgmt.c | 27 |
4 files changed, 48 insertions, 41 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 275bbb2c1a5a..a0ae02760139 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -836,13 +836,13 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, bool beacon) { struct cfg80211_csa_settings params; + struct ieee80211_csa_ie csa_ie; struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_chanctx *chanctx; enum nl80211_channel_type ch_type; int err, num_chanctx; u32 sta_flags; - u8 mode; if (sdata->vif.csa_active) return true; @@ -865,12 +865,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, } memset(¶ms, 0, sizeof(params)); + memset(&csa_ie, 0, sizeof(csa_ie)); err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, ifibss->chandef.chan->band, - sta_flags, ifibss->bssid, - ¶ms.count, &mode, - ¶ms.chandef); - + sta_flags, ifibss->bssid, &csa_ie); /* can't switch to destination channel, fail */ if (err < 0) goto disconnect; @@ -879,6 +877,9 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (err) return false; + params.count = csa_ie.count; + params.chandef = csa_ie.chandef; + if (ifibss->chandef.chan->band != params.chandef.chan->band) goto disconnect; @@ -965,7 +966,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, "received channel switch announcement to go to channel %d MHz\n", params.chandef.chan->center_freq); - params.block_tx = !!mode; + params.block_tx = !!csa_ie.mode; ieee80211_ibss_csa_beacon(sdata, ¶ms); sdata->csa_radar_required = params.radar_required; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ff3c310142b5..cbaea32bccf1 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1208,6 +1208,14 @@ struct ieee80211_ra_tid { u16 tid; }; +/* this struct holds the value parsing from channel switch IE */ +struct ieee80211_csa_ie { + struct cfg80211_chan_def chandef; + u8 mode; + u8 count; + u8 ttl; +}; + /* Parsed Information Elements */ struct ieee802_11_elems { const u8 *ie_start; @@ -1505,17 +1513,16 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT, * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ, * %IEEE80211_STA_DISABLE_160MHZ. - * @count: to be filled with the counter until the switch (on success only) * @bssid: the currently connected bssid (for reporting) - * @mode: to be filled with CSA mode (on success only) - * @new_chandef: to be filled with destination chandef (on success only) + * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl. + All of them will be filled with if success only. * Return: 0 on success, <0 on error and >0 if there is nothing to parse. */ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems, bool beacon, enum ieee80211_band current_band, - u32 sta_flags, u8 *bssid, u8 *count, u8 *mode, - struct cfg80211_chan_def *new_chandef); + u32 sta_flags, u8 *bssid, + struct ieee80211_csa_ie *csa_ie); /* Suspend/resume and hw reconfiguration */ int ieee80211_reconfig(struct ieee80211_local *local); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5cc1c274dd61..1305ff984d49 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -958,9 +958,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, struct cfg80211_bss *cbss = ifmgd->associated; struct ieee80211_chanctx *chanctx; enum ieee80211_band current_band; - u8 count; - u8 mode; - struct cfg80211_chan_def new_chandef = {}; + struct ieee80211_csa_ie csa_ie; int res; sdata_assert_lock(sdata); @@ -976,24 +974,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, return; current_band = cbss->channel->band; + memset(&csa_ie, 0, sizeof(csa_ie)); res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, ifmgd->flags, - ifmgd->associated->bssid, &count, - &mode, &new_chandef); + ifmgd->associated->bssid, &csa_ie); if (res < 0) ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); if (res) return; - if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef, + if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, IEEE80211_CHAN_DISABLED)) { sdata_info(sdata, "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", ifmgd->associated->bssid, - new_chandef.chan->center_freq, - new_chandef.width, new_chandef.center_freq1, - new_chandef.center_freq2); + csa_ie.chandef.chan->center_freq, + csa_ie.chandef.width, csa_ie.chandef.center_freq1, + csa_ie.chandef.center_freq2); ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); return; @@ -1037,9 +1035,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, } mutex_unlock(&local->chanctx_mtx); - local->csa_chandef = new_chandef; + local->csa_chandef = csa_ie.chandef; - if (mode) + if (csa_ie.mode) ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -1048,9 +1046,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, /* use driver's channel switch callback */ struct ieee80211_channel_switch ch_switch = { .timestamp = timestamp, - .block_tx = mode, - .chandef = new_chandef, - .count = count, + .block_tx = csa_ie.mode, + .chandef = csa_ie.chandef, + .count = csa_ie.count, }; drv_channel_switch(local, &ch_switch); @@ -1058,11 +1056,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, } /* channel switch handled in software */ - if (count <= 1) + if (csa_ie.count <= 1) ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); else mod_timer(&ifmgd->chswitch_timer, - TU_TO_EXP_TIME(count * cbss->beacon_interval)); + TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); } static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, @@ -3994,7 +3992,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } /* prepare assoc data */ - + ifmgd->beacon_crc_valid = false; /* diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 921597e279a3..a298e129633b 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -24,8 +24,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems, bool beacon, enum ieee80211_band current_band, - u32 sta_flags, u8 *bssid, u8 *count, u8 *mode, - struct cfg80211_chan_def *new_chandef) + u32 sta_flags, u8 *bssid, + struct ieee80211_csa_ie *csa_ie) { enum ieee80211_band new_band; int new_freq; @@ -62,13 +62,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, return -EINVAL; } new_chan_no = elems->ext_chansw_ie->new_ch_num; - *count = elems->ext_chansw_ie->count; - *mode = elems->ext_chansw_ie->mode; + csa_ie->count = elems->ext_chansw_ie->count; + csa_ie->mode = elems->ext_chansw_ie->mode; } else if (elems->ch_switch_ie) { new_band = current_band; new_chan_no = elems->ch_switch_ie->new_ch_num; - *count = elems->ch_switch_ie->count; - *mode = elems->ch_switch_ie->mode; + csa_ie->count = elems->ch_switch_ie->count; + csa_ie->mode = elems->ch_switch_ie->mode; } else { /* nothing here we understand */ return 1; @@ -103,25 +103,26 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, default: /* secondary_channel_offset was present but is invalid */ case IEEE80211_HT_PARAM_CHA_SEC_NONE: - cfg80211_chandef_create(new_chandef, new_chan, + cfg80211_chandef_create(&csa_ie->chandef, new_chan, NL80211_CHAN_HT20); break; case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - cfg80211_chandef_create(new_chandef, new_chan, + cfg80211_chandef_create(&csa_ie->chandef, new_chan, NL80211_CHAN_HT40PLUS); break; case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - cfg80211_chandef_create(new_chandef, new_chan, + cfg80211_chandef_create(&csa_ie->chandef, new_chan, NL80211_CHAN_HT40MINUS); break; case -1: - cfg80211_chandef_create(new_chandef, new_chan, + cfg80211_chandef_create(&csa_ie->chandef, new_chan, NL80211_CHAN_NO_HT); /* keep width for 5/10 MHz channels */ switch (sdata->vif.bss_conf.chandef.width) { case NL80211_CHAN_WIDTH_5: case NL80211_CHAN_WIDTH_10: - new_chandef->width = sdata->vif.bss_conf.chandef.width; + csa_ie->chandef.width = + sdata->vif.bss_conf.chandef.width; break; default: break; @@ -171,13 +172,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, /* if VHT data is there validate & use it */ if (new_vht_chandef.chan) { if (!cfg80211_chandef_compatible(&new_vht_chandef, - new_chandef)) { + &csa_ie->chandef)) { sdata_info(sdata, "BSS %pM: CSA has inconsistent channel data, disconnecting\n", bssid); return -EINVAL; } - *new_chandef = new_vht_chandef; + csa_ie->chandef = new_vht_chandef; } return 0; |