From: Johannes Berg This function is only called for at least HT capable stations, so doesn't need to differentiate 20/20_NOHT. Also, the check for VHT 160 MHz support is wrong, since a station could have support for both and the AP is using 80+80, but nothing cares anyway, so we don't need that. Simplify the function and move it to util.c since it now no longer is related to VHT, and also doesn't need a station. Also use the new function in ieee80211_get_sta_bw() for the chandef calculations, it just needs to handle the 20/20-noht separately; while at it fix that to handle HE stations. Reviewed-by: Miriam Rachel Korenblit Signed-off-by: Johannes Berg --- net/mac80211/chan.c | 38 +++++++++++--------------------------- net/mac80211/ht.c | 3 +-- net/mac80211/ieee80211_i.h | 5 +++-- net/mac80211/util.c | 19 +++++++++++++++++++ net/mac80211/vht.c | 34 +--------------------------------- 5 files changed, 35 insertions(+), 64 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 5e93405d70a3..b3d810e3691f 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -460,33 +460,17 @@ ieee80211_get_sta_bw(struct sta_info *sta, struct ieee80211_link_data *link) */ width = _ieee80211_sta_cap_rx_bw(link_sta, &link->conf->chanreq.oper); - switch (width) { - case IEEE80211_STA_RX_BW_20: - if (link_sta->pub->ht_cap.ht_supported) - return NL80211_CHAN_WIDTH_20; - else - return NL80211_CHAN_WIDTH_20_NOHT; - case IEEE80211_STA_RX_BW_40: - return NL80211_CHAN_WIDTH_40; - case IEEE80211_STA_RX_BW_80: - return NL80211_CHAN_WIDTH_80; - case IEEE80211_STA_RX_BW_160: - /* - * This applied for both 160 and 80+80. since we use - * the returned value to consider degradation of - * ctx->conf.min_def, we have to make sure to take - * the bigger one (NL80211_CHAN_WIDTH_160). - * Otherwise we might try degrading even when not - * needed, as the max required sta_bw returned (80+80) - * might be smaller than the configured bw (160). - */ - return NL80211_CHAN_WIDTH_160; - case IEEE80211_STA_RX_BW_320: - return NL80211_CHAN_WIDTH_320; - default: - WARN_ON(1); - return NL80211_CHAN_WIDTH_20; - } + if (width == IEEE80211_STA_RX_BW_20 && + !link_sta->pub->ht_cap.ht_supported && + !link_sta->pub->he_cap.has_he) + return NL80211_CHAN_WIDTH_20_NOHT; + + /* + * This returns 160 for both 160 and 80+80. Since we use + * the returned value to consider narrowing for + * ctx->conf.min_def, that's correct and necessary. + */ + return ieee80211_sta_rx_bw_to_chan_width(width); } static enum nl80211_chan_width diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 7d587f968a7f..3775d57d6c22 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -642,8 +642,7 @@ void ieee80211_ht_handle_chanwidth_notif(struct ieee80211_local *local, link_sta->pub->bandwidth = new_bw; sband = local->hw.wiphy->bands[band]; - sta_opmode.bw = - ieee80211_sta_rx_bw_to_chan_width(link_sta); + sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(new_bw); sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED; rate_control_rate_update(local, sband, link_sta, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 029600b3b7c0..3ab8368acaf9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2329,8 +2329,6 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata, struct ieee80211_sta_vht_cap *vht_cap); void ieee80211_get_vht_mask_from_cap(__le16 vht_cap, u16 vht_mask[NL80211_VHT_NSS_MAX]); -enum nl80211_chan_width -ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *sta); /* HE */ void @@ -2716,6 +2714,9 @@ void ieee80211_add_s1g_capab_ie(struct ieee80211_sub_if_data *sdata, void ieee80211_add_aid_request_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +enum nl80211_chan_width +ieee80211_sta_rx_bw_to_chan_width(enum ieee80211_sta_rx_bandwidth bw); + /* element building in SKBs */ int ieee80211_put_srates_elem(struct sk_buff *skb, const struct ieee80211_supported_band *sband, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b093bc203c81..a2ca8fd0c78a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3840,6 +3840,25 @@ void ieee80211_chandef_downgrade(struct cfg80211_chan_def *c, WARN_ON_ONCE(!cfg80211_chandef_valid(c)); } +enum nl80211_chan_width +ieee80211_sta_rx_bw_to_chan_width(enum ieee80211_sta_rx_bandwidth bw) +{ + switch (bw) { + case IEEE80211_STA_RX_BW_20: + return NL80211_CHAN_WIDTH_20; + case IEEE80211_STA_RX_BW_40: + return NL80211_CHAN_WIDTH_40; + case IEEE80211_STA_RX_BW_80: + return NL80211_CHAN_WIDTH_80; + case IEEE80211_STA_RX_BW_160: + return NL80211_CHAN_WIDTH_160; + case IEEE80211_STA_RX_BW_320: + return NL80211_CHAN_WIDTH_320; + default: + return NL80211_CHAN_WIDTH_20; + } +} + int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, struct cfg80211_csa_settings *csa_settings) { diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index c25190bc7c5c..17f3f281abe1 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -433,38 +433,6 @@ _ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta, link_sta->rx_omi_bw_rx); } -enum nl80211_chan_width -ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *link_sta) -{ - enum ieee80211_sta_rx_bandwidth cur_bw = - link_sta->pub->bandwidth; - struct ieee80211_sta_vht_cap *vht_cap = - &link_sta->pub->vht_cap; - u32 cap_width; - - switch (cur_bw) { - case IEEE80211_STA_RX_BW_20: - if (!link_sta->pub->ht_cap.ht_supported) - return NL80211_CHAN_WIDTH_20_NOHT; - else - return NL80211_CHAN_WIDTH_20; - case IEEE80211_STA_RX_BW_40: - return NL80211_CHAN_WIDTH_40; - case IEEE80211_STA_RX_BW_80: - return NL80211_CHAN_WIDTH_80; - case IEEE80211_STA_RX_BW_160: - cap_width = - vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; - - if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) - return NL80211_CHAN_WIDTH_160; - - return NL80211_CHAN_WIDTH_80P80; - default: - return NL80211_CHAN_WIDTH_20; - } -} - /* FIXME: rename/move - this deals with everything not just VHT */ enum ieee80211_sta_rx_bandwidth _ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta, @@ -671,7 +639,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, new_bw = ieee80211_sta_cur_vht_bw(link_sta); if (new_bw != link_sta->pub->bandwidth) { link_sta->pub->bandwidth = new_bw; - sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(link_sta); + sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(new_bw); changed |= IEEE80211_RC_BW_CHANGED; sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED; } -- 2.53.0