summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPrasanna Kerekoppa <prasanna.kerekoppa@infineon.com>2022-09-29 08:06:13 +0300
committerKalle Valo <kvalo@kernel.org>2022-10-05 10:41:45 +0300
commit1562bdef925117dcd5a5678417c01f703be99589 (patch)
treeb9e829d8bb10ac6b4bc8ae43c68b383f081aad44 /drivers
parent4388827b87d849e51053e098c4e12c707b9fef34 (diff)
downloadlinux-1562bdef925117dcd5a5678417c01f703be99589.tar.xz
brcmfmac: Fix AP interface delete issue
Fixes the ap interface delete issue. Fix is to make sure interface is created with supported version. Patch has been verified by creating and deleting AP interface. Signed-off-by: Prasanna Kerekoppa <prasanna.kerekoppa@infineon.com> Signed-off-by: Ian Lin <ian.lin@infineon.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220929050614.31518-4-ian.lin@infineon.com
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c101
1 files changed, 90 insertions, 11 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index e5f0a9ef2d0f..bf184c0e64cb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -702,24 +702,103 @@ static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
{
+ struct wl_interface_create_v1 iface_v1;
+ struct wl_interface_create_v2 iface_v2;
+ struct wl_interface_create_v3 iface_v3;
+ u32 iface_create_ver;
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_mbss_ssid_le mbss_ssid_le;
int bsscfgidx;
int err;
- memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
- bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
- if (bsscfgidx < 0)
- return bsscfgidx;
+ /* interface_create version 1 */
+ memset(&iface_v1, 0, sizeof(iface_v1));
+ iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
+ iface_v1.flags = WL_INTERFACE_CREATE_AP |
+ WL_INTERFACE_MAC_USE;
- mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
- mbss_ssid_le.SSID_len = cpu_to_le32(5);
- sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
+ brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
- err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
- sizeof(mbss_ssid_le));
- if (err < 0)
- bphy_err(drvr, "setting ssid failed %d\n", err);
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v1,
+ sizeof(iface_v1));
+ if (err) {
+ brcmf_info("failed to create interface(v1), err=%d\n",
+ err);
+ } else {
+ brcmf_dbg(INFO, "interface created(v1)\n");
+ return 0;
+ }
+
+ /* interface_create version 2 */
+ memset(&iface_v2, 0, sizeof(iface_v2));
+ iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
+ iface_v2.flags = WL_INTERFACE_MAC_USE;
+ iface_v2.iftype = WL_INTERFACE_CREATE_AP;
+
+ brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v2,
+ sizeof(iface_v2));
+ if (err) {
+ brcmf_info("failed to create interface(v2), err=%d\n",
+ err);
+ } else {
+ brcmf_dbg(INFO, "interface created(v2)\n");
+ return 0;
+ }
+
+ /* interface_create version 3+ */
+ /* get supported version from firmware side */
+ iface_create_ver = 0;
+ err = brcmf_fil_bsscfg_int_get(ifp, "interface_create",
+ &iface_create_ver);
+ if (err) {
+ brcmf_err("fail to get supported version, err=%d\n", err);
+ return -EOPNOTSUPP;
+ }
+
+ switch (iface_create_ver) {
+ case WL_INTERFACE_CREATE_VER_3:
+ memset(&iface_v3, 0, sizeof(iface_v3));
+ iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
+ iface_v3.flags = WL_INTERFACE_MAC_USE;
+ iface_v3.iftype = WL_INTERFACE_CREATE_AP;
+ brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v3,
+ sizeof(iface_v3));
+
+ if (!err)
+ brcmf_dbg(INFO, "interface created(v3)\n");
+ break;
+ default:
+ brcmf_err("not support interface create(v%d)\n",
+ iface_create_ver);
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ if (err) {
+ brcmf_info("Does not support interface_create (%d)\n",
+ err);
+ memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
+ bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
+ if (bsscfgidx < 0)
+ return bsscfgidx;
+
+ mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
+ mbss_ssid_le.SSID_len = cpu_to_le32(5);
+ sprintf(mbss_ssid_le.SSID, "ssid%d", bsscfgidx);
+
+ err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
+ sizeof(mbss_ssid_le));
+
+ if (err < 0)
+ bphy_err(drvr, "setting ssid failed %d\n", err);
+ }
return err;
}