The Apple firmware of the BCM4364 and BCM4377 runs Apple Wireless Direct Link (AWDL) itself and announces it with "awdl" in its capabilities. Add the feature flag for it. An AWDL interface is created with interface_create version 3 and interface type 2. The host gives the MAC address, the interface index and the BSSID, which the flags 0x2, 0x8 and 0x10 select. Add the definitions for the interface type and the two new flags. The BCM4350 firmware 7.35.180.133 lists "awdl" as well and answers every interface_create, including the version query, with BCME_UNSUPPORTED. Keep the flag only when the firmware reports interface_create version 3. Tested-by: Yossef Osman Tested-by: Aditya Garg Signed-off-by: Andre Eikmeyer --- .../broadcom/brcm80211/brcmfmac/feature.c | 26 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/feature.h | 3 ++- .../broadcom/brcm80211/brcmfmac/fwil_types.h | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index b324eb53a69..e7d5bc79c08 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -47,6 +47,7 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = { { BRCMF_FEAT_SAE_EXT, "sae_ext" }, { BRCMF_FEAT_FBT, "fbt" }, { BRCMF_FEAT_OKC, "okc" }, + { BRCMF_FEAT_AWDL, "awdl" }, }; #ifdef DEBUG @@ -294,6 +295,29 @@ static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data) return 0; } +/** + * brcmf_feat_awdl_check() - keep AWDL only with interface_create version 3. + * + * @ifp: interface to query. + * + * The AWDL interface is created with interface_create version 3. The + * BCM4350 firmware 7.35.180.133 lists "awdl" but answers every + * interface_create with BCME_UNSUPPORTED. + */ +static void brcmf_feat_awdl_check(struct brcmf_if *ifp) +{ + u32 ver = 0; + s32 err; + + err = brcmf_fil_bsscfg_int_query(ifp, "interface_create", &ver); + if (!err && ver == WL_INTERFACE_CREATE_VER_3) + return; + + brcmf_dbg(INFO, "disabling AWDL, interface_create version %u (%d)\n", + ver, err); + ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_AWDL); +} + void brcmf_feat_attach(struct brcmf_pub *drvr) { struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); @@ -303,6 +327,8 @@ void brcmf_feat_attach(struct brcmf_pub *drvr) s32 err; brcmf_feat_firmware_capabilities(ifp); + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_AWDL)) + brcmf_feat_awdl_check(ifp); memset(&gscan_cfg, 0, sizeof(gscan_cfg)); if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID && drvr->bus_if->chip != BRCM_CC_4345_CHIP_ID && diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h index 8165a286b63..0d98d4d7122 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h @@ -61,7 +61,8 @@ BRCMF_FEAT_DEF(PMKID_V3) \ BRCMF_FEAT_DEF(SAE_EXT) \ BRCMF_FEAT_DEF(FBT) \ - BRCMF_FEAT_DEF(OKC) + BRCMF_FEAT_DEF(OKC) \ + BRCMF_FEAT_DEF(AWDL) /* * Quirks: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index 6f13e10b16d..8d1532edbad 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -1244,9 +1244,12 @@ struct brcmf_mkeep_alive_pkt_le { #define WL_INTERFACE_MAC_DONT_USE 0x0 #define WL_INTERFACE_MAC_USE 0x2 +#define WL_INTERFACE_IF_INDEX_USE 0x8 +#define WL_INTERFACE_BSSID_USE 0x10 #define WL_INTERFACE_CREATE_STA 0x0 #define WL_INTERFACE_CREATE_AP 0x1 +#define WL_INTERFACE_CREATE_AWDL 0x2 struct wl_interface_create_v1 { u16 ver; /* structure version */