From cf935fd867065385b80e9cbd2ccfb9cbf56d1bb6 Mon Sep 17 00:00:00 2001 From: Carter Chen Date: Mon, 25 Dec 2023 01:50:16 -0600 Subject: [PATCH 208/296] brcmfmac: fixing mbss iovar setting for multiple BSS is enabled 1.) if the user enabled hostapd on wlan0, the type of wlan0 changes to AP_TYPE. 2.) then the user uses iw command to created a new interface wlan1, or wlan2 to AP mode. the vif->mbss belongs to wlan1, and wlan2 will always is "1" which causes while the start_ap is called, it highly relies on the interface's index to set related AP's parameter. if the first enabling AP interface is not the "first" interface with vif->mbss is "0", the upcoming ap interface enabling will fail. for example, - hostapd_cli -p /var/run/hostapd -i wlan2 disable - hostapd_cli -p /var/run/hostapd -i wlan1 disable - hostapd_cli -p /var/run/hostapd -i wlan0 disable - hostapd_cli -p /var/run/hostapd -i wlan2 enable //pass - hostapd_cli -p /var/run/hostapd -i wlan1 enable //fail - hostapd_cli -p /var/run/hostapd -i wlan0 enable //pass to make the judgement of check_vif_up can be workable. the command of disable shall add "ifconfig xxx down". for example, - hostapd_cli -p /var/run/hostapd -i wlan2 disable - ifconfig wlan2 down - hostapd_cli -p /var/run/hostapd -i wlan1 disable - ifconfig wlan1 down Signed-off-by: Carter Chen --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 71 +++++++++++++------ .../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 - .../broadcom/brcm80211/brcmfmac/fwil.h | 1 + 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 585ebf741c03..276c03b33ebb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5934,7 +5934,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype dev_role; struct brcmf_fil_bss_enable_le bss_enable; u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef); - bool mbss; + bool mbss = false; int is_11d; bool supports_11d; struct bcm_xtlv *he_tlv; @@ -5947,7 +5947,24 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, settings->ssid, settings->ssid_len, settings->auth_type, settings->inactivity_timeout); dev_role = ifp->vif->wdev.iftype; - mbss = ifp->vif->mbss; + + if (dev_role == NL80211_IFTYPE_AP && + brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { + struct brcmf_cfg80211_vif *vif_walk; + + list_for_each_entry(vif_walk, &cfg->vif_list, list) { + if (brcmf_is_apmode(vif_walk) && + check_vif_up(vif_walk) && + vif_walk != ifp->vif) { + /* found a vif is with the 1st AP type, + * and it doesn't equal to the currect vif calls start_ap. + * then it is mbss case. + */ + mbss = true; + break; + } + } + } brcmf_dbg(TRACE, "mbss %s\n", mbss ? "enabled" : "disabled"); /* store current 11d setting */ @@ -6041,8 +6058,29 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, ifp->isap = false; /* Interface specific setup */ if (dev_role == NL80211_IFTYPE_AP) { - if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss)) - brcmf_fil_iovar_int_set(ifp, "mbss", 1); + u32 is_up; + + if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && !mbss) { + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_UP, &is_up); + if (err < 0) { + bphy_err(drvr, "BRCMF_C_GET_UP error (%d)\n", err); + goto exit; + } + + /* mbss must be set in DOWN state. */ + if (is_up) { + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); + if (err < 0) { + bphy_err(drvr, "BRCMF_C_DOWN error (%d)\n", err); + goto exit; + } + } + err = brcmf_fil_iovar_int_set(ifp, "mbss", 1); + if (err < 0) { + bphy_err(drvr, "set mbss error (%d)\n", err); + goto exit; + } + } if (!test_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state)) { bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx); @@ -6072,7 +6110,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, goto exit; } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_UP, &is_up); + if (err < 0) { + bphy_err(drvr, "BRCMF_C_GET_UP error (%d)\n", err); + goto exit; + } + + if (!is_up) + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); if (err < 0) { bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err); goto exit; @@ -7282,10 +7327,7 @@ struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, enum nl80211_iftype type) { - struct brcmf_cfg80211_vif *vif_walk; struct brcmf_cfg80211_vif *vif; - bool mbss; - struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", sizeof(*vif)); @@ -7297,19 +7339,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, vif->wdev.iftype = type; brcmf_init_prof(&vif->profile); - - if (type == NL80211_IFTYPE_AP && - brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { - mbss = false; - list_for_each_entry(vif_walk, &cfg->vif_list, list) { - if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) { - mbss = true; - break; - } - } - vif->mbss = mbss; - } - init_completion(&vif->mgmt_tx); list_add_tail(&vif->list, &cfg->vif_list); return vif; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index 3c79f26c9c2c..6b2412b8dccf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -253,7 +253,6 @@ struct vif_saved_ie { * @sme_state: SME state using enum brcmf_vif_status bits. * @list: linked list. * @mgmt_rx_reg: registered rx mgmt frame types. - * @mbss: Multiple BSS type, set if not first AP (not relevant for P2P). * @cqm_rssi_low: Lower RSSI limit for CQM monitoring * @cqm_rssi_high: Upper RSSI limit for CQM monitoring * @cqm_rssi_last: Last RSSI reading for CQM monitoring @@ -269,7 +268,6 @@ struct brcmf_cfg80211_vif { unsigned long mgmt_tx_status; u32 mgmt_tx_id; u16 mgmt_rx_reg; - bool mbss; int is_11d; s32 cqm_rssi_low; s32 cqm_rssi_high; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h index c729ff69c48b..27dc9b9f1798 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h @@ -65,6 +65,7 @@ #define BRCMF_C_GET_BANDLIST 140 #define BRCMF_C_SET_SCB_TIMEOUT 158 #define BRCMF_C_GET_ASSOCLIST 159 +#define BRCMF_C_GET_UP 162 #define BRCMF_C_GET_PHYLIST 180 #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 -- 2.25.1