[PATCH 3/7] wifi: brcmfmac: detect AWDL support of the firmware

From: Andre Eikmeyer

Date: Wed Nov 04 2026 - 10:26:39 EST


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 <Yossef.Osman@xxxxxxxxx>
Tested-by: Aditya Garg <aditya.garg@xxxxxxxxx>
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
---
.../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 */