AP_VLAN interfaces do not maintain independent BSS configuration. When station information is reported for a 4-address station, BSS parameters are read from the AP_VLAN interface, causing beacon interval, DTIM period and BSS capability flags to be reported incorrectly. Read the BSS configuration from the parent AP when populating station information for AP_VLAN interfaces. This ensures that beacon interval, DTIM period, CTS protection, short preamble and short slot time reflect the parent AP configuration for both legacy and MLO station dumps. For MLO, the per-link BSS configuration is used so that CTS protection, short preamble and short slot time reflect the configuration of the corresponding parent AP link. Only advertise NL80211_STA_INFO_BSS_PARAM when a valid BSS configuration is available. This avoids reporting zero-valued BSS parameters when corresponding BSS configuration is unavailable. Co-developed-by: Ganesh Kariganuru Mahabalesh Signed-off-by: Ganesh Kariganuru Mahabalesh Signed-off-by: Aaradhana Sahu --- v2: -Remove unnecessary sdata->bss NULL check. --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/sta_info.c | 50 ++++++++++++++++++++++++-------------- net/mac80211/util.c | 17 +++++++++++++ 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 65311340db40..96978a4a7e2a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2985,6 +2985,8 @@ ieee80211_uhr_cap_ie_to_sta_uhr_cap(struct ieee80211_sub_if_data *sdata, const struct ieee80211_uhr_cap *uhr_cap, u8 uhr_cap_len, struct link_sta_info *link_sta); +struct ieee80211_bss_conf * +ieee80211_get_sdata_bss_conf(struct ieee80211_sub_if_data *sdata, int link_id); #if IS_ENABLED(CONFIG_MAC80211_KUNIT_TEST) #define EXPORT_SYMBOL_IF_MAC80211_KUNIT(sym) EXPORT_SYMBOL_IF_KUNIT(sym) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index fdf00cbf49d8..26c8b41042f8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2843,6 +2843,7 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct ieee80211_sta_rx_stats *last_rxstats; int i, ac, cpu, link_id = link->link_id; struct link_sta_info *link_sta_info; + struct ieee80211_bss_conf *bss_conf; u32 thr = 0; last_rxstats = sta_get_last_rx_stats(sta, link_id); @@ -2864,7 +2865,6 @@ static void sta_set_link_sinfo(struct sta_info *sta, link_sinfo); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | - BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); if (sdata->vif.type == NL80211_IFTYPE_STATION) { @@ -3038,14 +3038,21 @@ static void sta_set_link_sinfo(struct sta_info *sta, } link_sinfo->bss_param.flags = 0; - if (sdata->vif.bss_conf.use_cts_prot) - link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; - if (sdata->vif.bss_conf.use_short_preamble) - link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; - if (sdata->vif.bss_conf.use_short_slot) - link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; - link_sinfo->bss_param.dtim_period = link->conf->dtim_period; - link_sinfo->bss_param.beacon_interval = link->conf->beacon_int; + + bss_conf = ieee80211_get_sdata_bss_conf(sdata, link_id); + if (bss_conf) { + if (bss_conf->use_cts_prot) + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; + if (bss_conf->use_short_preamble) + link_sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (bss_conf->use_short_slot) + link_sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + link_sinfo->bss_param.dtim_period = bss_conf->dtim_period; + link_sinfo->bss_param.beacon_interval = bss_conf->beacon_int; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM); + } thr = sta_get_expected_throughput(sta); if (!thr && (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) @@ -3081,6 +3088,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, { struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; + struct ieee80211_bss_conf *bss_conf; u32 thr = 0; int i, ac, cpu; struct ieee80211_sta_rx_stats *last_rxstats; @@ -3099,7 +3107,6 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, drv_sta_statistics(local, sdata, &sta->sta, sinfo); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | BIT_ULL(NL80211_STA_INFO_STA_FLAGS) | - BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME) | BIT_ULL(NL80211_STA_INFO_ASSOC_AT_BOOTTIME) | BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); @@ -3268,14 +3275,21 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, #endif sinfo->bss_param.flags = 0; - if (sdata->vif.bss_conf.use_cts_prot) - sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; - if (sdata->vif.bss_conf.use_short_preamble) - sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; - if (sdata->vif.bss_conf.use_short_slot) - sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; - sinfo->bss_param.dtim_period = sdata->vif.bss_conf.dtim_period; - sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; + + bss_conf = ieee80211_get_sdata_bss_conf(sdata, -1); + if (bss_conf) { + if (bss_conf->use_cts_prot) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; + if (bss_conf->use_short_preamble) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (bss_conf->use_short_slot) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.dtim_period = bss_conf->dtim_period; + sinfo->bss_param.beacon_interval = bss_conf->beacon_int; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM); + } sinfo->sta_flags.set = 0; sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a96078a6bfa2..3f24862ba713 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -4752,3 +4752,20 @@ bool ieee80211_vif_nan_started(struct ieee80211_vif *vif) return vif->type == NL80211_IFTYPE_NAN && sdata->u.nan.started; } EXPORT_SYMBOL_GPL(ieee80211_vif_nan_started); + +struct ieee80211_bss_conf * +ieee80211_get_sdata_bss_conf(struct ieee80211_sub_if_data *sdata, int link_id) +{ + struct ieee80211_sub_if_data *bss_sdata = sdata; + + lockdep_assert_wiphy(sdata->local->hw.wiphy); + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + bss_sdata = get_bss_sdata(sdata); + + if (link_id >= 0) + return sdata_dereference(bss_sdata->vif.link_conf[link_id], + bss_sdata); + + return &bss_sdata->vif.bss_conf; +} base-commit: 27b084bdd009c5c82346d39d7773bab3191dd299 -- 2.34.1