AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/01 05:50 flow patch-triage
2m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the brcmfmac and brcmsmac Broadcom wireless drivers. These are vendor-specific drivers that require physical Broadcom Wi-Fi hardware (PCIe, SDIO, or BCMA) to initialize and function. While brcmfmac supports USB, reaching the modified data paths (RX/TX) and cfg80211 callbacks requires passing a complex firmware loading and initialization handshake, which is impossible to achieve via random USB gadget fuzzing without a dedicated firmware emulator. Therefore, the modified code paths are unreachable in standard virtualized environments like QEMU.",
  "WorthFuzzing": false
}

1/1 2026/08/01 05:50 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 2a0dc1d8c1816e399e32e5a88c877b547825eff3\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sat Aug 1 05:50:07 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c\nindex 0b55d445895f2..7d7e5ececd229 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c\n@@ -3989,12 +3989,10 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,\n \n static __always_inline void brcmf_delay(u32 ms)\n {\n-\tif (ms \u003c 1000 / HZ) {\n-\t\tcond_resched();\n-\t\tmdelay(ms);\n-\t} else {\n+\tif (ms \u003c= 20)\n+\t\tusleep_range(ms * 1000, ms * 1000 + 1000);\n+\telse\n \t\tmsleep(ms);\n-\t}\n }\n \n static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],\n@@ -4364,6 +4362,104 @@ brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa,\n \treturn ret;\n }\n \n+/**\n+ * brcmf_pmksa_v2_op - update firmware PMKSA cache using the V2 list interface.\n+ *\n+ * V2 firmware (revision 12) uses a versioned flat list structure\n+ * (brcmf_pmk_list_v2_le) rather than the per-entry operation model of V3.\n+ * Each entry carries FILS-specific fields (raw PMK material, SSID, and\n+ * fils_cache_id) in addition to the basic BSSID + PMKID pair, enabling\n+ * FILS fast-roaming on devices that do not support V3.\n+ *\n+ * @cfg:   driver config structure holding the shadow V2 PMKSA list\n+ * @ifp:   interface pointer\n+ * @pmksa: the PMKSA to add/remove, or NULL for a flush\n+ * @alive: true = add (set time_left to no-expiry), false = remove/flush\n+ */\n+static s32\n+brcmf_pmksa_v2_op(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,\n+\t\t  struct cfg80211_pmksa *pmksa, bool alive)\n+{\n+\tstruct brcmf_pub *drvr = cfg-\u003epub;\n+\tstruct brcmf_pmk_list_v2_le *list = \u0026cfg-\u003epmk_list_v2;\n+\tstruct brcmf_pmksa_v2 *pmk = list-\u003epmk;\n+\tu32 npmk = le16_to_cpu(list-\u003elength);\n+\tu32 i;\n+\n+\t/* npmk here stores the count of valid entries, repurposing the\n+\t * length field of the shadow list as a counter.  We convert to\n+\t * the wire format (byte length) when sending to firmware.\n+\t */\n+\tif (!pmksa) {\n+\t\t/* Flush: zero the shadow list and push an empty V2 list. */\n+\t\tmemset(list, 0, sizeof(*list));\n+\t\tgoto send;\n+\t}\n+\n+\tif (alive) {\n+\t\t/* Set: search for existing BSSID match first. */\n+\t\tfor (i = 0; i \u003c npmk; i++)\n+\t\t\tif (!memcmp(pmksa-\u003ebssid, pmk[i].bssid, ETH_ALEN))\n+\t\t\t\tbreak;\n+\n+\t\tif (i \u003e= BRCMF_MAXPMKID) {\n+\t\t\tbphy_err(drvr, \"V2 PMKSA cache full (%d entries)\\n\",\n+\t\t\t\t npmk);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tmemset(\u0026pmk[i], 0, sizeof(pmk[i]));\n+\t\tpmk[i].length = cpu_to_le16(sizeof(struct brcmf_pmksa_v2));\n+\t\tif (pmksa-\u003ebssid)\n+\t\t\tmemcpy(pmk[i].bssid, pmksa-\u003ebssid, ETH_ALEN);\n+\t\tif (pmksa-\u003epmkid)\n+\t\t\tmemcpy(pmk[i].pmkid, pmksa-\u003epmkid, WLAN_PMKID_LEN);\n+\t\tif (pmksa-\u003epmk \u0026\u0026 pmksa-\u003epmk_len \u0026\u0026\n+\t\t    pmksa-\u003epmk_len \u003c= WLAN_PMK_LEN_SUITE_B_192) {\n+\t\t\tmemcpy(pmk[i].pmk, pmksa-\u003epmk, pmksa-\u003epmk_len);\n+\t\t\tpmk[i].pmk_len = cpu_to_le16(pmksa-\u003epmk_len);\n+\t\t}\n+\t\tif (pmksa-\u003essid \u0026\u0026 pmksa-\u003essid_len) {\n+\t\t\tmemcpy(pmk[i].ssid.SSID, pmksa-\u003essid, pmksa-\u003essid_len);\n+\t\t\tpmk[i].ssid.SSID_len = pmksa-\u003essid_len;\n+\t\t}\n+\t\tif (pmksa-\u003efils_cache_id)\n+\t\t\tpmk[i].fils_cache_id = *pmksa-\u003efils_cache_id;\n+\n+\t\tif (i == npmk)\n+\t\t\tnpmk++;\n+\t} else {\n+\t\t/* Delete: find by BSSID and compact the list. */\n+\t\tfor (i = 0; i \u003c npmk; i++)\n+\t\t\tif (!memcmp(pmksa-\u003ebssid, pmk[i].bssid, ETH_ALEN))\n+\t\t\t\tbreak;\n+\n+\t\tif (i \u003e= npmk) {\n+\t\t\tbphy_err(drvr, \"V2 PMKSA entry not found\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tfor (; i \u003c npmk - 1; i++)\n+\t\t\tmemcpy(\u0026pmk[i], \u0026pmk[i + 1], sizeof(pmk[i]));\n+\t\tmemset(\u0026pmk[npmk - 1], 0, sizeof(pmk[npmk - 1]));\n+\t\tnpmk--;\n+\t}\n+\n+\t/* Update shadow entry count (stored in length field). */\n+\tlist-\u003elength = cpu_to_le16(npmk);\n+\n+send:\n+\t/* Build the wire-format header and send the full list to firmware.\n+\t * version and length on the wire reflect the actual byte footprint.\n+\t */\n+\tlist-\u003eversion = cpu_to_le16(BRCMF_PMKSA_VER_2);\n+\tlist-\u003elength  = cpu_to_le16(offsetof(struct brcmf_pmk_list_v2_le, pmk) +\n+\t\t\t\t   npmk * sizeof(struct brcmf_pmksa_v2));\n+\n+\treturn brcmf_fil_iovar_data_set(ifp, \"pmkid_info\", list, sizeof(*list));\n+}\n+\n+\n static __used s32\n brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)\n {\n@@ -4402,8 +4498,8 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,\n \n \tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))\n \t\treturn brcmf_pmksa_v3_op(ifp, pmksa, true);\n-\n-\t/* TODO: implement PMKID_V2 */\n+\tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V2))\n+\t\treturn brcmf_pmksa_v2_op(cfg, ifp, pmksa, true);\n \n \tnpmk = le32_to_cpu(cfg-\u003epmk_list.npmk);\n \tfor (i = 0; i \u003c npmk; i++)\n@@ -4446,8 +4542,8 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,\n \n \tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))\n \t\treturn brcmf_pmksa_v3_op(ifp, pmksa, false);\n-\n-\t/* TODO: implement PMKID_V2 */\n+\tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V2))\n+\t\treturn brcmf_pmksa_v2_op(cfg, ifp, pmksa, false);\n \n \tnpmk = le32_to_cpu(cfg-\u003epmk_list.npmk);\n \tfor (i = 0; i \u003c npmk; i++)\n@@ -4487,8 +4583,8 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)\n \n \tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))\n \t\treturn brcmf_pmksa_v3_op(ifp, NULL, false);\n-\n-\t/* TODO: implement PMKID_V2 */\n+\tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V2))\n+\t\treturn brcmf_pmksa_v2_op(cfg, ifp, NULL, false);\n \n \tmemset(\u0026cfg-\u003epmk_list, 0, sizeof(cfg-\u003epmk_list));\n \terr = brcmf_update_pmklist(cfg, ifp);\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h\nindex 6ceb301429054..57167fde5ba15 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h\n@@ -344,7 +344,8 @@ struct brcmf_cfg80211_wowl {\n  * @bss_list: bss_list holding scanned ap information.\n  * @bss_info: bss information for cfg80211 layer.\n  * @conn_info: association info.\n- * @pmk_list: wpa2 pmk list.\n+ * @pmk_list: wpa2 pmk list (V1 firmware).\n+ * @pmk_list_v2: wpa2 pmk list for V2 firmware (FILS-capable, firmware rev 12).\n  * @scan_status: scan activity on the dongle.\n  * @pub: common driver information.\n  * @channel: current channel.\n@@ -376,6 +377,7 @@ struct brcmf_cfg80211_info {\n \tstruct wl_cfg80211_bss_info *bss_info;\n \tstruct brcmf_cfg80211_connect_info conn_info;\n \tstruct brcmf_pmk_list_le pmk_list;\n+\tstruct brcmf_pmk_list_v2_le pmk_list_v2;\n \tunsigned long scan_status;\n \tstruct brcmf_pub *pub;\n \tu32 channel;\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c\nindex ec170647800da..673f0000389cc 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c\n@@ -431,45 +431,51 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)\n \tnetif_rx(skb);\n }\n \n+struct brcmf_radiotap_info {\n+\tstruct ieee80211_radiotap_header hdr;\n+\ts8 dbm_antsignal;\n+} __packed;\n+\n void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)\n {\n \tif (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {\n-\t\t/* Do nothing */\n+\t\t/* Firmware already provided a full radiotap header; do nothing */\n \t} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) {\n \t\tstruct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb-\u003edata;\n-\t\tstruct ieee80211_radiotap_header *radiotap;\n+\t\tstruct brcmf_radiotap_info *rtap;\n \t\tunsigned int offset;\n \t\tu16 RxStatus1;\n+\t\ts8 rssi;\n \n \t\tRxStatus1 = le16_to_cpu(wlc_rxhdr-\u003erxhdr.RxStatus1);\n+\t\trssi = wlc_rxhdr-\u003erssi;\n \n \t\toffset = sizeof(struct wlc_d11rxhdr);\n-\t\t/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU\n-\t\t * subframes\n-\t\t */\n+\t\t/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */\n \t\tif (RxStatus1 \u0026 RXS_PBPRES)\n \t\t\toffset += 2;\n \t\toffset += D11_PHY_HDR_LEN;\n \n \t\tskb_pull(skb, offset);\n \n-\t\t/* TODO: use RX header to fill some radiotap data */\n-\t\tradiotap = skb_push(skb, sizeof(*radiotap));\n-\t\tmemset(radiotap, 0, sizeof(*radiotap));\n-\t\tradiotap-\u003eit_len = cpu_to_le16(sizeof(*radiotap));\n+\t\t/* Insert our radiotap header with RSSI data */\n+\t\trtap = skb_push(skb, sizeof(*rtap));\n+\t\tmemset(rtap, 0, sizeof(*rtap));\n+\t\trtap-\u003ehdr.it_len = cpu_to_le16(sizeof(*rtap));\n+\t\trtap-\u003ehdr.it_present = cpu_to_le32(1 \u003c\u003c IEEE80211_RADIOTAP_DBM_ANTSIGNAL);\n+\t\trtap-\u003edbm_antsignal = rssi;\n \n-\t\t/* TODO: 4 bytes with receive status? */\n-\t\tskb-\u003elen -= 4;\n+\t\t/* Strip the 4-byte receive status / FCS tail */\n+\t\tskb_trim(skb, skb-\u003elen - 4);\n \t} else {\n \t\tstruct ieee80211_radiotap_header *radiotap;\n \n-\t\t/* TODO: use RX status to fill some radiotap data */\n \t\tradiotap = skb_push(skb, sizeof(*radiotap));\n \t\tmemset(radiotap, 0, sizeof(*radiotap));\n \t\tradiotap-\u003eit_len = cpu_to_le16(sizeof(*radiotap));\n \n-\t\t/* TODO: 4 bytes with receive status? */\n-\t\tskb-\u003elen -= 4;\n+\t\t/* Strip the 4-byte receive status / FCS tail */\n+\t\tskb_trim(skb, skb-\u003elen - 4);\n \t}\n \n \tskb-\u003edev = ifp-\u003endev;\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c\nindex 35cbcea0abc9a..b9c518939f504 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c\n@@ -182,10 +182,8 @@ static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid,\n \tstruct brcmf_bus *bus_if;\n \tstruct brcmf_pub *drvr;\n \tstruct brcmf_if *ifp;\n-\tbool currently_blocked;\n-\tint i;\n-\tu8 ifidx;\n \tunsigned long flags;\n+\tu8 ifidx;\n \n \tspin_lock_irqsave(\u0026flow-\u003eblock_lock, flags);\n \n@@ -194,23 +192,54 @@ static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid,\n \t\tspin_unlock_irqrestore(\u0026flow-\u003eblock_lock, flags);\n \t\treturn;\n \t}\n-\tifidx = brcmf_flowring_ifidx_get(flow, flowid);\n \n-\tcurrently_blocked = false;\n-\tfor (i = 0; i \u003c flow-\u003enrofrings; i++) {\n-\t\tif ((flow-\u003erings[i]) \u0026\u0026 (i != flowid)) {\n-\t\t\tring = flow-\u003erings[i];\n-\t\t\tif ((ring-\u003estatus == RING_OPEN) \u0026\u0026\n-\t\t\t    (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {\n-\t\t\t\tif (ring-\u003eblocked) {\n-\t\t\t\t\tcurrently_blocked = true;\n-\t\t\t\t\tbreak;\n-\t\t\t\t}\n-\t\t\t}\n+\tifidx = brcmf_flowring_ifidx_get(flow, flowid);\n+\tring-\u003eblocked = blocked;\n+\n+\t/*\n+\t * Maintain the per-interface blocked-ring counter.\n+\t *\n+\t * We use ring-\u003ecounted_in_blocked rather than checking\n+\t * ring-\u003estatus here.  A ring that became blocked while\n+\t * RING_OPEN has already been counted (counted_in_blocked=true).\n+\t * By the time we unblock it during teardown its status may have\n+\t * advanced to RING_CLOSING, so testing RING_OPEN would wrongly\n+\t * skip the atomic_dec and permanently leak the counter, leaving\n+\t * the netif queue stopped forever.\n+\t *\n+\t * Rule:\n+\t *   block transition  (unblocked→blocked): count only if RING_OPEN,\n+\t *                                          set counted_in_blocked.\n+\t *   unblock transition (blocked→unblocked): decrement only if we\n+\t *                                          previously counted it,\n+\t *                                          clear counted_in_blocked.\n+\t */\n+\tif (blocked) {\n+\t\tif (ring-\u003estatus == RING_OPEN) {\n+\t\t\tatomic_inc(\u0026flow-\u003eif_blocked_cnt[ifidx]);\n+\t\t\tring-\u003ecounted_in_blocked = true;\n \t\t}\n+\t} else {\n+\t\tif (ring-\u003ecounted_in_blocked) {\n+\t\t\tatomic_dec(\u0026flow-\u003eif_blocked_cnt[ifidx]);\n+\t\t\tring-\u003ecounted_in_blocked = false;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Only propagate a netif queue-stop/wake when the interface\n+\t * transitions between fully-clear and at-least-one-blocked.\n+\t * Reading the atomic is safe here: we hold block_lock, so no\n+\t * concurrent brcmf_flowring_block() call can race the update\n+\t * we just made above.\n+\t */\n+\tif (blocked \u0026\u0026 atomic_read(\u0026flow-\u003eif_blocked_cnt[ifidx]) != 1) {\n+\t\t/* Another ring was already blocked; no new queue-stop needed. */\n+\t\tspin_unlock_irqrestore(\u0026flow-\u003eblock_lock, flags);\n+\t\treturn;\n \t}\n-\tflow-\u003erings[flowid]-\u003eblocked = blocked;\n-\tif (currently_blocked) {\n+\tif (!blocked \u0026\u0026 atomic_read(\u0026flow-\u003eif_blocked_cnt[ifidx]) != 0) {\n+\t\t/* More rings still blocked; do not wake the queue yet. */\n \t\tspin_unlock_irqrestore(\u0026flow-\u003eblock_lock, flags);\n \t\treturn;\n \t}\n@@ -367,6 +396,8 @@ struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings)\n \t\tspin_lock_init(\u0026flow-\u003eblock_lock);\n \t\tfor (i = 0; i \u003c ARRAY_SIZE(flow-\u003eaddr_mode); i++)\n \t\t\tflow-\u003eaddr_mode[i] = ADDR_INDIRECT;\n+\t\tfor (i = 0; i \u003c ARRAY_SIZE(flow-\u003eif_blocked_cnt); i++)\n+\t\t\tatomic_set(\u0026flow-\u003eif_blocked_cnt[i], 0);\n \t\tfor (i = 0; i \u003c ARRAY_SIZE(flow-\u003ehash); i++)\n \t\t\tflow-\u003ehash[i].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;\n \t}\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h\nindex f3d511f9a3c9a..afdea8b3f8aa7 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h\n@@ -5,6 +5,8 @@\n #ifndef BRCMFMAC_FLOWRING_H\n #define BRCMFMAC_FLOWRING_H\n \n+#include \u003clinux/atomic.h\u003e\n+\n \n #define BRCMF_FLOWRING_HASHSIZE\t\t512\t\t/* has to be 2^x */\n #define BRCMF_FLOWRING_INVALID_ID\t0xFFFFFFFF\n@@ -26,6 +28,16 @@ enum ring_status {\n struct brcmf_flowring_ring {\n \tu16 hash_id;\n \tbool blocked;\n+\t/*\n+\t * True when this ring has been counted in the per-interface\n+\t * if_blocked_cnt[].  Set to true whenever the ring transitions\n+\t * unblocked→blocked while RING_OPEN; cleared on the matching\n+\t * blocked→unblocked transition.  Needed so that a ring that\n+\t * becomes blocked while RING_OPEN and is later moved to\n+\t * RING_CLOSING still correctly decrements the counter at\n+\t * teardown, even though its status is no longer RING_OPEN.\n+\t */\n+\tbool counted_in_blocked;\n \tenum ring_status status;\n \tstruct sk_buff_head skblist;\n };\n@@ -40,6 +52,12 @@ struct brcmf_flowring {\n \tstruct brcmf_flowring_hash hash[BRCMF_FLOWRING_HASHSIZE];\n \tspinlock_t block_lock;\n \tenum proto_addr_mode addr_mode[BRCMF_MAX_IFS];\n+\t/* Per-interface count of currently blocked open rings.\n+\t * Maintained atomically so brcmf_flowring_block() can check\n+\t * whether any sibling ring is already blocked in O(1) without\n+\t * holding block_lock across an O(nrofrings) walk.\n+\t */\n+\tatomic_t if_blocked_cnt[BRCMF_MAX_IFS];\n \tu16 nrofrings;\n \tbool tdls_active;\n \tstruct brcmf_flowring_tdls_entry *tdls_entry;\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c\nindex a43f1a38b0e30..3c1ca355e8eec 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c\n@@ -1037,7 +1037,9 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)\n \t\t} else {\n \t\t\tbrcmf_dbg(TRACE, \"use existing\\n\");\n \t\t\tWARN_ON(entry-\u003emac_handle != mac_handle);\n-\t\t\t/* TODO: what should we do here: continue, reinit, .. */\n+\t\t\t/* Firmware re-sent ADD for the same MAC handle.\n+\t\t\t * No action required; it is a safe no-op.\n+\t\t\t */\n \t\t}\n \t}\n \treturn 0;\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c\nindex ba1ce1552e0f4..8db6167072da3 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c\n@@ -48,7 +48,19 @@\n #define MSGBUF_TYPE_LPBK_DMAXFER\t\t0x13\n #define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT\t\t0x14\n \n-#define NR_TX_PKTIDS\t\t\t\t2048\n+/*\n+ * NR_TX_PKTIDS: number of simultaneously in-flight TX packet IDs.\n+ * Each outstanding TX frame consumes one ID until the dongle returns\n+ * a TX-status completion.  The original 2048-entry pool exhausted under\n+ * ≥4 concurrent iperf3 streams on Wi-Fi 5/6 (802.11ac/ax) devices,\n+ * causing \"No PKTID available\" drops and TCP retransmits.  4096 gives\n+ * headroom for high-aggregation scenarios while still fitting in a\n+ * modest amount of host memory (~48 KB for the pktid table entries).\n+ *\n+ * NR_RX_PKTIDS: RX post buffers pre-allocated to the dongle.  1024 is\n+ * sufficient for current hardware RX ring depths; leave unchanged.\n+ */\n+#define NR_TX_PKTIDS\t\t\t\t4096\n #define NR_RX_PKTIDS\t\t\t\t1024\n \n #define BRCMF_IOCTL_REQ_PKTID\t\t\t0xFFFE\n@@ -64,8 +76,29 @@\n #define BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK\t0x07\n #define BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT\t5\n \n-#define BRCMF_MSGBUF_TX_FLUSH_CNT1\t\t32\n-#define BRCMF_MSGBUF_TX_FLUSH_CNT2\t\t96\n+/*\n+ * TX flush / doorbell-ring thresholds.\n+ *\n+ * CNT1 is the minimum number of frames to accumulate in the commonring\n+ * before the first intermediate write_complete() (doorbell ring) is\n+ * issued mid-batch.  CNT2 is the hard flush interval: after this many\n+ * frames have been written since the last flush, we unconditionally\n+ * ring the bell and reset the counter.\n+ *\n+ * Raising both from the original 32/96 to 64/128 doubles the average\n+ * number of TX descriptors committed per MMIO write, halving the PCIe\n+ * doorbell rate on sustained throughput workloads.  The tradeoff is a\n+ * marginally higher worst-case latency for the last frames in a burst,\n+ * which in practice is hidden by the time the dongle DMA engine drains\n+ * the previous batch.\n+ *\n+ * TRICKLE_TXWORKER_THRS governs how often brcmf_msgbuf_tx_queue_data()\n+ * forces a workqueue schedule when the queue depth is not a multiple of\n+ * this value.  Keeping it at half of CNT1 (32) preserves responsiveness\n+ * for low-rate flows (e.g. VoIP, ICMP) that never accumulate 64 frames.\n+ */\n+#define BRCMF_MSGBUF_TX_FLUSH_CNT1\t\t64\n+#define BRCMF_MSGBUF_TX_FLUSH_CNT2\t\t128\n \n #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS\t96\n #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS\t32\n@@ -787,10 +820,30 @@ static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid,\n {\n \tstruct brcmf_commonring *commonring;\n \n-\tset_bit(flowid, msgbuf-\u003eflow_map);\n+\t/*\n+\t * If the bit was already set, a txflow_work item is already\n+\t * queued or running for this ring.  In that case the existing\n+\t * worker will drain our freshly enqueued frame when it runs,\n+\t * so we only need to schedule another work item when the\n+\t * force flag is set or the ring is below the delay threshold.\n+\t *\n+\t * If the bit was NOT set (test_and_set_bit returns false), no\n+\t * worker is pending for this ring at all.  We MUST schedule\n+\t * one unconditionally, otherwise the frame we just enqueued\n+\t * will sit in the flowring unsent until some unrelated event\n+\t * triggers the workqueue — causing silent TX stalls under\n+\t * high load when outstanding_tx \u003e= DELAY_TXWORKER_THRS.\n+\t */\n+\tif (!test_and_set_bit(flowid, msgbuf-\u003eflow_map)) {\n+\t\t/* Bit was clear: no worker pending, always schedule. */\n+\t\tqueue_work(msgbuf-\u003etxflow_wq, \u0026msgbuf-\u003etxflow_work);\n+\t\treturn 0;\n+\t}\n+\n+\t/* Bit was already set: worker pending, apply coalescing heuristic. */\n \tcommonring = msgbuf-\u003eflowrings[flowid];\n-\tif ((force) || (atomic_read(\u0026commonring-\u003eoutstanding_tx) \u003c\n-\t\t\tBRCMF_MSGBUF_DELAY_TXWORKER_THRS))\n+\tif (force || (atomic_read(\u0026commonring-\u003eoutstanding_tx) \u003c\n+\t\t      BRCMF_MSGBUF_DELAY_TXWORKER_THRS))\n \t\tqueue_work(msgbuf-\u003etxflow_wq, \u0026msgbuf-\u003etxflow_work);\n \n \treturn 0;\n@@ -1621,11 +1674,11 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)\n \tdo {\n \t\tbrcmf_msgbuf_rxbuf_data_fill(msgbuf);\n \t\tif (msgbuf-\u003emax_rxbufpost != msgbuf-\u003erxbufpost)\n-\t\t\tmsleep(10);\n+\t\t\tusleep_range(1000, 2000);\n \t\telse\n \t\t\tbreak;\n \t\tcount++;\n-\t} while (count \u003c 10);\n+\t} while (count \u003c 100);\n \tbrcmf_msgbuf_rxbuf_event_post(msgbuf);\n \tbrcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);\n \ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c\nindex 13662aa4b4ea6..9338a5faa260a 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c\n@@ -268,6 +268,27 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {\n \n #define BRCMF_PCIE_MBDATA_TIMEOUT\t\tmsecs_to_jiffies(2000)\n \n+/*\n+ * H2D mailbox poll timing parameters.\n+ *\n+ * The dongle typically clears the H2D mailbox register within a few\n+ * hundred microseconds after the doorbell interrupt fires.  The\n+ * original code used msleep(10) * 100 iterations, meaning the\n+ * minimum observable latency was 10ms even when the dongle was fast.\n+ *\n+ * We instead start with a short sleep and double it each iteration\n+ * (exponential backoff) up to BRCMF_PCIE_MB_POLL_MAX_US, staying\n+ * within the same 1-second absolute timeout.\n+ *\n+ * MIN_US / INITIAL_MAX_US : usleep_range bounds for the first iteration.\n+ * MAX_US     : cap on the per-iteration sleep (µs).\n+ * TIMEOUT_US : total budget before giving up (1 second).\n+ */\n+#define BRCMF_PCIE_MB_POLL_MIN_US\t\t40\n+#define BRCMF_PCIE_MB_POLL_INITIAL_MAX_US\t50\n+#define BRCMF_PCIE_MB_POLL_MAX_US\t\t5000\n+#define BRCMF_PCIE_MB_POLL_TIMEOUT_US\t\t1000000\n+\n #define BRCMF_PCIE_CFGREG_STATUS_CMD\t\t0x4\n #define BRCMF_PCIE_CFGREG_PM_CSR\t\t0x4C\n #define BRCMF_PCIE_CFGREG_MSI_CAP\t\t0x58\n@@ -766,7 +787,8 @@ brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)\n \tstruct brcmf_core *core;\n \tu32 addr;\n \tu32 cur_htod_mb_data;\n-\tu32 i;\n+\tu32 elapsed_us = 0;\n+\tu32 sleep_us = BRCMF_PCIE_MB_POLL_INITIAL_MAX_US;\n \n \tshared = \u0026devinfo-\u003eshared;\n \taddr = shared-\u003ehtod_mb_data_addr;\n@@ -776,12 +798,40 @@ brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)\n \t\tbrcmf_dbg(PCIE, \"MB transaction is already pending 0x%04x\\n\",\n \t\t\t  cur_htod_mb_data);\n \n-\ti = 0;\n+\t/*\n+\t * Wait for the dongle to consume the previous H2D mailbox message.\n+\t *\n+\t * There is no interrupt that signals when the dongle clears this\n+\t * register, so polling is unavoidable.  The original code used\n+\t * msleep(10) per iteration, incurring at least 10ms of latency\n+\t * even when the dongle responded in microseconds.\n+\t *\n+\t * We use usleep_range() with exponential backoff instead:\n+\t *   - First iteration sleeps ~50µs (fast path for responsive dongle).\n+\t *   - Each subsequent iteration doubles the sleep, capped at 5ms,\n+\t *     so long waits still yield the CPU without busy-spinning.\n+\t *   - Total timeout matches the original 1-second limit.\n+\t *   - We bail early if the device has gone down so that a dead\n+\t *     dongle does not hold the caller for a full second.\n+\t */\n \twhile (cur_htod_mb_data != 0) {\n-\t\tmsleep(10);\n-\t\ti++;\n-\t\tif (i \u003e 100)\n+\t\tif (devinfo-\u003estate == BRCMFMAC_PCIE_STATE_DOWN) {\n+\t\t\tbrcmf_dbg(PCIE, \"Device down, aborting MB send\\n\");\n \t\t\treturn -EIO;\n+\t\t}\n+\n+\t\tif (elapsed_us \u003e= BRCMF_PCIE_MB_POLL_TIMEOUT_US) {\n+\t\t\tbrcmf_err(\"Timeout waiting for H2D MB slot after %u us\\n\",\n+\t\t\t\t  elapsed_us);\n+\t\t\treturn -EIO;\n+\t\t}\n+\n+\t\tusleep_range(BRCMF_PCIE_MB_POLL_MIN_US, sleep_us);\n+\t\telapsed_us += sleep_us;\n+\n+\t\t/* Exponential backoff, capped at BRCMF_PCIE_MB_POLL_MAX_US */\n+\t\tsleep_us = min(sleep_us * 2, (u32)BRCMF_PCIE_MB_POLL_MAX_US);\n+\n \t\tcur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);\n \t}\n \n@@ -1001,10 +1051,10 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)\n \tfree_irq(pdev-\u003eirq, devinfo);\n \tpci_disable_msi(pdev);\n \n-\tmsleep(50);\n+\tusleep_range(1000, 2000);\n \tcount = 0;\n-\twhile ((devinfo-\u003ein_irq) \u0026\u0026 (count \u003c 20)) {\n-\t\tmsleep(50);\n+\twhile ((devinfo-\u003ein_irq) \u0026\u0026 (count \u003c 1000)) {\n+\t\tusleep_range(1000, 2000);\n \t\tcount++;\n \t}\n \tif (devinfo-\u003ein_irq)\ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c\nindex b725c64e5b5c6..4e414403d7471 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c\n@@ -1645,37 +1645,43 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)\n \n \t\trd_new.seq_num = rxseq;\n \t\trd_new.len = dlen;\n+\n+\t\t/*\n+\t\t * Claim the host once for the entire header-parsing phase.\n+\t\t *\n+\t\t * brcmf_sdio_hdparse() operates on data already in host\n+\t\t * memory, but may call brcmf_sdio_rxfail() on error, which\n+\t\t * writes SDIO Func1 registers and therefore requires the\n+\t\t * host to be claimed.\n+\t\t *\n+\t\t * skb_pull() and the num counter are pure host-memory\n+\t\t * operations; keep them outside the lock to minimise the\n+\t\t * hold time.  Both hdparse calls (superframe header and\n+\t\t * each subframe header) are grouped under a single claim/\n+\t\t * release, replacing the original N+1 separate pairs.\n+\t\t */\n \t\tsdio_claim_host(bus-\u003esdiodev-\u003efunc1);\n \t\terrcode = brcmf_sdio_hdparse(bus, pfirst-\u003edata, \u0026rd_new,\n \t\t\t\t\t     BRCMF_SDIO_FT_SUPER);\n-\t\tsdio_release_host(bus-\u003esdiodev-\u003efunc1);\n-\t\tbus-\u003ecur_read.len = rd_new.len_nxtfrm \u003c\u003c 4;\n-\n-\t\t/* Remove superframe header, remember offset */\n-\t\tskb_pull(pfirst, rd_new.dat_offset);\n-\t\tnum = 0;\n-\n-\t\t/* Validate all the subframe headers */\n-\t\tskb_queue_walk(\u0026bus-\u003eglom, pnext) {\n-\t\t\t/* leave when invalid subframe is found */\n-\t\t\tif (errcode)\n-\t\t\t\tbreak;\n \n-\t\t\trd_new.len = pnext-\u003elen;\n-\t\t\trd_new.seq_num = rxseq++;\n-\t\t\tsdio_claim_host(bus-\u003esdiodev-\u003efunc1);\n-\t\t\terrcode = brcmf_sdio_hdparse(bus, pnext-\u003edata, \u0026rd_new,\n-\t\t\t\t\t\t     BRCMF_SDIO_FT_SUB);\n-\t\t\tsdio_release_host(bus-\u003esdiodev-\u003efunc1);\n-\t\t\tbrcmf_dbg_hex_dump(BRCMF_GLOM_ON(),\n-\t\t\t\t\t   pnext-\u003edata, 32, \"subframe:\\n\");\n-\n-\t\t\tnum++;\n+\t\t/* Validate all the subframe headers while host is claimed */\n+\t\tif (!errcode) {\n+\t\t\tskb_queue_walk(\u0026bus-\u003eglom, pnext) {\n+\t\t\t\trd_new.len = pnext-\u003elen;\n+\t\t\t\trd_new.seq_num = rxseq++;\n+\t\t\t\terrcode = brcmf_sdio_hdparse(bus, pnext-\u003edata,\n+\t\t\t\t\t\t\t     \u0026rd_new,\n+\t\t\t\t\t\t\t     BRCMF_SDIO_FT_SUB);\n+\t\t\t\tbrcmf_dbg_hex_dump(BRCMF_GLOM_ON(),\n+\t\t\t\t\t\t   pnext-\u003edata, 32,\n+\t\t\t\t\t\t   \"subframe:\\n\");\n+\t\t\t\tif (errcode)\n+\t\t\t\t\tbreak;\n+\t\t\t}\n \t\t}\n \n \t\tif (errcode) {\n-\t\t\t/* Terminate frame on error */\n-\t\t\tsdio_claim_host(bus-\u003esdiodev-\u003efunc1);\n+\t\t\t/* Terminate frame on error, still holding the host */\n \t\t\tbrcmf_sdio_rxfail(bus, true, false);\n \t\t\tbus-\u003esdcnt.rxglomfail++;\n \t\t\tbrcmf_sdio_free_glom(bus);\n@@ -1683,6 +1689,14 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)\n \t\t\tbus-\u003ecur_read.len = 0;\n \t\t\treturn 0;\n \t\t}\n+\t\tsdio_release_host(bus-\u003esdiodev-\u003efunc1);\n+\n+\t\t/* Host released; now do the pure-memory bookkeeping */\n+\t\tbus-\u003ecur_read.len = rd_new.len_nxtfrm \u003c\u003c 4;\n+\n+\t\t/* Remove superframe header, remember offset */\n+\t\tskb_pull(pfirst, rd_new.dat_offset);\n+\t\tnum = 0;\n \n \t\t/* Basic SD framing looks ok - process each packet (header) */\n \ndiff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c\nindex fc7a5dd2e5d86..3fd8bdbd35e58 100644\n--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c\n+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c\n@@ -516,12 +516,11 @@ int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,\n \t\t\treturn -ENOSPC;\n \n \t\t/*\n-\t\t * We aren't really out of space if the new frame is of\n-\t\t * a different priority, but we want the same behaviour\n-\t\t * so return -ENOSPC anyway.\n-\t\t *\n-\t\t * XXX: The old AMPDU code did this, but is it really\n-\t\t * necessary?\n+\t\t * IEEE 802.11n standard requires that all MPDUs within an\n+\t\t * A-MPDU belong to the same TID (Traffic Identifier).\n+\t\t * Since priority maps to TID, a different priority means\n+\t\t * we must close the current aggregate and start a new one,\n+\t\t * so we return -ENOSPC here.\n \t\t */\n \t\tfirst = skb_peek(\u0026session-\u003eskb_list);\n \t\tif (p-\u003epriority != first-\u003epriority)\n"
}

2/1 2026/08/01 05:50 agent patch-evaluator
2m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the brcmfmac and brcmsmac Broadcom wireless drivers. These are vendor-specific drivers that require physical Broadcom Wi-Fi hardware (PCIe, SDIO, or BCMA) to initialize and function. While brcmfmac supports USB, reaching the modified data paths (RX/TX) and cfg80211 callbacks requires passing a complex firmware loading and initialization handshake, which is impossible to achieve via random USB gadget fuzzing without a dedicated firmware emulator. Therefore, the modified code paths are unreachable in standard virtualized environments like QEMU.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 2a0dc1d8c1816e399e32e5a88c877b547825eff3
Author: syz-cluster <triage@syzkaller.com>
Date:   Sat Aug 1 05:50:07 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 0b55d445895f2..7d7e5ececd229 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3989,12 +3989,10 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
 
 static __always_inline void brcmf_delay(u32 ms)
 {
-	if (ms < 1000 / HZ) {
-		cond_resched();
-		mdelay(ms);
-	} else {
+	if (ms <= 20)
+		usleep_range(ms * 1000, ms * 1000 + 1000);
+	else
 		msleep(ms);
-	}
 }
 
 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
@@ -4364,6 +4362,104 @@ brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa,
 	return ret;
 }
 
+/**
+ * brcmf_pmksa_v2_op - update firmware PMKSA cache using the V2 list interface.
+ *
+ * V2 firmware (revision 12) uses a versioned flat list structure
+ * (brcmf_pmk_list_v2_le) rather than the per-entry operation model of V3.
+ * Each entry carries FILS-specific fields (raw PMK material, SSID, and
+ * fils_cache_id) in addition to the basic BSSID + PMKID pair, enabling
+ * FILS fast-roaming on devices that do not support V3.
+ *
+ * @cfg:   driver config structure holding the shadow V2 PMKSA list
+ * @ifp:   interface pointer
+ * @pmksa: the PMKSA to add/remove, or NULL for a flush
+ * @alive: true = add (set time_left to no-expiry), false = remove/flush
+ */
+static s32
+brcmf_pmksa_v2_op(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
+		  struct cfg80211_pmksa *pmksa, bool alive)
+{
+	struct brcmf_pub *drvr = cfg->pub;
+	struct brcmf_pmk_list_v2_le *list = &cfg->pmk_list_v2;
+	struct brcmf_pmksa_v2 *pmk = list->pmk;
+	u32 npmk = le16_to_cpu(list->length);
+	u32 i;
+
+	/* npmk here stores the count of valid entries, repurposing the
+	 * length field of the shadow list as a counter.  We convert to
+	 * the wire format (byte length) when sending to firmware.
+	 */
+	if (!pmksa) {
+		/* Flush: zero the shadow list and push an empty V2 list. */
+		memset(list, 0, sizeof(*list));
+		goto send;
+	}
+
+	if (alive) {
+		/* Set: search for existing BSSID match first. */
+		for (i = 0; i < npmk; i++)
+			if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
+				break;
+
+		if (i >= BRCMF_MAXPMKID) {
+			bphy_err(drvr, "V2 PMKSA cache full (%d entries)\n",
+				 npmk);
+			return -EINVAL;
+		}
+
+		memset(&pmk[i], 0, sizeof(pmk[i]));
+		pmk[i].length = cpu_to_le16(sizeof(struct brcmf_pmksa_v2));
+		if (pmksa->bssid)
+			memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
+		if (pmksa->pmkid)
+			memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
+		if (pmksa->pmk && pmksa->pmk_len &&
+		    pmksa->pmk_len <= WLAN_PMK_LEN_SUITE_B_192) {
+			memcpy(pmk[i].pmk, pmksa->pmk, pmksa->pmk_len);
+			pmk[i].pmk_len = cpu_to_le16(pmksa->pmk_len);
+		}
+		if (pmksa->ssid && pmksa->ssid_len) {
+			memcpy(pmk[i].ssid.SSID, pmksa->ssid, pmksa->ssid_len);
+			pmk[i].ssid.SSID_len = pmksa->ssid_len;
+		}
+		if (pmksa->fils_cache_id)
+			pmk[i].fils_cache_id = *pmksa->fils_cache_id;
+
+		if (i == npmk)
+			npmk++;
+	} else {
+		/* Delete: find by BSSID and compact the list. */
+		for (i = 0; i < npmk; i++)
+			if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
+				break;
+
+		if (i >= npmk) {
+			bphy_err(drvr, "V2 PMKSA entry not found\n");
+			return -EINVAL;
+		}
+
+		for (; i < npmk - 1; i++)
+			memcpy(&pmk[i], &pmk[i + 1], sizeof(pmk[i]));
+		memset(&pmk[npmk - 1], 0, sizeof(pmk[npmk - 1]));
+		npmk--;
+	}
+
+	/* Update shadow entry count (stored in length field). */
+	list->length = cpu_to_le16(npmk);
+
+send:
+	/* Build the wire-format header and send the full list to firmware.
+	 * version and length on the wire reflect the actual byte footprint.
+	 */
+	list->version = cpu_to_le16(BRCMF_PMKSA_VER_2);
+	list->length  = cpu_to_le16(offsetof(struct brcmf_pmk_list_v2_le, pmk) +
+				   npmk * sizeof(struct brcmf_pmksa_v2));
+
+	return brcmf_fil_iovar_data_set(ifp, "pmkid_info", list, sizeof(*list));
+}
+
+
 static __used s32
 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
 {
@@ -4402,8 +4498,8 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
 
 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
 		return brcmf_pmksa_v3_op(ifp, pmksa, true);
-
-	/* TODO: implement PMKID_V2 */
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V2))
+		return brcmf_pmksa_v2_op(cfg, ifp, pmksa, true);
 
 	npmk = le32_to_cpu(cfg->pmk_list.npmk);
 	for (i = 0; i < npmk; i++)
@@ -4446,8 +4542,8 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
 
 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
 		return brcmf_pmksa_v3_op(ifp, pmksa, false);
-
-	/* TODO: implement PMKID_V2 */
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V2))
+		return brcmf_pmksa_v2_op(cfg, ifp, pmksa, false);
 
 	npmk = le32_to_cpu(cfg->pmk_list.npmk);
 	for (i = 0; i < npmk; i++)
@@ -4487,8 +4583,8 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
 
 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
 		return brcmf_pmksa_v3_op(ifp, NULL, false);
-
-	/* TODO: implement PMKID_V2 */
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V2))
+		return brcmf_pmksa_v2_op(cfg, ifp, NULL, false);
 
 	memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
 	err = brcmf_update_pmklist(cfg, ifp);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 6ceb301429054..57167fde5ba15 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -344,7 +344,8 @@ struct brcmf_cfg80211_wowl {
  * @bss_list: bss_list holding scanned ap information.
  * @bss_info: bss information for cfg80211 layer.
  * @conn_info: association info.
- * @pmk_list: wpa2 pmk list.
+ * @pmk_list: wpa2 pmk list (V1 firmware).
+ * @pmk_list_v2: wpa2 pmk list for V2 firmware (FILS-capable, firmware rev 12).
  * @scan_status: scan activity on the dongle.
  * @pub: common driver information.
  * @channel: current channel.
@@ -376,6 +377,7 @@ struct brcmf_cfg80211_info {
 	struct wl_cfg80211_bss_info *bss_info;
 	struct brcmf_cfg80211_connect_info conn_info;
 	struct brcmf_pmk_list_le pmk_list;
+	struct brcmf_pmk_list_v2_le pmk_list_v2;
 	unsigned long scan_status;
 	struct brcmf_pub *pub;
 	u32 channel;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index ec170647800da..673f0000389cc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -431,45 +431,51 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
 	netif_rx(skb);
 }
 
+struct brcmf_radiotap_info {
+	struct ieee80211_radiotap_header hdr;
+	s8 dbm_antsignal;
+} __packed;
+
 void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
 {
 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {
-		/* Do nothing */
+		/* Firmware already provided a full radiotap header; do nothing */
 	} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) {
 		struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data;
-		struct ieee80211_radiotap_header *radiotap;
+		struct brcmf_radiotap_info *rtap;
 		unsigned int offset;
 		u16 RxStatus1;
+		s8 rssi;
 
 		RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1);
+		rssi = wlc_rxhdr->rssi;
 
 		offset = sizeof(struct wlc_d11rxhdr);
-		/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU
-		 * subframes
-		 */
+		/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
 		if (RxStatus1 & RXS_PBPRES)
 			offset += 2;
 		offset += D11_PHY_HDR_LEN;
 
 		skb_pull(skb, offset);
 
-		/* TODO: use RX header to fill some radiotap data */
-		radiotap = skb_push(skb, sizeof(*radiotap));
-		memset(radiotap, 0, sizeof(*radiotap));
-		radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
+		/* Insert our radiotap header with RSSI data */
+		rtap = skb_push(skb, sizeof(*rtap));
+		memset(rtap, 0, sizeof(*rtap));
+		rtap->hdr.it_len = cpu_to_le16(sizeof(*rtap));
+		rtap->hdr.it_present = cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
+		rtap->dbm_antsignal = rssi;
 
-		/* TODO: 4 bytes with receive status? */
-		skb->len -= 4;
+		/* Strip the 4-byte receive status / FCS tail */
+		skb_trim(skb, skb->len - 4);
 	} else {
 		struct ieee80211_radiotap_header *radiotap;
 
-		/* TODO: use RX status to fill some radiotap data */
 		radiotap = skb_push(skb, sizeof(*radiotap));
 		memset(radiotap, 0, sizeof(*radiotap));
 		radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
 
-		/* TODO: 4 bytes with receive status? */
-		skb->len -= 4;
+		/* Strip the 4-byte receive status / FCS tail */
+		skb_trim(skb, skb->len - 4);
 	}
 
 	skb->dev = ifp->ndev;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
index 35cbcea0abc9a..b9c518939f504 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
@@ -182,10 +182,8 @@ static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid,
 	struct brcmf_bus *bus_if;
 	struct brcmf_pub *drvr;
 	struct brcmf_if *ifp;
-	bool currently_blocked;
-	int i;
-	u8 ifidx;
 	unsigned long flags;
+	u8 ifidx;
 
 	spin_lock_irqsave(&flow->block_lock, flags);
 
@@ -194,23 +192,54 @@ static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid,
 		spin_unlock_irqrestore(&flow->block_lock, flags);
 		return;
 	}
-	ifidx = brcmf_flowring_ifidx_get(flow, flowid);
 
-	currently_blocked = false;
-	for (i = 0; i < flow->nrofrings; i++) {
-		if ((flow->rings[i]) && (i != flowid)) {
-			ring = flow->rings[i];
-			if ((ring->status == RING_OPEN) &&
-			    (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
-				if (ring->blocked) {
-					currently_blocked = true;
-					break;
-				}
-			}
+	ifidx = brcmf_flowring_ifidx_get(flow, flowid);
+	ring->blocked = blocked;
+
+	/*
+	 * Maintain the per-interface blocked-ring counter.
+	 *
+	 * We use ring->counted_in_blocked rather than checking
+	 * ring->status here.  A ring that became blocked while
+	 * RING_OPEN has already been counted (counted_in_blocked=true).
+	 * By the time we unblock it during teardown its status may have
+	 * advanced to RING_CLOSING, so testing RING_OPEN would wrongly
+	 * skip the atomic_dec and permanently leak the counter, leaving
+	 * the netif queue stopped forever.
+	 *
+	 * Rule:
+	 *   block transition  (unblocked→blocked): count only if RING_OPEN,
+	 *                                          set counted_in_blocked.
+	 *   unblock transition (blocked→unblocked): decrement only if we
+	 *                                          previously counted it,
+	 *                                          clear counted_in_blocked.
+	 */
+	if (blocked) {
+		if (ring->status == RING_OPEN) {
+			atomic_inc(&flow->if_blocked_cnt[ifidx]);
+			ring->counted_in_blocked = true;
 		}
+	} else {
+		if (ring->counted_in_blocked) {
+			atomic_dec(&flow->if_blocked_cnt[ifidx]);
+			ring->counted_in_blocked = false;
+		}
+	}
+
+	/*
+	 * Only propagate a netif queue-stop/wake when the interface
+	 * transitions between fully-clear and at-least-one-blocked.
+	 * Reading the atomic is safe here: we hold block_lock, so no
+	 * concurrent brcmf_flowring_block() call can race the update
+	 * we just made above.
+	 */
+	if (blocked && atomic_read(&flow->if_blocked_cnt[ifidx]) != 1) {
+		/* Another ring was already blocked; no new queue-stop needed. */
+		spin_unlock_irqrestore(&flow->block_lock, flags);
+		return;
 	}
-	flow->rings[flowid]->blocked = blocked;
-	if (currently_blocked) {
+	if (!blocked && atomic_read(&flow->if_blocked_cnt[ifidx]) != 0) {
+		/* More rings still blocked; do not wake the queue yet. */
 		spin_unlock_irqrestore(&flow->block_lock, flags);
 		return;
 	}
@@ -367,6 +396,8 @@ struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings)
 		spin_lock_init(&flow->block_lock);
 		for (i = 0; i < ARRAY_SIZE(flow->addr_mode); i++)
 			flow->addr_mode[i] = ADDR_INDIRECT;
+		for (i = 0; i < ARRAY_SIZE(flow->if_blocked_cnt); i++)
+			atomic_set(&flow->if_blocked_cnt[i], 0);
 		for (i = 0; i < ARRAY_SIZE(flow->hash); i++)
 			flow->hash[i].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;
 	}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h
index f3d511f9a3c9a..afdea8b3f8aa7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h
@@ -5,6 +5,8 @@
 #ifndef BRCMFMAC_FLOWRING_H
 #define BRCMFMAC_FLOWRING_H
 
+#include <linux/atomic.h>
+
 
 #define BRCMF_FLOWRING_HASHSIZE		512		/* has to be 2^x */
 #define BRCMF_FLOWRING_INVALID_ID	0xFFFFFFFF
@@ -26,6 +28,16 @@ enum ring_status {
 struct brcmf_flowring_ring {
 	u16 hash_id;
 	bool blocked;
+	/*
+	 * True when this ring has been counted in the per-interface
+	 * if_blocked_cnt[].  Set to true whenever the ring transitions
+	 * unblocked→blocked while RING_OPEN; cleared on the matching
+	 * blocked→unblocked transition.  Needed so that a ring that
+	 * becomes blocked while RING_OPEN and is later moved to
+	 * RING_CLOSING still correctly decrements the counter at
+	 * teardown, even though its status is no longer RING_OPEN.
+	 */
+	bool counted_in_blocked;
 	enum ring_status status;
 	struct sk_buff_head skblist;
 };
@@ -40,6 +52,12 @@ struct brcmf_flowring {
 	struct brcmf_flowring_hash hash[BRCMF_FLOWRING_HASHSIZE];
 	spinlock_t block_lock;
 	enum proto_addr_mode addr_mode[BRCMF_MAX_IFS];
+	/* Per-interface count of currently blocked open rings.
+	 * Maintained atomically so brcmf_flowring_block() can check
+	 * whether any sibling ring is already blocked in O(1) without
+	 * holding block_lock across an O(nrofrings) walk.
+	 */
+	atomic_t if_blocked_cnt[BRCMF_MAX_IFS];
 	u16 nrofrings;
 	bool tdls_active;
 	struct brcmf_flowring_tdls_entry *tdls_entry;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index a43f1a38b0e30..3c1ca355e8eec 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -1037,7 +1037,9 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
 		} else {
 			brcmf_dbg(TRACE, "use existing\n");
 			WARN_ON(entry->mac_handle != mac_handle);
-			/* TODO: what should we do here: continue, reinit, .. */
+			/* Firmware re-sent ADD for the same MAC handle.
+			 * No action required; it is a safe no-op.
+			 */
 		}
 	}
 	return 0;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index ba1ce1552e0f4..8db6167072da3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -48,7 +48,19 @@
 #define MSGBUF_TYPE_LPBK_DMAXFER		0x13
 #define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT		0x14
 
-#define NR_TX_PKTIDS				2048
+/*
+ * NR_TX_PKTIDS: number of simultaneously in-flight TX packet IDs.
+ * Each outstanding TX frame consumes one ID until the dongle returns
+ * a TX-status completion.  The original 2048-entry pool exhausted under
+ * ≥4 concurrent iperf3 streams on Wi-Fi 5/6 (802.11ac/ax) devices,
+ * causing "No PKTID available" drops and TCP retransmits.  4096 gives
+ * headroom for high-aggregation scenarios while still fitting in a
+ * modest amount of host memory (~48 KB for the pktid table entries).
+ *
+ * NR_RX_PKTIDS: RX post buffers pre-allocated to the dongle.  1024 is
+ * sufficient for current hardware RX ring depths; leave unchanged.
+ */
+#define NR_TX_PKTIDS				4096
 #define NR_RX_PKTIDS				1024
 
 #define BRCMF_IOCTL_REQ_PKTID			0xFFFE
@@ -64,8 +76,29 @@
 #define BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK	0x07
 #define BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT	5
 
-#define BRCMF_MSGBUF_TX_FLUSH_CNT1		32
-#define BRCMF_MSGBUF_TX_FLUSH_CNT2		96
+/*
+ * TX flush / doorbell-ring thresholds.
+ *
+ * CNT1 is the minimum number of frames to accumulate in the commonring
+ * before the first intermediate write_complete() (doorbell ring) is
+ * issued mid-batch.  CNT2 is the hard flush interval: after this many
+ * frames have been written since the last flush, we unconditionally
+ * ring the bell and reset the counter.
+ *
+ * Raising both from the original 32/96 to 64/128 doubles the average
+ * number of TX descriptors committed per MMIO write, halving the PCIe
+ * doorbell rate on sustained throughput workloads.  The tradeoff is a
+ * marginally higher worst-case latency for the last frames in a burst,
+ * which in practice is hidden by the time the dongle DMA engine drains
+ * the previous batch.
+ *
+ * TRICKLE_TXWORKER_THRS governs how often brcmf_msgbuf_tx_queue_data()
+ * forces a workqueue schedule when the queue depth is not a multiple of
+ * this value.  Keeping it at half of CNT1 (32) preserves responsiveness
+ * for low-rate flows (e.g. VoIP, ICMP) that never accumulate 64 frames.
+ */
+#define BRCMF_MSGBUF_TX_FLUSH_CNT1		64
+#define BRCMF_MSGBUF_TX_FLUSH_CNT2		128
 
 #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS	96
 #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS	32
@@ -787,10 +820,30 @@ static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid,
 {
 	struct brcmf_commonring *commonring;
 
-	set_bit(flowid, msgbuf->flow_map);
+	/*
+	 * If the bit was already set, a txflow_work item is already
+	 * queued or running for this ring.  In that case the existing
+	 * worker will drain our freshly enqueued frame when it runs,
+	 * so we only need to schedule another work item when the
+	 * force flag is set or the ring is below the delay threshold.
+	 *
+	 * If the bit was NOT set (test_and_set_bit returns false), no
+	 * worker is pending for this ring at all.  We MUST schedule
+	 * one unconditionally, otherwise the frame we just enqueued
+	 * will sit in the flowring unsent until some unrelated event
+	 * triggers the workqueue — causing silent TX stalls under
+	 * high load when outstanding_tx >= DELAY_TXWORKER_THRS.
+	 */
+	if (!test_and_set_bit(flowid, msgbuf->flow_map)) {
+		/* Bit was clear: no worker pending, always schedule. */
+		queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
+		return 0;
+	}
+
+	/* Bit was already set: worker pending, apply coalescing heuristic. */
 	commonring = msgbuf->flowrings[flowid];
-	if ((force) || (atomic_read(&commonring->outstanding_tx) <
-			BRCMF_MSGBUF_DELAY_TXWORKER_THRS))
+	if (force || (atomic_read(&commonring->outstanding_tx) <
+		      BRCMF_MSGBUF_DELAY_TXWORKER_THRS))
 		queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
 
 	return 0;
@@ -1621,11 +1674,11 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
 	do {
 		brcmf_msgbuf_rxbuf_data_fill(msgbuf);
 		if (msgbuf->max_rxbufpost != msgbuf->rxbufpost)
-			msleep(10);
+			usleep_range(1000, 2000);
 		else
 			break;
 		count++;
-	} while (count < 10);
+	} while (count < 100);
 	brcmf_msgbuf_rxbuf_event_post(msgbuf);
 	brcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 13662aa4b4ea6..9338a5faa260a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -268,6 +268,27 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
 
 #define BRCMF_PCIE_MBDATA_TIMEOUT		msecs_to_jiffies(2000)
 
+/*
+ * H2D mailbox poll timing parameters.
+ *
+ * The dongle typically clears the H2D mailbox register within a few
+ * hundred microseconds after the doorbell interrupt fires.  The
+ * original code used msleep(10) * 100 iterations, meaning the
+ * minimum observable latency was 10ms even when the dongle was fast.
+ *
+ * We instead start with a short sleep and double it each iteration
+ * (exponential backoff) up to BRCMF_PCIE_MB_POLL_MAX_US, staying
+ * within the same 1-second absolute timeout.
+ *
+ * MIN_US / INITIAL_MAX_US : usleep_range bounds for the first iteration.
+ * MAX_US     : cap on the per-iteration sleep (µs).
+ * TIMEOUT_US : total budget before giving up (1 second).
+ */
+#define BRCMF_PCIE_MB_POLL_MIN_US		40
+#define BRCMF_PCIE_MB_POLL_INITIAL_MAX_US	50
+#define BRCMF_PCIE_MB_POLL_MAX_US		5000
+#define BRCMF_PCIE_MB_POLL_TIMEOUT_US		1000000
+
 #define BRCMF_PCIE_CFGREG_STATUS_CMD		0x4
 #define BRCMF_PCIE_CFGREG_PM_CSR		0x4C
 #define BRCMF_PCIE_CFGREG_MSI_CAP		0x58
@@ -766,7 +787,8 @@ brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)
 	struct brcmf_core *core;
 	u32 addr;
 	u32 cur_htod_mb_data;
-	u32 i;
+	u32 elapsed_us = 0;
+	u32 sleep_us = BRCMF_PCIE_MB_POLL_INITIAL_MAX_US;
 
 	shared = &devinfo->shared;
 	addr = shared->htod_mb_data_addr;
@@ -776,12 +798,40 @@ brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)
 		brcmf_dbg(PCIE, "MB transaction is already pending 0x%04x\n",
 			  cur_htod_mb_data);
 
-	i = 0;
+	/*
+	 * Wait for the dongle to consume the previous H2D mailbox message.
+	 *
+	 * There is no interrupt that signals when the dongle clears this
+	 * register, so polling is unavoidable.  The original code used
+	 * msleep(10) per iteration, incurring at least 10ms of latency
+	 * even when the dongle responded in microseconds.
+	 *
+	 * We use usleep_range() with exponential backoff instead:
+	 *   - First iteration sleeps ~50µs (fast path for responsive dongle).
+	 *   - Each subsequent iteration doubles the sleep, capped at 5ms,
+	 *     so long waits still yield the CPU without busy-spinning.
+	 *   - Total timeout matches the original 1-second limit.
+	 *   - We bail early if the device has gone down so that a dead
+	 *     dongle does not hold the caller for a full second.
+	 */
 	while (cur_htod_mb_data != 0) {
-		msleep(10);
-		i++;
-		if (i > 100)
+		if (devinfo->state == BRCMFMAC_PCIE_STATE_DOWN) {
+			brcmf_dbg(PCIE, "Device down, aborting MB send\n");
 			return -EIO;
+		}
+
+		if (elapsed_us >= BRCMF_PCIE_MB_POLL_TIMEOUT_US) {
+			brcmf_err("Timeout waiting for H2D MB slot after %u us\n",
+				  elapsed_us);
+			return -EIO;
+		}
+
+		usleep_range(BRCMF_PCIE_MB_POLL_MIN_US, sleep_us);
+		elapsed_us += sleep_us;
+
+		/* Exponential backoff, capped at BRCMF_PCIE_MB_POLL_MAX_US */
+		sleep_us = min(sleep_us * 2, (u32)BRCMF_PCIE_MB_POLL_MAX_US);
+
 		cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
 	}
 
@@ -1001,10 +1051,10 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
 	free_irq(pdev->irq, devinfo);
 	pci_disable_msi(pdev);
 
-	msleep(50);
+	usleep_range(1000, 2000);
 	count = 0;
-	while ((devinfo->in_irq) && (count < 20)) {
-		msleep(50);
+	while ((devinfo->in_irq) && (count < 1000)) {
+		usleep_range(1000, 2000);
 		count++;
 	}
 	if (devinfo->in_irq)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b725c64e5b5c6..4e414403d7471 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1645,37 +1645,43 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 
 		rd_new.seq_num = rxseq;
 		rd_new.len = dlen;
+
+		/*
+		 * Claim the host once for the entire header-parsing phase.
+		 *
+		 * brcmf_sdio_hdparse() operates on data already in host
+		 * memory, but may call brcmf_sdio_rxfail() on error, which
+		 * writes SDIO Func1 registers and therefore requires the
+		 * host to be claimed.
+		 *
+		 * skb_pull() and the num counter are pure host-memory
+		 * operations; keep them outside the lock to minimise the
+		 * hold time.  Both hdparse calls (superframe header and
+		 * each subframe header) are grouped under a single claim/
+		 * release, replacing the original N+1 separate pairs.
+		 */
 		sdio_claim_host(bus->sdiodev->func1);
 		errcode = brcmf_sdio_hdparse(bus, pfirst->data, &rd_new,
 					     BRCMF_SDIO_FT_SUPER);
-		sdio_release_host(bus->sdiodev->func1);
-		bus->cur_read.len = rd_new.len_nxtfrm << 4;
-
-		/* Remove superframe header, remember offset */
-		skb_pull(pfirst, rd_new.dat_offset);
-		num = 0;
-
-		/* Validate all the subframe headers */
-		skb_queue_walk(&bus->glom, pnext) {
-			/* leave when invalid subframe is found */
-			if (errcode)
-				break;
 
-			rd_new.len = pnext->len;
-			rd_new.seq_num = rxseq++;
-			sdio_claim_host(bus->sdiodev->func1);
-			errcode = brcmf_sdio_hdparse(bus, pnext->data, &rd_new,
-						     BRCMF_SDIO_FT_SUB);
-			sdio_release_host(bus->sdiodev->func1);
-			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
-					   pnext->data, 32, "subframe:\n");
-
-			num++;
+		/* Validate all the subframe headers while host is claimed */
+		if (!errcode) {
+			skb_queue_walk(&bus->glom, pnext) {
+				rd_new.len = pnext->len;
+				rd_new.seq_num = rxseq++;
+				errcode = brcmf_sdio_hdparse(bus, pnext->data,
+							     &rd_new,
+							     BRCMF_SDIO_FT_SUB);
+				brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+						   pnext->data, 32,
+						   "subframe:\n");
+				if (errcode)
+					break;
+			}
 		}
 
 		if (errcode) {
-			/* Terminate frame on error */
-			sdio_claim_host(bus->sdiodev->func1);
+			/* Terminate frame on error, still holding the host */
 			brcmf_sdio_rxfail(bus, true, false);
 			bus->sdcnt.rxglomfail++;
 			brcmf_sdio_free_glom(bus);
@@ -1683,6 +1689,14 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 			bus->cur_read.len = 0;
 			return 0;
 		}
+		sdio_release_host(bus->sdiodev->func1);
+
+		/* Host released; now do the pure-memory bookkeeping */
+		bus->cur_read.len = rd_new.len_nxtfrm << 4;
+
+		/* Remove superframe header, remember offset */
+		skb_pull(pfirst, rd_new.dat_offset);
+		num = 0;
 
 		/* Basic SD framing looks ok - process each packet (header) */
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c
index fc7a5dd2e5d86..3fd8bdbd35e58 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c
@@ -516,12 +516,11 @@ int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
 			return -ENOSPC;
 
 		/*
-		 * We aren't really out of space if the new frame is of
-		 * a different priority, but we want the same behaviour
-		 * so return -ENOSPC anyway.
-		 *
-		 * XXX: The old AMPDU code did this, but is it really
-		 * necessary?
+		 * IEEE 802.11n standard requires that all MPDUs within an
+		 * A-MPDU belong to the same TID (Traffic Identifier).
+		 * Since priority maps to TID, a different priority means
+		 * we must close the current aggregate and start a new one,
+		 * so we return -ENOSPC here.
 		 */
 		first = skb_peek(&session->skb_list);
 		if (p->priority != first->priority)

3/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13316
							output: 49
							thoughts: 1043
						

Thoughts:
**Analyzing the brcm80211 Patch for brcmfmac**

Okay, so I've got this patch for the `brcm80211` driver, specifically for `brcmfmac` and `brcmsmac`. Let's break down the implications.

First, looking at the `brcmfmac/cfg80211.c` changes, the `brcmf_delay` modifications are interesting. Swapping `mdelay` for `usleep_range`/`msleep` suggests an attempt to be more precise or flexible with timing, likely aimed at avoiding potential busy-waiting issues or improving power management. The addition of `brcmf_pmksa_v2_op` and its integration with PMKID V2 support is definitely significant, and points to the inclusion of FILS-capable firmware interactions. This suggests an effort to accommodate newer security protocols. And the change to `brcmf_cfg80211_set_pmksa`, `brcmf_cfg80211_del_pmksa`, `brcmf_cfg80211_flush_pmksa` means the new feature is fully integrated.

The inclusion of `pmk_list_v2` in the `brcmf_cfg80211_info` struct in `cfg80211.h` clearly complements the PMKID V2 implementation.

In `brcmfmac/core.c`, the addition of a radiotap header with RSSI data when `BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR` is enabled looks like a helpful addition for monitoring and debugging, and this might be something interesting to look at in more detail.

`brcmfmac/flowring.c` and `flowring.h` show optimization in the blocking logic with a per-interface blocked-ring counter, which should improve performance.

The changes in `brcmfmac/fwsignal.c` and `brcmsmac/ampdu.c` seem purely cosmetic, just adding or replacing comments. Not relevant to the analysis.

`brcmfmac/msgbuf.c` sees some substantial modifications, with increases in `NR_TX_PKTIDS`, `BRCMF_MSGBUF_TX_FLUSH_CNT1`, and `BRCMF_MSGBUF_TX_FLUSH_CNT2`. This hints at potentially handling higher throughput or a larger number of outstanding transactions. The logic change in `brcmf_msgbuf_schedule_txdata` is also interesting; always scheduling a worker seems potentially more robust. Similarly, the timing changes in `brcmf_proto_msgbuf_attach` with the increased loop count and `usleep_range` suggests some refinement in communication with the firmware.

The polling adjustments in `brcmfmac/pcie.c` with exponential backoff and the timing improvements in `brcmf_pcie_release_irq` are further evidence of an effort to optimize communication, specifically on PCIe.

In `brcmfmac/sdio.c`, minimizing `sdio_claim_host` hold time in `brcmf_sdio_rxglom` also points to trying to speed things up or improve concurrency.

Now, the important question: is this worth fuzzing? `brcmfmac` is a wireless driver, which always raises security concerns. It communicates with firmware over SDIO, PCIe, or USB. Given that there are several communications paths, there are multiple avenues of possible attack.

I'm thinking about fuzzing strategies. I know I can emulate USB in QEMU. But can I use that with `brcmfmac`? `brcmfmac` is a FullMAC driver and won't interact with `mac80211_hwsim`. I need actual Broadcom hardware for this driver.

What about syzkaller? It has USB fuzzing capabilities, but I need to make sure the USB part of `brcmfmac` is reachable or supported. I should search for `brcmf_usb_probe` in `drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c` to see. The patch mentions no changes to the USB subsystem, but I need to see what's possible to fuzz.



4/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "brcmf_usb_probe",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1165=static const struct brcmf_bus_ops brcmf_usb_bus_ops = {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1175-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1176:static void brcmf_usb_probe_phase2(struct device *dev, int ret,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1177-\t\t\t\t   struct brcmf_fw_request *fwreq)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1224=brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1243-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1244:static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1245-\t\t\t      enum brcmf_fwvendor fwvid)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1307-\t/* request firmware here */\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1308:\tret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1309-\tif (ret) {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1341=static int\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1342:brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1343-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1442-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1443:\tret = brcmf_usb_probe_cb(devinfo, id-\u003edriver_info);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1444-\tif (ret)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1511=static int brcmf_usb_reset_resume(struct usb_interface *intf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1523-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1524:\tret = brcmf_fw_get_firmwares(\u0026usb-\u003edev, fwreq, brcmf_usb_probe_phase2);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1525-\tif (ret \u003c 0)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1565=static struct usb_driver brcmf_usbdrvr = {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1566-\t.name = KBUILD_MODNAME,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1567:\t.probe = brcmf_usb_probe,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1568-\t.disconnect = brcmf_usb_disconnect,\n"
}

5/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16503
							output: 48
							thoughts: 261
						

Thoughts:
**Fuzzing the `brcmfmac` Driver with Syzkaller: Initial Considerations**

Okay, so the `brcmfmac` driver has a USB interface, which is a great starting point since Syzkaller is capable of fuzzing USB devices. My immediate concern, however, is the firmware dependency. I recall that `brcmfmac` relies on firmware loading via `brcmf_fw_get_firmwares`. If that process fails, the probe will likely bail out early, and I'll miss a significant portion of the driver's logic.

I need to quickly check if Syzkaller offers the necessary firmware for `brcmfmac` or if there's a way to bypass this requirement. Ah, right, `brcmfmac` uses `request_firmware` or something similar, which Syzkaller sometimes handles by having the firmware already baked into the image. But that may also fail. If the firmware load fails, is fuzzing even worthwhile? Even if a lot of the code is unreachable?

Let's look at the areas of change to get a sense of where to focus. The commit logs show changes in `cfg80211.c`, `core.c`, `flowring.c`, `msgbuf.c`, `pcie.c`, and `sdio.c`. The `cfg80211.c` changes are likely related to the wireless configuration and operations, `core.c` for the receive path, and `flowring.c` and `msgbuf.c` relate to the transmit path. `pcie.c` and `sdio.c` are PCIe and SDIO specific. Wait. `msgbuf.c` and `flowring.c` are used by PCIe. Are they also used by USB? I need to verify that before I go too far down this road. I need to make sure I am on the right track!



6/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "brcmf_msgbuf",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 534 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c=409=void brcmf_flowring_detach(struct brcmf_flowring *flow)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c-418-\t\tif (flow-\u003erings[flowid])\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c:419:\t\t\tbrcmf_msgbuf_delete_flowring(drvr, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c-420-\t}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c=432=void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c-445-\t\t\t\t\tcontinue;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c:446:\t\t\t\tbrcmf_msgbuf_delete_flowring(drvr, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c-447-\t\t\t}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c=454=void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c-484-\t\t\tif (flow-\u003erings[flowid]-\u003estatus == RING_OPEN)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c:485:\t\t\t\tbrcmf_msgbuf_delete_flowring(drvr, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c-486-\t\t}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-94- *\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:95: * TRICKLE_TXWORKER_THRS governs how often brcmf_msgbuf_tx_queue_data()\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-96- * forces a workqueue schedule when the queue depth is not a multiple of\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=248=struct msgbuf_flowring_flush_resp {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-253-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:254:struct brcmf_msgbuf_work_item {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-255-\tstruct list_head queue;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-261-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:262:struct brcmf_msgbuf {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-263-\tstruct brcmf_pub *drvr;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-296-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:297:\tstruct brcmf_msgbuf_pktids *tx_pktids;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:298:\tstruct brcmf_msgbuf_pktids *rx_pktids;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-299-\tstruct brcmf_flowring *flow;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-310-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:311:struct brcmf_msgbuf_pktid {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-312-\tatomic_t  allocated;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-317-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:318:struct brcmf_msgbuf_pktids {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-319-\tu32 array_size;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-321-\tenum dma_data_direction direction;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:322:\tstruct brcmf_msgbuf_pktid *array;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-323-};\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-324-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:325:static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-326-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-327-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:328:static struct brcmf_msgbuf_pktids *\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:329:brcmf_msgbuf_init_pktids(u32 nr_array_entries,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-330-\t\t\t enum dma_data_direction direction)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-331-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:332:\tstruct brcmf_msgbuf_pktid *array;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:333:\tstruct brcmf_msgbuf_pktids *pktids;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-334-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=351=static int\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:352:brcmf_msgbuf_alloc_pktid(struct device *dev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:353:\t\t\t struct brcmf_msgbuf_pktids *pktids,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-354-\t\t\t struct sk_buff *skb, u16 data_offset,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-356-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:357:\tstruct brcmf_msgbuf_pktid *array;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-358-\tu32 count;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=399=static struct sk_buff *\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:400:brcmf_msgbuf_get_pktid(struct device *dev, struct brcmf_msgbuf_pktids *pktids,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-401-\t\t       u32 idx)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-402-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:403:\tstruct brcmf_msgbuf_pktid *pktid;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-404-\tstruct sk_buff *skb;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=427=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:428:brcmf_msgbuf_release_array(struct device *dev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:429:\t\t\t   struct brcmf_msgbuf_pktids *pktids)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-430-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:431:\tstruct brcmf_msgbuf_pktid *array;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:432:\tstruct brcmf_msgbuf_pktid *pktid;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-433-\tu32 count;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-452-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:453:static void brcmf_msgbuf_release_pktids(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-454-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-455-\tif (msgbuf-\u003erx_pktids)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:456:\t\tbrcmf_msgbuf_release_array(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-457-\t\t\t\t\t   msgbuf-\u003erx_pktids);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-458-\tif (msgbuf-\u003etx_pktids)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:459:\t\tbrcmf_msgbuf_release_array(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-460-\t\t\t\t\t   msgbuf-\u003etx_pktids);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-463-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:464:static int brcmf_msgbuf_tx_ioctl(struct brcmf_pub *drvr, int ifidx,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-465-\t\t\t\t uint cmd, void *buf, uint len)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-466-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:467:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-468-\tstruct brcmf_commonring *commonring;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-509-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:510:static int brcmf_msgbuf_ioctl_resp_wait(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-511-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-517-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:518:static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-519-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-524-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:525:static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-526-\t\t\t\t   uint cmd, void *buf, uint len, int *fwerr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-527-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:528:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-529-\tstruct sk_buff *skb = NULL;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-535-\tmsgbuf-\u003ectl_completed = false;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:536:\terr = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-537-\tif (err)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-539-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:540:\ttimeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-541-\tif (!timeout) {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-545-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:546:\tskb = brcmf_msgbuf_get_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-547-\t\t\t\t     msgbuf-\u003erx_pktids,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-562-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:563:static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-564-\t\t\t\t uint cmd, void *buf, uint len, int *fwerr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-565-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:566:\treturn brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-567-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-569-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:570:static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-571-\t\t\t\tstruct sk_buff *skb, struct brcmf_if **ifp)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-575-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:576:static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-577-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=580=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:581:brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-582-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-596-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:597:static struct brcmf_msgbuf_work_item *\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:598:brcmf_msgbuf_dequeue_work(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-599-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:600:\tstruct brcmf_msgbuf_work_item *work = NULL;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-601-\tulong flags;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-605-\t\twork = list_first_entry(\u0026msgbuf-\u003ework_queue,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:606:\t\t\t\t\tstruct brcmf_msgbuf_work_item, queue);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-607-\t\tlist_del(\u0026work-\u003equeue);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=615=static u32\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:616:brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:617:\t\t\t\t    struct brcmf_msgbuf_work_item *work)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-618-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-649-\t\tbrcmf_commonring_unlock(commonring);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:650:\t\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-651-\t\treturn BRCMF_FLOWRING_INVALID_ID;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-675-\t\tbphy_err(drvr, \"Failed to write commonring\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:676:\t\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-677-\t\treturn BRCMF_FLOWRING_INVALID_ID;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-683-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:684:static void brcmf_msgbuf_flowring_worker(struct work_struct *work)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-685-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:686:\tstruct brcmf_msgbuf *msgbuf;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:687:\tstruct brcmf_msgbuf_work_item *create;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-688-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:689:\tmsgbuf = container_of(work, struct brcmf_msgbuf, flowring_work);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-690-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:691:\twhile ((create = brcmf_msgbuf_dequeue_work(msgbuf))) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:692:\t\tbrcmf_msgbuf_flowring_create_worker(msgbuf, create);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-693-\t\tkfree(create);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-697-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:698:static u32 brcmf_msgbuf_flowring_create(struct brcmf_msgbuf *msgbuf, int ifidx,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-699-\t\t\t\t\tstruct sk_buff *skb)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-700-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:701:\tstruct brcmf_msgbuf_work_item *create;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-702-\tstruct ethhdr *eh = (struct ethhdr *)(skb-\u003edata);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-730-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:731:static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-732-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-758-\t\tskb_orphan(skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:759:\t\tif (brcmf_msgbuf_alloc_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-760-\t\t\t\t\t     msgbuf-\u003etx_pktids, skb, ETH_HLEN,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-767-\t\tif (!ret_ptr) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:768:\t\t\tbrcmf_msgbuf_get_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-769-\t\t\t\t\t       msgbuf-\u003etx_pktids, pktid);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-804-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:805:static void brcmf_msgbuf_txflow_worker(struct work_struct *worker)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-806-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:807:\tstruct brcmf_msgbuf *msgbuf;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-808-\tu32 flowid;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-809-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:810:\tmsgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-811-\tfor_each_set_bit(flowid, msgbuf-\u003eflow_map, msgbuf-\u003emax_flowrings) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-812-\t\tclear_bit(flowid, msgbuf-\u003eflow_map);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:813:\t\tbrcmf_msgbuf_txflow(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-814-\t}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-817-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:818:static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-819-\t\t\t\t\tbool force)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-852-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:853:static int brcmf_msgbuf_tx_queue_data(struct brcmf_pub *drvr, int ifidx,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-854-\t\t\t\t      struct sk_buff *skb)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-855-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:856:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-857-\tstruct brcmf_flowring *flow = msgbuf-\u003eflow;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-864-\tif (flowid == BRCMF_FLOWRING_INVALID_ID) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:865:\t\tflowid = brcmf_msgbuf_flowring_create(msgbuf, ifidx, skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-866-\t\tif (flowid == BRCMF_FLOWRING_INVALID_ID) {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-874-\tforce = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:875:\tbrcmf_msgbuf_schedule_txdata(msgbuf, flowid, force);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-876-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=881=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:882:brcmf_msgbuf_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-883-\t\t\t\t enum proto_addr_mode addr_mode)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-884-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:885:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-886-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=891=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:892:brcmf_msgbuf_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-893-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:894:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-895-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=900=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:901:brcmf_msgbuf_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-902-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:903:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-904-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=909=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:910:brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-911-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-920-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:921:\tbrcmf_msgbuf_ioctl_resp_wake(msgbuf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-922-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-924-\t\tmsgbuf-\u003ecur_ioctlrespbuf--;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:925:\tbrcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-926-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=929=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:930:brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-931-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-941-\tflowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:942:\tskb = brcmf_msgbuf_get_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-943-\t\t\t\t     msgbuf-\u003etx_pktids, idx);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-955-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:956:static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-957-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-991-\t\tpktlen = skb-\u003elen;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:992:\t\tif (brcmf_msgbuf_alloc_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-993-\t\t\t\t\t     msgbuf-\u003erx_pktids, skb, 0,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1034=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1035:brcmf_msgbuf_rxbuf_data_fill(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1036-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1042-\twhile (fillbufs) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1043:\t\tretcount = brcmf_msgbuf_rxbuf_data_post(msgbuf, fillbufs);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1044-\t\tif (!retcount)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1052=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1053:brcmf_msgbuf_update_rxbufpost_count(struct brcmf_msgbuf *msgbuf, u16 rxcnt)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1054-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1057-\t\t\t\t  BRCMF_MSGBUF_RXBUFPOST_THRESHOLD))\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1058:\t\tbrcmf_msgbuf_rxbuf_data_fill(msgbuf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1059-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1062=static u32\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1063:brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1064-\t\t\t     u32 count)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1101-\t\tpktlen = skb-\u003elen;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1102:\t\tif (brcmf_msgbuf_alloc_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1103-\t\t\t\t\t     msgbuf-\u003erx_pktids, skb, 0,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1135-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1136:static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1137-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1140-\tcount = msgbuf-\u003emax_ioctlrespbuf - msgbuf-\u003ecur_ioctlrespbuf;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1141:\tcount = brcmf_msgbuf_rxbuf_ctrl_post(msgbuf, false, count);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1142-\tmsgbuf-\u003ecur_ioctlrespbuf += count;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1145-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1146:static void brcmf_msgbuf_rxbuf_event_post(struct brcmf_msgbuf *msgbuf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1147-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1150-\tcount = msgbuf-\u003emax_eventbuf - msgbuf-\u003ecur_eventbuf;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1151:\tcount = brcmf_msgbuf_rxbuf_ctrl_post(msgbuf, true, count);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1152-\tmsgbuf-\u003ecur_eventbuf += count;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1155-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1156:static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1157-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1170-\t\tmsgbuf-\u003ecur_eventbuf--;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1171:\tbrcmf_msgbuf_rxbuf_event_post(msgbuf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1172-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1173:\tskb = brcmf_msgbuf_get_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1174-\t\t\t\t     msgbuf-\u003erx_pktids, idx);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1199=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1200:brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1201-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1210-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1211:\tbrcmf_msgbuf_update_rxbufpost_count(msgbuf, 1);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1212-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1218-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1219:\tskb = brcmf_msgbuf_get_pktid(msgbuf-\u003edrvr-\u003ebus_if-\u003edev,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1220-\t\t\t\t     msgbuf-\u003erx_pktids, idx);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1256-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1257:static void brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf *msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1258-\t\t\t\t\t    void *buf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1268-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1269:static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1270-\t\t\t\t\t     void *buf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1285=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1286:brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1287-\t\t\t\t\t       void *buf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1301-\t\tbphy_err(drvr, \"Flowring creation failed, code %d\\n\", status);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1302:\t\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1303-\t\treturn;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1309-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1310:\tbrcmf_msgbuf_schedule_txdata(msgbuf, flowid, true);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1311-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1314=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1315:brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1316-\t\t\t\t\t       void *buf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1336-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1337:\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1338-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1340-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1341:static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1342-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1349-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_GEN_STATUS\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1350:\t\tbrcmf_msgbuf_process_gen_status(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1351-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1353-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_RING_STATUS\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1354:\t\tbrcmf_msgbuf_process_ring_status(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1355-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1357-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1358:\t\tbrcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1359-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1361-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1362:\t\tbrcmf_msgbuf_process_flow_ring_delete_response(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1363-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1368-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_IOCTL_CMPLT\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1369:\t\tbrcmf_msgbuf_process_ioctl_complete(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1370-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1372-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_WL_EVENT\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1373:\t\tbrcmf_msgbuf_process_event(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1374-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1376-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_TX_STATUS\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1377:\t\tbrcmf_msgbuf_process_txstatus(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1378-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1380-\t\tbrcmf_dbg(MSGBUF, \"MSGBUF_TYPE_RX_CMPLT\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1381:\t\tbrcmf_msgbuf_process_rx_complete(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1382-\t\tbreak;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1389-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1390:static void brcmf_msgbuf_process_rx(struct brcmf_msgbuf *msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1391-\t\t\t\t    struct brcmf_commonring *commonring)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1403-\twhile (count) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1404:\t\tbrcmf_msgbuf_process_msgtype(msgbuf,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1405-\t\t\t\t\t     buf + msgbuf-\u003erx_dataoffset);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1422=int brcmf_proto_msgbuf_rx_trigger(struct device *dev)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1425-\tstruct brcmf_pub *drvr = bus_if-\u003edrvr;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1426:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1427-\tstruct brcmf_commonring *commonring;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1432-\tbuf = msgbuf-\u003ecommonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1433:\tbrcmf_msgbuf_process_rx(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1434-\tbuf = msgbuf-\u003ecommonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1435:\tbrcmf_msgbuf_process_rx(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1436-\tbuf = msgbuf-\u003ecommonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1437:\tbrcmf_msgbuf_process_rx(msgbuf, buf);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1438-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1446-\t\t\t\tBRCMF_MSGBUF_TRICKLE_TXWORKER_THRS)))\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1447:\t\t\tbrcmf_msgbuf_schedule_txdata(msgbuf, flowid, true);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1448-\t}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1453-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1454:void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1455-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1456:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1457-\tstruct msgbuf_tx_flowring_delete_req *delete;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1483-\t\tbrcmf_dbg(MSGBUF, \"bus down, flowring will be removed\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1484:\t\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1485-\t\treturn;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1493-\t\tbrcmf_commonring_unlock(commonring);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1494:\t\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1495-\t\treturn;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1516-\t\tbphy_err(drvr, \"Failed to submit RING_DELETE, flowring will be removed\\n\");\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1517:\t\tbrcmf_msgbuf_remove_flowring(msgbuf, flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1518-\t}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1521-#ifdef DEBUG\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1522:static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1523-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1525-\tstruct brcmf_pub *drvr = bus_if-\u003edrvr;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1526:\tstruct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr-\u003eproto-\u003epd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1527-\tstruct brcmf_commonring *commonring;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1568-#else\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1569:static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1570-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1574-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1575:static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1576-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1577:\tbrcmf_debugfs_add_entry(drvr, \"msgbuf_stats\", brcmf_msgbuf_stats_read);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1578-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1580=int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1582-\tstruct brcmf_bus_msgbuf *if_msgbuf;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1583:\tstruct brcmf_msgbuf *msgbuf;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1584-\tu64 address;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1603-\t}\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1604:\tINIT_WORK(\u0026msgbuf-\u003etxflow_work, brcmf_msgbuf_txflow_worker);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1605-\tcount = BITS_TO_LONGS(if_msgbuf-\u003emax_flowrings);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1625-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1626:\tdrvr-\u003eproto-\u003ehdrpull = brcmf_msgbuf_hdrpull;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1627:\tdrvr-\u003eproto-\u003equery_dcmd = brcmf_msgbuf_query_dcmd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1628:\tdrvr-\u003eproto-\u003eset_dcmd = brcmf_msgbuf_set_dcmd;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1629:\tdrvr-\u003eproto-\u003etx_queue_data = brcmf_msgbuf_tx_queue_data;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1630:\tdrvr-\u003eproto-\u003econfigure_addr_mode = brcmf_msgbuf_configure_addr_mode;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1631:\tdrvr-\u003eproto-\u003edelete_peer = brcmf_msgbuf_delete_peer;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1632:\tdrvr-\u003eproto-\u003eadd_tdls_peer = brcmf_msgbuf_add_tdls_peer;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1633:\tdrvr-\u003eproto-\u003erxreorder = brcmf_msgbuf_rxreorder;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1634:\tdrvr-\u003eproto-\u003edebugfs_create = brcmf_msgbuf_debugfs_create;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1635-\tdrvr-\u003eproto-\u003epd = msgbuf;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1654-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1655:\tmsgbuf-\u003etx_pktids = brcmf_msgbuf_init_pktids(NR_TX_PKTIDS,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1656-\t\t\t\t\t\t     DMA_TO_DEVICE);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1658-\t\tgoto fail;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1659:\tmsgbuf-\u003erx_pktids = brcmf_msgbuf_init_pktids(NR_RX_PKTIDS,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1660-\t\t\t\t\t\t     DMA_FROM_DEVICE);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1674-\tdo {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1675:\t\tbrcmf_msgbuf_rxbuf_data_fill(msgbuf);\n\n"
}

7/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 35214
							output: 52
							thoughts: 30
						

Thoughts:
Here's my thought process, as it relates to this code:

**Checking PCIe/USB Driver Dependencies**

Okay, so I'm looking at `msgbuf.c` and `flowring.c`. The context tells me these are definitely involved in PCIe operations. My immediate thought is, "Are these also utilized by the USB stack?" It's a valid question, as both PCIe and USB are methods for data transfer, and there could be overlap in how buffers and flow control are managed at a low level. It makes sense to verify if there's any shared code. Determining whether USB uses these files would help me understand the architecture more fully. It would determine the extent of these utilities, and how they relate across the different devices supported by the system. My next step will be to dive into the USB driver code and look for any references or dependencies on these particular modules.



8/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "brcmf_proto_msgbuf_attach",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1575=static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1579-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1580:int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1581-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h=32=void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h:33:int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h-34-void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h-35-#else\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h:36:static inline int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h-37-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c=20=int brcmf_proto_attach(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-35-\t} else if (drvr-\u003ebus_if-\u003eproto_type == BRCMF_PROTO_MSGBUF) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c:36:\t\tif (brcmf_proto_msgbuf_attach(drvr))\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-37-\t\t\tgoto fail;\n"
}

9/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 36148
							output: 48
							thoughts: 13
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience, and delivered as a first-person summary:

**Digging into the `proto_type` USB Implementation**

Alright, so I need to understand what `proto_type` USB uses under the hood. It’s crucial to know this, because that impacts everything from power consumption and data transfer rates to overall system architecture and design choices. I need to be able to assess potential bottlenecks and understand the implications of any decisions around this `proto_type`. I'm going to quickly get a sense of the USB version and features it's using. This will help me plan a more thorough investigation. Knowing this will give me a baseline to work from, before I start looking at the lower level details.



10/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "proto_type",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1244=static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1268-\tbus-\u003eops = \u0026brcmf_usb_bus_ops;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1269:\tbus-\u003eproto_type = BRCMF_PROTO_BCDC;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1270-\tbus-\u003efwvid = fwvid;\n"
}

11/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 36579
							output: 55
							thoughts: 355
						

Thoughts:
**My Analysis of Broadcom Wi-Fi Driver Fuzzing Potential**

Okay, so I'm trying to figure out how to fuzz the `brcmfmac` driver, specifically for Broadcom Wi-Fi. My initial thought is to look at the different protocol layers it uses, namely `BRCMF_PROTO_BCDC` for USB and `BRCMF_PROTO_MSGBUF` for PCIe. Can I even get to the PCIe side for fuzzing? Syzkaller's no help here, it doesn't do a good job of emulating Broadcom PCIe Wi-Fi. It only has generic device emulation, right?

Alright, let's see, does QEMU offer any emulation that might help with Broadcom PCIe Wi-Fi? Nope. So, that's a dead end. Standard QEMU just won't get me there. SDIO? Syzkaller again isn't going to help. And `mac80211_hwsim`? Forget it, `brcmfmac` is a FullMAC driver, which means it doesn't use `mac80211_hwsim`.

So, the real question is, how do I reach the `brcmfmac` code without real hardware?

If the driver is probed via USB, it uses `BRCMF_PROTO_BCDC`. I've noticed the patch touches a bunch of files: `cfg80211.c`, `core.c`, `flowring.c`, `msgbuf.c`, `pcie.c`, `sdio.c`, and `ampdu.c`. The good news is that `cfg80211.c` and `core.c` are shared by all the buses, USB, PCIe, and SDIO. That's a good place to start.

I need to focus my efforts on whether I can successfully probe the `brcmfmac` USB without the real firmware. If loading the firmware fails, `brcmf_usb_probe_phase2` will fail, and the driver will unregister. I should probably dig into `brcmf_usb_probe_phase2` to see what is going on there.



12/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "brcmf_usb_probe_phase2",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1165=static const struct brcmf_bus_ops brcmf_usb_bus_ops = {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1175-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1176:static void brcmf_usb_probe_phase2(struct device *dev, int ret,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1177-\t\t\t\t   struct brcmf_fw_request *fwreq)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1244=static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1307-\t/* request firmware here */\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1308:\tret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1309-\tif (ret) {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1511=static int brcmf_usb_reset_resume(struct usb_interface *intf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1523-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1524:\tret = brcmf_fw_get_firmwares(\u0026usb-\u003edev, fwreq, brcmf_usb_probe_phase2);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1525-\tif (ret \u003c 0)\n"
}

13/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 38051
							output: 54
							thoughts: 19
						

Thoughts:
Okay, here's my attempt at summarizing the thought process, tailored for an expert audience, and written in the first person:

**Diving into brcmf_usb_probe_phase2**

Alright, let's get into the nitty-gritty. I'm taking a look at `brcmf_usb_probe_phase2` to see what's happening. I expect this function is where the USB-specific initialization steps finalize after the initial device attachment. First, I'll be looking for resource allocation; memory, interrupts, DMA channels. I'll want to see how it's interacting with the underlying USB stack, probably using `usb_register_dev()`.

I'm betting the firmware loading is handled here, or at least initiated. It's likely using `usb_bulk_msg` or `usb_control_msg` to transfer the firmware image to the device. I need to track down the error handling as well. Where are the failure points? What's the recovery path if the firmware load fails, or if the device fails during initialization? 

Next I'll look for device specific configuration. Are there any vendor-specific requests or URB setup? I'll probably find some more `usb_set_intfdata()` calls, setting up per-device data. This might be where power management is setup as well. I'll check how it handles different USB configurations; high-speed, full-speed, etc. The clock setup is probably here too, if it needs a specific clock.

Finally, I'm expecting to see the initialization of the BRCMF driver's internal data structures, like the *brcmf_pub* structure, and linking them to the USB device. I'll be checking to see what gets registered with the kernel, specifically, is a network device interface created, and how it is connected to the USB device. I will search for the appropriate `netif_` calls, and `register_netdev()`, and its associated cleanup function. Time to start digging!



14/2 2026/08/01 05:50 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c",
  "FirstLine": 1176,
  "LineCount": 50
}

Results:
{
  "Contents": "1176:\tstatic void brcmf_usb_probe_phase2(struct device *dev, int ret,\n1177:\t\t\t\t\t   struct brcmf_fw_request *fwreq)\n1178:\t{\n1179:\t\tstruct brcmf_bus *bus = dev_get_drvdata(dev);\n1180:\t\tstruct brcmf_usbdev_info *devinfo = bus-\u003ebus_priv.usb-\u003edevinfo;\n1181:\t\tconst struct firmware *fw;\n1182:\t\n1183:\t\tif (ret)\n1184:\t\t\tgoto error;\n1185:\t\n1186:\t\tbrcmf_dbg(USB, \"Start fw downloading\\n\");\n1187:\t\n1188:\t\tfw = fwreq-\u003eitems[BRCMF_USB_FW_CODE].binary;\n1189:\t\tkfree(fwreq);\n1190:\t\n1191:\t\tret = check_file(fw-\u003edata);\n1192:\t\tif (ret \u003c 0) {\n1193:\t\t\tbrcmf_err(\"invalid firmware\\n\");\n1194:\t\t\trelease_firmware(fw);\n1195:\t\t\tgoto error;\n1196:\t\t}\n1197:\t\n1198:\t\tdevinfo-\u003eimage = fw-\u003edata;\n1199:\t\tdevinfo-\u003eimage_len = fw-\u003esize;\n1200:\t\n1201:\t\tret = brcmf_usb_fw_download(devinfo);\n1202:\t\trelease_firmware(fw);\n1203:\t\tif (ret)\n1204:\t\t\tgoto error;\n1205:\t\n1206:\t\tret = brcmf_alloc(devinfo-\u003edev, devinfo-\u003esettings);\n1207:\t\tif (ret)\n1208:\t\t\tgoto error;\n1209:\t\n1210:\t\t/* Attach to the common driver interface */\n1211:\t\tret = brcmf_attach(devinfo-\u003edev);\n1212:\t\tif (ret)\n1213:\t\t\tgoto error;\n1214:\t\n1215:\t\tcomplete(\u0026devinfo-\u003edev_init_done);\n1216:\t\treturn;\n1217:\terror:\n1218:\t\tbrcmf_dbg(TRACE, \"failed: dev=%s, err=%d\\n\", dev_name(dev), ret);\n1219:\t\tcomplete(\u0026devinfo-\u003edev_init_done);\n1220:\t\tdevice_release_driver(dev);\n1221:\t}\n1222:\t\n1223:\tstatic struct brcmf_fw_request *\n1224:\tbrcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo)\n1225:\t{\n"
}

15/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 39292
							output: 48
							thoughts: 214
						

Thoughts:
**Analyzing the Broadcom Wi-Fi Driver Firmware Loading Process**

Okay, so I'm looking at this error handling, and it's pretty straightforward. If the return code, `ret`, is anything other than zero – meaning the firmware isn't found – we jump right into error handling. That involves releasing the driver with `device_release_driver(dev)` and then, predictably, it fails. Standard stuff.

My initial thought is that Syzkaller probably doesn't have the Broadcom firmware images for `brcmfmac`. Specifically, the ones like `brcmfmac43143.bin` or `brcmfmac43236b.bin`, and the code would throw an error if one of these weren't provided.

Wait, hold on. I need to rethink this, since I remember Syzkaller has some firmware images. Okay, but I bet they're not Broadcom Wi-Fi firmwares. Even if they were, that `brcmf_usb_fw_download` function is going to try and write the firmware to the device using USB control messages. Since this is a dummy USB device, it probably will just accept those messages. However, since the device isn't real, it won't actually execute the firmware or respond correctly. So, it's likely a dead end, even if we *could* get the right firmware loaded.

After that firmware download, we get `brcmf_attach`, which initializes the core driver. That's the real meat of the operation. So, I need to understand what `brcmf_attach` is actually doing. Let's see...



16/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "int brcmf_attach",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h=299=int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h-300-/* Indication from bus module regarding presence/insertion of dongle. */\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h:301:int brcmf_attach(struct device *dev);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h-302-/* Indication from bus module regarding removal/absence of dongle */\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c=1307=int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-1335-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c:1336:int brcmf_attach(struct device *dev)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-1337-{\n"
}

17/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 40273
							output: 54
							thoughts: 11
						

Thoughts:
Okay, here's my attempt at summarizing the thought process, as if I were a seasoned professional in the field, starting with the bolded header:

**Diving into `brcmf_attach`**

Alright, let's get down to brass tacks. The target here is `brcmf_attach`. I'm already anticipating what to expect, but let's see how well it maps to my mental model. Usually in these sorts of drivers, this is the pivotal function— the gateway. It's the point where a new device instance gets integrated into the system. I’m thinking initialization, resource allocation, and binding to the relevant kernel subsystems are all likely candidates for this function's responsibilities. Things like hardware identification, setting up DMA channels, establishing interrupt handlers... I'm really curious to see how the Broadcom driver manages its device context and how it interacts with the firmware. Is there a separate firmware load stage? How does it handle potential errors during attachment? Are there any clever tricks to optimize the process, maybe specific to their chipsets? I know these drivers can get convoluted quickly, so I'll be keeping an eye out for any particularly interesting or unconventional approaches. Time to dig in!



18/2 2026/08/01 05:50 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c",
  "FirstLine": 1336,
  "LineCount": 50
}

Results:
{
  "Contents": "1336:\tint brcmf_attach(struct device *dev)\n1337:\t{\n1338:\t\tstruct brcmf_bus *bus_if = dev_get_drvdata(dev);\n1339:\t\tstruct brcmf_pub *drvr = bus_if-\u003edrvr;\n1340:\t\tint ret = 0;\n1341:\t\tint i;\n1342:\t\n1343:\t\tbrcmf_dbg(TRACE, \"Enter\\n\");\n1344:\t\n1345:\t\tfor (i = 0; i \u003c ARRAY_SIZE(drvr-\u003eif2bss); i++)\n1346:\t\t\tdrvr-\u003eif2bss[i] = BRCMF_BSSIDX_INVALID;\n1347:\t\n1348:\t\tmutex_init(\u0026drvr-\u003eproto_block);\n1349:\t\n1350:\t\t/* Link to bus module */\n1351:\t\tdrvr-\u003ehdrlen = 0;\n1352:\t\n1353:\t\tret = brcmf_fwvid_attach(drvr);\n1354:\t\tif (ret != 0) {\n1355:\t\t\tbphy_err(drvr, \"brcmf_fwvid_attach failed\\n\");\n1356:\t\t\tgoto fail;\n1357:\t\t}\n1358:\t\n1359:\t\t/* Attach and link in the protocol */\n1360:\t\tret = brcmf_proto_attach(drvr);\n1361:\t\tif (ret != 0) {\n1362:\t\t\tbphy_err(drvr, \"brcmf_prot_attach failed\\n\");\n1363:\t\t\tgoto fail;\n1364:\t\t}\n1365:\t\n1366:\t\t/* attach firmware event handler */\n1367:\t\tret = brcmf_fweh_attach(drvr);\n1368:\t\tif (ret != 0) {\n1369:\t\t\tbphy_err(drvr, \"brcmf_fweh_attach failed\\n\");\n1370:\t\t\tgoto fail;\n1371:\t\t}\n1372:\t\n1373:\t\t/* Attach to events important for core code */\n1374:\t\tbrcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,\n1375:\t\t\t\t    brcmf_psm_watchdog_notify);\n1376:\t\n1377:\t\tbrcmf_fwvid_get_cfg80211_ops(drvr);\n1378:\t\n1379:\t\tret = brcmf_bus_started(drvr, drvr-\u003eops);\n1380:\t\tif (ret != 0) {\n1381:\t\t\tbphy_err(drvr, \"dongle is not responding: err=%d\\n\", ret);\n1382:\t\t\tgoto fail;\n1383:\t\t}\n1384:\t\n1385:\t\treturn 0;\n"
}

19/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 41374
							output: 50
							thoughts: 20
						

Thoughts:
Okay, here's my take on those thoughts, framed for an expert like myself:

**Diving into brcmf_bus_started**

Alright, the `brcmf_bus_started` function has been called. Time to dig in and see what's happening under the hood. I need to understand what this function is actually *doing* at this critical juncture. It's likely setting up the initial state for the Broadcom Wi-Fi bus, but I need to get the specific details. I'll need to trace its call graph and examine its function calls to understand the setup process. Am I going to be dealing with register reads and writes? Power management configuration? Initialization of DMA channels? I’m expecting a flurry of bus initialization actions. I will need to understand if the start is successful or if any errors are returned. This should give a good idea of how the driver orchestrates the interactions between the host and the Broadcom Wi-Fi chip, from the very beginning.



20/2 2026/08/01 05:50 tool grepper
0m Args:
{
  "Expression": "int brcmf_bus_started",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c=1201=static const struct file_operations bus_reset_fops = {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-1205-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c:1206:static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-1207-{\n"
}

21/2 2026/08/01 05:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 41840
							output: 54
							thoughts: 13
						

Thoughts:
Okay, let's dive into this. Here's my take on `brcmf_bus_started`:

**My Analysis of brcmf_bus_started**

Alright, I'm going to examine the `brcmf_bus_started` function. Based on the naming, I'm immediately expecting to see the initial stages of bringing up the bus interface for the Broadcom Wi-Fi driver. This is likely where the hardware is initialized and configured after the driver has been loaded, or at least started its initialization sequence. I'll be looking for things like:

*   **Hardware probing and identification:** Is there any detection or identification of specific bus types (SDIO, PCIe, USB, etc.) and related hardware? I'll pay attention to the bus-specific initialization.
*   **Resource allocation:** Are memory regions, interrupts, or other hardware resources being requested and mapped here? I need to understand the resource management.
*   **Bus-specific initialization:** What bus-specific operations are being performed? Are there any low-level hardware registers being programmed?
*   **Driver registration/attachment:** Is this where the driver itself is attaching to the bus? I'm watching for any calls to bus driver attachment functions or something like "device registration".
*   **Power management considerations:** Is any power management logic being used here? Are there power-on sequences or power state transitions involved?
*   **Error handling:** What error conditions are handled, and how? This is critical for reliability. Are there attempts to probe or re-initialize if it fails?
*   **Interrupt setup:** Any interrupt-related set-up.
*   **Deferred work:** If this function kicks off any deferred work, like a delayed probe, I'll need to understand what's happening.

This will give me the information on how the Broadcom Wi-Fi driver gets the bus interface ready for data transfer. Understanding the sequence of steps and the potential points of failure is crucial for debugging and optimization. It will also help me to identify any areas of concern in terms of resource contention or driver dependencies. Essentially, it's the foundation for the whole data plane. I'm keen to go through the code step-by-step and see how the bus gets started.



22/2 2026/08/01 05:51 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c",
  "FirstLine": 1206,
  "LineCount": 50
}

Results:
{
  "Contents": "1206:\tstatic int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)\n1207:\t{\n1208:\t\tint ret = -1;\n1209:\t\tstruct brcmf_bus *bus_if = drvr-\u003ebus_if;\n1210:\t\tstruct brcmf_if *ifp;\n1211:\t\tstruct brcmf_if *p2p_ifp;\n1212:\t\n1213:\t\tbrcmf_dbg(TRACE, \"\\n\");\n1214:\t\n1215:\t\t/* add primary networking interface */\n1216:\t\tifp = brcmf_add_if(drvr, 0, 0, false, \"wlan%d\",\n1217:\t\t\t\t   is_valid_ether_addr(drvr-\u003esettings-\u003emac) ? drvr-\u003esettings-\u003emac : NULL);\n1218:\t\tif (IS_ERR(ifp))\n1219:\t\t\treturn PTR_ERR(ifp);\n1220:\t\n1221:\t\tp2p_ifp = NULL;\n1222:\t\n1223:\t\t/* signal bus ready */\n1224:\t\tbrcmf_bus_change_state(bus_if, BRCMF_BUS_UP);\n1225:\t\n1226:\t\t/* do bus specific preinit here */\n1227:\t\tret = brcmf_bus_preinit(bus_if);\n1228:\t\tif (ret \u003c 0)\n1229:\t\t\tgoto fail;\n1230:\t\n1231:\t\t/* Bus is ready, do any initialization */\n1232:\t\tret = brcmf_c_preinit_dcmds(ifp);\n1233:\t\tif (ret \u003c 0)\n1234:\t\t\tgoto fail;\n1235:\t\n1236:\t\tbrcmf_feat_attach(drvr);\n1237:\t\n1238:\t\tret = brcmf_proto_init_done(drvr);\n1239:\t\tif (ret \u003c 0)\n1240:\t\t\tgoto fail;\n1241:\t\n1242:\t\tbrcmf_proto_add_if(drvr, ifp);\n1243:\t\n1244:\t\tdrvr-\u003econfig = brcmf_cfg80211_attach(drvr, ops,\n1245:\t\t\t\t\t\t     drvr-\u003esettings-\u003ep2p_enable);\n1246:\t\tif (drvr-\u003econfig == NULL) {\n1247:\t\t\tret = -ENOMEM;\n1248:\t\t\tgoto fail;\n1249:\t\t}\n1250:\t\n1251:\t\tret = brcmf_net_attach(ifp, false);\n1252:\t\n1253:\t\tif ((!ret) \u0026\u0026 (drvr-\u003esettings-\u003ep2p_enable)) {\n1254:\t\t\tp2p_ifp = drvr-\u003eiflist[1];\n1255:\t\t\tif (p2p_ifp)\n"
}

23/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 43187
							output: 46
							thoughts: 396
						

Thoughts:
**My Analysis of the `brcmfmac` USB Driver Initialization**

Okay, so here's the breakdown of my thinking. The `brcmf_c_preinit_dcmds` function sends commands to the firmware. Now, if the firmware isn't actually running (like with a dummy USB device), those commands are going to fail or time out, which causes `brcmf_bus_started` to fail. This is the normal initialization flow and means the driver won't complete setup.

But, hold on a second. If syzkaller is fuzzing this USB interface, it can *provide* the responses to the control messages and the bulk endpoints that the driver is expecting. Hmm, the implication is that syzkaller can basically *emulate* the firmware's responses!

Right, I need to check if syzkaller can emulate `brcmfmac`'s USB behavior specifically. Based on prior knowledge, I believe syzkaller's `dummy_hcd` can emulate *any* USB device. The fuzzer has the power to provide completely arbitrary responses to any incoming USB request.

Therefore, it's totally plausible for the fuzzer to bypass the `brcmf_c_preinit_dcmds` function by giving it the USB responses it needs.

Ah, but there's more to this. The `brcmfmac` firmware download *itself* happens over USB. So, the driver sends the firmware image, expects the firmware to boot, and then respond to commands. This is done with `BRCMF_PROTO_BCDC` for USB.

Let's see if `brcmf_c_preinit_dcmds` is actually reachable. If it is reachable, then there's a possibility that changes made to the `cfg80211.c` file could be exploitable, and it would be worth targeting.

Thinking about it, I need to check `brcmf_cfg80211_set_pmksa`. This is a cfg80211 callback. It is called by userspace via netlink to set the PMKSA. This requires the wireless device to be registered with cfg80211 (`wiphy_register`). That function is likely called in `brcmf_cfg80211_attach`, or something similar. So, next step, I need to investigate `brcmf_cfg80211_attach`.



24/2 2026/08/01 05:51 tool grepper
0m Args:
{
  "Expression": "wiphy_register",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c=8405=struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c-8489-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:8490:\terr = wiphy_register(wiphy);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c-8491-\tif (err \u003c 0) {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c-8501-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:8502:\t/* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c-8503-\t * setup 40MHz in 2GHz band and enable OBSS scanning.\n"
}

25/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 44530
							output: 28
							thoughts: 137
						

Thoughts:
**My Assessment of the `brcmfmac` Fuzzing Potential**

Okay, so the challenge here is getting a fuzzer, specifically Syzkaller, to really dig into `brcmfmac` via the USB interface. The core problem, as I see it, is the initialization sequence. If the fuzzer can flawlessly emulate the USB device sufficiently to make it past `brcmf_c_preinit_dcmds` and `brcmf_bus_started`, then we're in business – the wiphy registers and the `cfg80211` callbacks will open up. The crucial question is, can Syzkaller realistically achieve that?

Syzkaller does have USB device descriptions, but I'm highly skeptical of pure random fuzzing succeeding with complex firmware initialization handshakes. These protocols are often intricate and require specific knowledge of the expected data structures and command sequences. Unless we have dedicated Syzlang descriptions tailored for the `brcmfmac` USB protocol, I think we're going to hit a wall. Therefore, I need to check to confirm if any syzkaller descriptions exist for `brcmfmac`, if they don't we will have to make them.



26/2 2026/08/01 05:51 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "brcmfmac",
  "PathPrefix": "sys/linux/"
}

Results:
{
  "error": "no matches"
}

27/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 44964
							output: 52
							thoughts: 502
						

Thoughts:
**Analyzing the Worthiness of Fuzzing a Patch**

Okay, first things first. The prompt clearly states I can't directly search syzkaller-specific descriptions. That means I can't use `grepper` on `sys/linux/` or anything with "syz_" in it. That's a good reminder. But, the overarching goal here is to determine if the patch is *worth* fuzzing. And even if syzkaller can't directly *describe* it, doesn't mean it can't reach it. So I need to keep that perspective. Syzkaller might still be able to hit it. Reachable core/driver logic is always worth consideration.

Alright, the next part of the prompt outlines some specific scenarios where I should return `WorthFuzzing=false`. These are: documentation changes, Kconfig modifications, comments, decorative logging (pr_err, printk, tracepoints), numeric constant changes (unless they impact execution), unreachable code in virtualized environments, and vendor-specific drivers requiring physical hardware. Got it. I need to be diligent about identifying these.

Now, on to the actual patch I'm examining. I'm looking at `brcmfmac`, a Broadcom FullMAC wireless driver that supports PCIe, SDIO, and USB. Important. PCIe and SDIO aren't emulated in standard QEMU. That's a key piece of information. However, USB *is* emulated via `dummy_hcd`, USB gadget. So, the question becomes: can `brcmfmac`'s USB path be reached? The answer is yes, through the `dummy_hcd`. But... the patch modifies multiple files: `msgbuf.c`, `flowring.c`, `pcie.c`, `sdio.c`, `cfg80211.c`, `core.c`, and `ampdu.c`. Now I need to examine to what extent the parts of `brcmfmac` which use USB are modified. `pcie.c` and `sdio.c` are not applicable, as we just learned.

My next step is to drill down. Are `msgbuf.c` and `flowring.c` used by USB? Remember, I'm trying to decide if this is worth fuzzing. I recall that `BRCMF_PROTO_BCDC` is used for USB. Therefore, I'll need to check if `BRCMF_PROTO_BCDC` makes use of either `msgbuf.c` or `flowring.c`. I need to figure out what files are used by each USB protocol, and determine if they're affected by this patch.



28/2 2026/08/01 05:51 tool grepper
0m Args:
{
  "Expression": "brcmf_proto_msgbuf_attach",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1575=static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1579-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1580:int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1581-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h=32=void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h:33:int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h-34-void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h-35-#else\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h:36:static inline int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h-37-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c=20=int brcmf_proto_attach(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-35-\t} else if (drvr-\u003ebus_if-\u003eproto_type == BRCMF_PROTO_MSGBUF) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c:36:\t\tif (brcmf_proto_msgbuf_attach(drvr))\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-37-\t\t\tgoto fail;\n"
}

29/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46759
							output: 51
							thoughts: 44
						

Thoughts:
Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person:

**Decoding the `msgbuf.c` Dependency**

Alright, so the `msgbuf.c` file is only pulled in when `proto_type` is set to `BRCMF_PROTO_MSGBUF`. Straightforward enough, but that begs the question: Where is `BRCMF_PROTO_MSGBUF` actually *defined* and, critically, *how* is it being set? We need to trace this back. The dependency on `msgbuf.c` is conditional on a protocol type, so I need to find the specific bus that configures `BRCMF_PROTO_MSGBUF`, because that's what triggers the inclusion of `msgbuf.c`. Understanding the bus implementation setting the specific protocol will be essential to understanding where `msgbuf.c` is used. Time to dig in and find where that variable is being assigned. Let's see...



30/2 2026/08/01 05:51 tool grepper
0m Args:
{
  "Expression": "BRCMF_PROTO_MSGBUF",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h=50=enum brcmf_bus_protocol_type {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h-51-\tBRCMF_PROTO_BCDC,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h:52:\tBRCMF_PROTO_MSGBUF\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h-53-};\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c=2489=brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c-2564-\tbus-\u003eops = \u0026brcmf_pcie_bus_ops;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c:2565:\tbus-\u003eproto_type = BRCMF_PROTO_MSGBUF;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c-2566-\tbus-\u003echip = devinfo-\u003ecoreid;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c=20=int brcmf_proto_attach(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-34-\t\t\tgoto fail;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c:35:\t} else if (drvr-\u003ebus_if-\u003eproto_type == BRCMF_PROTO_MSGBUF) {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-36-\t\tif (brcmf_proto_msgbuf_attach(drvr))\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c=59=void brcmf_proto_detach(struct brcmf_pub *drvr)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-65-\t\t\tbrcmf_proto_bcdc_detach(drvr);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c:66:\t\telse if (drvr-\u003ebus_if-\u003eproto_type == BRCMF_PROTO_MSGBUF)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c-67-\t\t\tbrcmf_proto_msgbuf_detach(drvr);\n"
}

31/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 47829
							output: 44
							thoughts: 385
						

Thoughts:
**My Analysis of Reachable Code Paths**

Okay, let me break this down. From my understanding of the code, it seems that `BRCMF_PROTO_MSGBUF` is *only* used within the PCIe context. And `flowring.c` seems to be linked with `msgbuf.c`. Therefore, `msgbuf.c`, `flowring.c`, and `pcie.c` are all PCIe-specific modules. But what about SDIO? Ah, `sdio.c` is SDIO-specific. Fine. `cfg80211.c` and `core.c` appear to be shared modules – which is expected.

Now, let's consider the `brcmfmac` Wi-Fi driver. It's a FullMAC driver, which means it relies on firmware for operations and command responses. The critical point is whether we can get to `cfg80211.c` and `core.c`. If we emulate the USB device via a fuzzer, we should be able to get there.

The question then becomes, "can we reach these areas in QEMU?". The answer, as I see it, is yes. We can reach `cfg80211.c` and `core.c` in QEMU, specifically by USB fuzzing.

Hang on, the prompt emphasizes unreachable code paths in virtualized environments. It mentions the usual suspects: code dependent on specific physical PCIe cards (like `mlxsw`, `pds_core`, `qed`, etc.). But `brcmfmac` is a Wi-Fi driver, with a USB interface. This means the USB portions and the shared parts of the driver (`cfg80211.c`, `core.c`) are indeed reachable through USB gadget emulation.

I also need to check something else. `brcmsmac` also appears to have modifications. Specifically, `ampdu.c`. Let me quickly confirm. Is `brcmsmac` also PCIe-only?



32/2 2026/08/01 05:51 tool grepper
0m Args:
{
  "Expression": "module_init",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmsmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c=1318=static DECLARE_WORK(brcms_driver_work, brcms_driver_init);\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-1319-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:1320:static int __init brcms_module_init(void)\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-1321-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c=1336=static void __exit brcms_module_exit(void)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-1342-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:1343:module_init(brcms_module_init);\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-1344-module_exit(brcms_module_exit);\n"
}

33/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49075
							output: 60
							thoughts: 12
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into brcms_module_init**

Okay, time to get to the heart of the matter. Let's start with `brcms_module_init`. I need to understand what this module's initialization routine is doing. It's the entry point, the critical first step. I need to know: what resources is it grabbing? What structures is it allocating and populating? Any hardware initialization routines it's kicking off? What are the key data structures being initialized? Any interaction with the core firmware or device drivers? Is there any interesting platform-specific code I should be aware of? I'll probably start by looking for any calls to `request_mem_region` or `ioremap`... that'll give me a handle on memory management. Then, the calls to register device drivers, interrupt handlers, and any PCI configuration routines. I need to trace the initialization flow carefully, looking for potential areas of concern, particularly race conditions or resource conflicts. Understanding this routine is going to be key to debugging or modifying anything related to the Broadcom wireless stack.



34/2 2026/08/01 05:51 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c",
  "FirstLine": 1320,
  "LineCount": 20
}

Results:
{
  "Contents": "1320:\tstatic int __init brcms_module_init(void)\n1321:\t{\n1322:\t\tbrcms_debugfs_init();\n1323:\t\tif (!schedule_work(\u0026brcms_driver_work))\n1324:\t\t\treturn -EBUSY;\n1325:\t\n1326:\t\treturn 0;\n1327:\t}\n1328:\t\n1329:\t/*\n1330:\t * This function unloads the brcmsmac driver from the system.\n1331:\t *\n1332:\t * This function unconditionally unloads the brcmsmac driver module from the\n1333:\t * system.\n1334:\t *\n1335:\t */\n1336:\tstatic void __exit brcms_module_exit(void)\n1337:\t{\n1338:\t\tcancel_work_sync(\u0026brcms_driver_work);\n1339:\t\tbcma_driver_unregister(\u0026brcms_bcma_driver);\n"
}

35/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49665
							output: 49
							thoughts: 1976
						

Thoughts:
**Worth Fuzzing Assessment for brcmfmac/brcmsmac**

Okay, let's break this down. First, `brcmsmac` registers a `bcma` driver, which is Broadcom's internal bus, usually PCIe or SoC. Can we fuzz `bcma`? Syzkaller doesn't have a `bcma` fuzzer, that seems like a dead end. However, `brcmfmac` has a USB driver, so maybe that's the angle.

This specific patch modifies `brcmfmac/cfg80211.c` and `brcmfmac/core.c`. Looking at the changes in `cfg80211.c`: `brcmf_delay` is being changed, and a new function `brcmf_pmksa_v2_op` is added, along with modifications to `brcmf_cfg80211_set_pmksa`, `brcmf_cfg80211_del_pmksa`, and `brcmf_cfg80211_flush_pmksa` to use that new function.

Can we reach `brcmf_cfg80211_set_pmksa`? Yes, via cfg80211 netlink commands, like `NL80211_CMD_SET_PMKSA`. However, the driver needs to be registered with cfg80211 first. And that requires the firmware to be loaded and the device to respond to commands. If syzkaller can emulate the USB device, that may work.

But does syzkaller *actually* emulate `brcmfmac` USB?  The `dummy_hcd` just lets syzkaller inject USB descriptors and respond to USB transfers, it doesn't have a specialized state machine for `brcmfmac` firmware. Syzkaller can generate random USB responses, but will that be enough to pass the firmware loading phase? `request_firmware` needs to succeed. Syzkaller images may not have Broadcom firmware available, although it can inject firmware through `syz_mount_image` or in `/lib/firmware`. Let's assume that syzkaller has some Broadcom firmware available.

Even with the firmware, the driver reads it, sends it via USB, and expects the firmware to boot and respond to specific Broadcom commands. The probability of a random fuzzer generating *valid* Broadcom command responses is astronomically low.  Syzkaller has `mac80211_hwsim` for Wi-Fi fuzzing, but `mac80211_hwsim` is a software simulator for `mac80211`, and `brcmfmac` is a FullMAC driver that uses `cfg80211`, not `mac80211`. So that's not relevant.

Is `brcmfmac` worth fuzzing, based on this prompt?  The prompt explicitly excludes vendor-specific hardware drivers, especially PCIe switch, SmartNIC, or GPU drivers. `brcmfmac` is a vendor-specific Wi-Fi driver. It requires hardware (Broadcom chips) or complex USB emulation.

Syzkaller *has* found bugs in many USB Wi-Fi drivers like `ath9k_htc`, `rtw88`, `mt76`, `rtl8xxxu` via USB emulation, but that’s different than getting `brcmfmac` working. If `brcmfmac` relies on `request_firmware`, it might fail early. However, syzkaller's `dummy_hcd` can often hit bugs in probe or early initialization. But this patch's modifications are in data paths (RX/TX) or cfg80211 operations:

-   `brcmf_pmksa_v2_op` (cfg80211 ops, requires registered wiphy)
-   `brcmf_netif_mon_rx` (rx path, requires registered netdev)
-   `brcmf_flowring_block`, `brcmf_msgbuf_schedule_txdata`, `brcmf_pcie_send_mb_data` (tx path, PCIe specific)
-   `brcmf_sdio_rxglom` (SDIO specific)
-   `brcms_c_ampdu_add_frame` (brcmsmac, bcma bus)

The PCIe, SDIO and BCMA parts are unreachable in QEMU. The USB data paths are unlikely to be hit since they require the device to be fully initialized.

I see a commit message that seems like a syzkaller triage, but this is merely a patch *submitted* for testing


36/2 2026/08/01 05:51 tool grepper
0m Args:
{
  "Expression": "brcmf_rx_frame",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h=279=static inline void brcmf_bus_remove(struct brcmf_bus *bus)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h-293-/* Receive frame for delivery to OS.  Callee disposes of rxp. */\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h:294:void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h-295-\t\t    bool inirq);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c=489=static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-507-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c:508:void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-509-\t\t    bool inirq)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c=1514=static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c-1731-\t\t\telse\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:1732:\t\t\t\tbrcmf_rx_frame(bus-\u003esdiodev-\u003edev, pfirst,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c-1733-\t\t\t\t\t       false, false);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c=1870=static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c-2065-\t\telse\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2066:\t\t\tbrcmf_rx_frame(bus-\u003esdiodev-\u003edev, pkt,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c-2067-\t\t\t\t       false, false);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=507=static void brcmf_usb_rx_complete(struct urb *urb)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-527-\t\tskb_put(skb, urb-\u003eactual_length);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:528:\t\tbrcmf_rx_frame(devinfo-\u003edev, skb, true, true);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-529-\t\tbrcmf_usb_rx_refill(devinfo, req);\n"
}

37/2 2026/08/01 05:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 53698
							output: 55
							thoughts: 117
						

Thoughts:
**Analyzing the RX Frame Flow**

Okay, so I'm tracing how data gets received over USB in this `brcmf` driver. I see that `brcmf_rx_frame` is the ultimate handler for incoming frames, and it's called from `brcmf_usb_rx_complete`. `brcmf_usb_rx_complete` is triggered when a USB bulk IN transfer is complete. Right, makes sense. So, if a fuzzer, for example, sends a bulk IN transfer to the device, it'll hit `brcmf_usb_rx_complete`, and that function will in turn call `brcmf_rx_frame` to process the data.

Hmm, a question arises. Does `brcmf_usb_rx_complete` have any preconditions? Specifically, does it require the USB device to be completely initialized and in a stable state before it can execute correctly? This is something I'll need to verify, as it has implications for fuzzing coverage. I need to understand when and how those USB URBs are submitted in the driver's initialization process. I'll need to go back and examine the initialization sequence to see how the device is set up.



38/2 2026/08/01 05:52 tool grepper
0m Args:
{
  "Expression": "brcmf_usb_rx_refill",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=120=struct brcmf_usbdev_info {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-162-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:163:static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-164-\t\t\t\tstruct brcmf_usbreq  *req);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=507=static void brcmf_usb_rx_complete(struct urb *urb)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-528-\t\tbrcmf_rx_frame(devinfo-\u003edev, skb, true, true);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:529:\t\tbrcmf_usb_rx_refill(devinfo, req);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-530-\t\tusb_mark_last_busy(urb-\u003edev);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-538-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:539:static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-540-\t\t\t\tstruct brcmf_usbreq  *req)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=571=static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-579-\twhile ((req = brcmf_usb_deq(devinfo, \u0026devinfo-\u003erx_freeq, NULL)) != NULL)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:580:\t\tbrcmf_usb_rx_refill(devinfo, req);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-581-}\n"
}

39/2 2026/08/01 05:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 54848
							output: 56
							thoughts: 21
						

Thoughts:
Okay, here's my thought process laid out, as if I were considering this myself:

**Tracing the Execution Path of `brcmf_usb_rx_fill_all`**

Alright, I need to understand how `brcmf_usb_rx_fill_all` is being used. Where does it fit into the broader data flow within this Broadcom USB Wi-Fi driver? I need to quickly identify all the call sites. I'll need to use my usual tools - likely grep or some code navigation tools - to pinpoint every instance where that function is invoked. Understanding its call graph is crucial for grasping its role and potentially diagnosing any issues I might be seeing or anticipating. This quick check will give me a critical overview before I delve into the function's internal logic. Let's see what we can find.



40/2 2026/08/01 05:52 tool grepper
0m Args:
{
  "Expression": "brcmf_usb_rx_fill_all",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=539=static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-570-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:571:static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-572-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=665=static int brcmf_usb_up(struct device *dev)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-693-\t}\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:694:\tbrcmf_usb_rx_fill_all(devinfo);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-695-\treturn 0;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1498=static int brcmf_usb_resume(struct usb_interface *intf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1505-\tdevinfo-\u003ebus_pub.state = BRCMFMAC_USB_STATE_UP;\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1506:\tbrcmf_usb_rx_fill_all(devinfo);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1507-\tdevice_set_wakeup_enable(devinfo-\u003edev, false);\n"
}

41/2 2026/08/01 05:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 55659
							output: 52
							thoughts: 36
						

Thoughts:
Here's my take on the thought process, as if it were my own:

**Investigating the `brcmf_usb_up` Call Site**

Okay, so `brcmf_usb_up` is triggered when the USB bus itself is activated, which is an important hook to understand. My immediate thought is, I need to pinpoint exactly *where* that function is being called in the driver. This is crucial for tracing the initialization sequence and understanding the bus-specific setup process. I need to track down all instances of `brcmf_usb_up` to understand the conditions under which it's invoked. Let's dig in and figure out exactly how the USB interface comes to life within this framework.



42/2 2026/08/01 05:52 tool grepper
0m Args:
{
  "Expression": "brcmf_usb_up",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=608=static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-664-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:665:static int brcmf_usb_up(struct device *dev)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-666-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c=1165=static const struct brcmf_bus_ops brcmf_usb_bus_ops = {\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:1166:\t.preinit = brcmf_usb_up,\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c-1167-\t.stop = brcmf_usb_down,\n"
}

43/2 2026/08/01 05:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 56220
							output: 52
							thoughts: 808
						

Thoughts:
**Analyzing Driver Reachability with Firmware Loading and Dummy USB Devices**

Okay, let's break this down. My initial thought is that `brcmf_usb_up` is the `preinit` callback for this bus. I remember seeing earlier that `brcmf_bus_preinit` is called from `brcmf_bus_started`, which is itself called from `brcmf_attach`. Further back, `brcmf_attach` gets called from `brcmf_usb_probe_phase2`, and that's triggered after firmware loading. So, if firmware loading goes belly-up, `brcmf_usb_up` never runs. No URBs get submitted, and therefore `brcmf_usb_rx_complete` never gets invoked, which means `brcmf_netif_mon_rx` is unreachable. Simple enough.

But what about `brcmf_cfg80211_set_pmksa`? That's a cfg80211 callback, and those require the wiphy to be registered. The wiphy gets registered in `brcmf_cfg80211_attach`, which is also called from `brcmf_bus_started`. This reinforces the conclusion: if firmware loading fails, the wiphy doesn't register, and no cfg80211 callbacks are ever called. The entire driver logic is fundamentally unreachable without successful firmware loading.

Now, the interesting part. Does syzkaller actually *provide* Broadcom firmware? It usually uses generic Debian or Buildroot images. Typically, `linux-firmware` is included in those Debian images. So, there's a chance `brcmfmac` firmware *might* be present. If it *is* present, `request_firmware` should succeed. Then, `brcmf_usb_fw_download` will try to send the firmware to the dummy USB device. This dummy device will just accept the control messages, or fail depending on how the fuzzer is behaving. If the fuzzer is successful, `brcmf_usb_fw_download` completes successfully.

That's when `brcmf_attach` is called. And `brcmf_attach`, of course, calls `brcmf_bus_started`. This then triggers the calling of `brcmf_bus_preinit` (which is `brcmf_usb_up`), which submits those RX URBs. Afterward, it calls `brcmf_c_preinit_dcmds`. This sends those Broadcom-specific commands to the device and waits for the responses. Since it's a dummy device, it's not going to generate the right Broadcom-specific responses. The fuzzer would have to know *exactly* what those responses look like (e.g., the format of the `struct brcmf_dcmd` with the right status and data) to get through `brcmf_c_preinit_dcmds`. The odds of that happening by accident are infinitesimally small. If `brcmf_c_preinit_dcmds` fails, `brcmf_bus_started` fails, and `brcmf_attach` fails. If `brcmf_attach` fails, the driver gives up on initialization, and the wiphy doesn't get registered, which means no cfg80211 callbacks.

But, what about those RX URBs that got submitted in `brcmf_usb_up`? If the fuzzer manages to complete an RX URB *before* `brcmf_attach` fails, then `brcmf_usb_rx_complete` *will* be called. This, in turn, calls `brcmf_rx_frame`. Now we need to investigate how to get `brcmf_rx_frame` to eventually reach `brcmf_netif_mon_rx`.



44/2 2026/08/01 05:52 tool grepper
0m Args:
{
  "Expression": "brcmf_netif_mon_rx",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c=434=struct brcmf_radiotap_info {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-438-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c:439:void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-440-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h=220=void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h:221:void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h-222-void brcmf_net_detach(struct net_device *ndev, bool locked);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1200=brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1240-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1241:\t\tbrcmf_netif_mon_rx(ifp, skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1242-\t\treturn;\n"
}

45/2 2026/08/01 05:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 58459
							output: 52
							thoughts: 54
						

Thoughts:
Okay, let me think this through.

**PCIe and the `brcmf_netif_mon_rx` Function: A Deep Dive**

Hmm, so `brcmf_netif_mon_rx`... that function's called only from `brcmf_msgbuf_process_rx_complete`, right? And now I remember, `msgbuf.c`... that’s the module that handles the message buffer, and I'm pretty sure that's exclusive to the PCIe interface implementation. This sounds like an interesting dependency to keep in mind. I need to be absolutely certain though. I'm going to quickly cross-check that and make sure I haven't missed any potential call paths. Just a quick double-check for my own peace of mind, of course. Need to confirm that my initial analysis is spot on.



46/2 2026/08/01 05:52 tool grepper
0m Args:
{
  "Expression": "brcmf_netif_mon_rx",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c=434=struct brcmf_radiotap_info {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-438-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c:439:void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c-440-{\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h=220=void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h:221:void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h-222-void brcmf_net_detach(struct net_device *ndev, bool locked);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c=1200=brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1240-\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c:1241:\t\tbrcmf_netif_mon_rx(ifp, skb);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c-1242-\t\treturn;\n"
}

47/2 2026/08/01 05:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 59283
							output: 47
							thoughts: 794
						

Thoughts:
**Analysis of Patch Reachability**

Okay, let's break this down. First, `brcmf_netif_mon_rx` is called exclusively from `msgbuf.c`, which, as we know, is only used by PCIe. So, dead end in QEMU. Likewise, `brcmf_flowring_block` and `brcmf_msgbuf_schedule_txdata` are also in `msgbuf.c`, therefore PCIe-only. `brcmf_pcie_send_mb_data` lives in `pcie.c`, making it PCIe-specific.  `brcmf_sdio_rxglom` is tied to `sdio.c`, implying SDIO, therefore unreachable without an SDIO emulator. `brcms_c_ampdu_add_frame` is within `brcmsmac/ampdu.c` meaning BCMA only.

What about `brcmf_pmksa_v2_op`? This one is called from `brcmf_cfg80211_set_pmksa`, a cfg80211 callback. Registering the wiphy requires `brcmf_c_preinit_dcmds` which, considering the need for a dedicated firmware emulator, is effectively impossible for a fuzzer. So, those cfg80211 callbacks are out.

So, all the modified code paths are confined to:

1.  PCIe-specific code (unreachable in QEMU).
2.  SDIO-specific code (unreachable in QEMU).
3.  BCMA-specific code (unreachable in QEMU).
4.  cfg80211 callbacks within a FullMAC driver that cannot be initialized without a dedicated firmware emulator (unreachable in QEMU).

I need to quickly rule out a chance that Syzkaller could emulate the required hardware.  No PCIe Broadcom emulation? No SDIO either? And definitely no BCMA? Okay, that confirms it.

Therefore, since all these paths are blocked by their hardware dependencies (PCIe, SDIO, BCMA) or a complex firmware dependency, and QEMU doesn't emulate the necessary hardware, they are impossible to reach in QEMU.  The prompt explicitly excludes patches with this characteristic.  The patch modifies `brcmfmac` and `brcmsmac`, which are vendor-specific Wi-Fi drivers that would require specific firmware emulation. This isn't possible in standard QEMU.

Hold on, I should check whether `mac80211_hwsim` can reach `brcmsmac`. Ah, it's a `mac80211` driver! But the question is how it interacts. Looking at `brcmsmac/mac80211_if.c` now...

Considering all this, this patch is **not** worth fuzzing.



48/2 2026/08/01 05:52 tool grepper
0m Args:
{
  "Expression": "mac80211",
  "PathPrefix": "drivers/net/wireless/broadcom/brcm80211/brcmsmac/"
}

Results:
{
  "Output": "drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile=23=brcmsmac-y := \\\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile:24:\tmac80211_if.o \\\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile-25-\tucode_loader.o \\\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c-15- */\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c:16:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c-17-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c-17-#include \u003clinux/slab.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c:18:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c-19-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_events.c-19-#ifndef __CHECKER__\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_events.c:20:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_events.c-21-#define CREATE_TRACE_POINTS\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_events.h-22-#include \u003clinux/tracepoint.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_events.h:23:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_events.h-24-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c-18-#include \u003cnet/cfg80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c:19:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c-20-#include \u003cnet/regulatory.h\u003e\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c-27-#include \"channel.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c:28:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c-29-#include \"debug.h\"\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c-23-#include \u003clinux/module.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c:24:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c-25-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h-22-#include \u003cnet/cfg80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h:23:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h-24-#include \"main.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h:25:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h-26-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h=42=void __brcms_dbg(struct device *dev, u32 level, const char *func,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h-60-#define brcms_dbg_info(core, f, a...)\t\tbrcms_dbg(core, BRCM_DL_INFO, f, ##a)\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h:61:#define brcms_dbg_mac80211(core, f, a...)\tbrcms_dbg(core, BRCM_DL_MAC80211, f, ##a)\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.h-62-#define brcms_dbg_rx(core, f, a...)\t\tbrcms_dbg(core, BRCM_DL_RX, f, ##a)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c-20-#include \u003cnet/cfg80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c:21:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c-22-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c-1-// SPDX-License-Identifier: GPL-2.0\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c:2:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c-3-#include \u003clinux/bcma/bcma_driver_chipcommon.h\u003e\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c-7-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c:8:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c-9-#include \"pub.h\"\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-27-#include \u003clinux/string_choices.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:28:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-29-#include \u003cdefs.h\u003e\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-35-#include \"ucode_loader.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:36:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-37-#include \"main.h\"\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-40-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:41:#define N_TX_QUEUES\t4 /* #tx queues on mac80211\u003c-\u003edriver interface */\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-42-#define BRCMS_FLUSH_TIMEOUT\t500 /* msec */\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c=402=static void brcms_ops_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-414-\t}\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:415:\tif (brcms_c_sendpkt_mac80211(wl-\u003ewlc, skb, hw))\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-416-\t\ttx_info-\u003erate_driver_data[0] = control-\u003esta;\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c=906=static void brcms_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-917-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:918:\tbrcms_dbg_mac80211(wl-\u003ewlc-\u003ehw-\u003ed11core,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c-919-\t\t\t   \"ret=%d\\n\", jiffies_to_msecs(ret));\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-22-#include \u003cnet/cfg80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:23:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-24-#include \u003cbrcm_hw_ids.h\u003e\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-33-#include \"ampdu.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:34:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-35-#include \"ucode_loader.h\"\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=747=static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-748-{\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:749:\tbrcms_dbg_mac80211(wlc_hw-\u003ed11core, \"wl%d: bandunit %d\\n\", wlc_hw-\u003eunit,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-750-\t\t\t   bandunit);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=772=static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-777-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:778:\tbrcms_dbg_mac80211(wlc_hw-\u003ed11core, \"wl%d\\n\", wlc_hw-\u003eunit);\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-779-\tmacctrl = bcma_read32(wlc_hw-\u003ed11core,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=1659=static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-1662-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:1663:\tbrcms_dbg_mac80211(wlc_hw-\u003ed11core, \"wl%d: bandunit %d\\n\", wlc_hw-\u003eunit,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-1664-\t\t\t   wlc_hw-\u003eband-\u003ebandunit);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=2594=void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-2599-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:2600:\tbrcms_dbg_mac80211(core, \"wl%d: bandunit %d\\n\", wlc_hw-\u003eunit,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-2601-\t\t\t   wlc_hw-\u003eband-\u003ebandunit);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=2662=void brcms_c_enable_mac(struct brcms_c_info *wlc)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-2667-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:2668:\tbrcms_dbg_mac80211(core, \"wl%d: bandunit %d\\n\", wlc_hw-\u003eunit,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-2669-\t\t\t   wlc-\u003eband-\u003ebandunit);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=3697=static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-3704-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:3705:\tbrcms_dbg_mac80211(wlc-\u003ehw-\u003ed11core, \"wl%d: hps %d\\n\", wlc-\u003epub-\u003eunit,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-3706-\t\t\t   hps);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=3793=brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-3797-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:3798:\tbrcms_dbg_mac80211(wlc_hw-\u003ed11core, \"wl%d: 0x%x\\n\", wlc_hw-\u003eunit,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-3799-\t\t\t   chanspec);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=5798=static u32\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:5799:mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-5800-\t\t       u32 int_val)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-5835-\t\t\tif (stf != PHY_TXC1_MODE_SDM) {\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:5836:\t\t\t\tbrcms_dbg_mac80211(core, \"wl%d: enabling \"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-5837-\t\t\t\t\t\t   \"SDM mode for mcs %d\\n\",\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=6123=static u16\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6124:brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6125-\t\t     struct sk_buff *p, struct scb *scb, uint frag,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6227-\t\t} else {\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6228:\t\t\trspec[k] = mac80211_wlc_set_nrate(wlc, wlc-\u003eband,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6229-\t\t\t\t\tNRATE_MCS_INUSE | txrate[k]-\u003eidx);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=6761=static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6773-\t\t/*\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6774:\t\t * We sometimes get a frame from mac80211 after stopping\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6775-\t\t * the queues. This only ever seems to be a single frame\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6814-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6815:bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6816-\t\t\t      struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6821-\tfifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6822:\tbrcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6823-\tif (!brcms_c_tx(wlc, sdu))\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=6832=brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p)\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6843-\t * Stop queue if DMA ring is full. Reserve some free descriptors,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6844:\t * as we sometimes receive a frame from mac80211 after the queues\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6845-\t * are stopped.\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=6962=static void\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:6963:prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-6964-\t\t     struct sk_buff *p,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-7042-\t\t * a subset of the 2.4G rates. See bitrates field\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:7043:\t\t * of brcms_band_5GHz_nphy (in mac80211_if.c).\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-7044-\t\t */\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c=7076=brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-7083-\tmemset(\u0026rx_status, 0, sizeof(rx_status));\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c:7084:\tprep_mac80211_status(wlc, rxh, p, \u0026rx_status);\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c-7085-\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c-24-#include \u003clinux/slab.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c:25:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c-26-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c-27-#include \"main.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c:28:#include \"mac80211_if.h\"\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c-29-#include \"phy_shim.h\"\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h=144=struct brcms_pub {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h-147-\tstruct scb_ampdu *global_ampdu;\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h:148:\tuint mac80211_state;\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h-149-\tuint unit;\t\t/* device instance number */\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h=285=bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h:286:bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/pub.h-287-\t\t\t      struct ieee80211_hw *hw);\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/scb.h=43=struct scb_ampdu {\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/scb.h-49-\t * This could easily be a ini[] pointer and we keep this info in wl\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/scb.h:50:\t * itself instead of having mac80211 hold it for us. Also could be made\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/scb.h-51-\t * dynamic per tid instead of static.\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c-16-\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c:17:#include \u003cnet/mac80211.h\u003e\ndrivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c-18-\n"
}

49/2 2026/08/01 05:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 67651
							output: 150
							thoughts: 619
						

Thoughts:
**My Assessment: Patch Unfuzzable in Current Environment**

Okay, so I've got this patch affecting the Broadcom Wi-Fi drivers, specifically `brcmfmac` and `brcmsmac`. My initial thought is that these are *definitely* going to be problematic in a virtualized fuzzing environment, and after walking through the reasoning, I'm pretty confident about my assessment.

First off, `brcmsmac` is a `mac80211` driver, but it's *not* the software simulator `mac80211_hwsim`. That's important. It needs actual Broadcom hardware connected via the BCMA bus. There's no BCMA emulation in QEMU, so that code path is unreachable. That takes `brcmsmac` off the table.

Then there's `brcmfmac`. This is a FullMAC driver and is even trickier. It requires either the physical Broadcom hardware or an incredibly complex USB firmware emulation. While it supports USB, simply throwing random data at it isn't going to work. The firmware handshake is notoriously complex, and it won't be possible to get through this with only random data. This is even more unlikely to be fuzzable, and is virtually impossible without a dedicated firmware emulator.

So, according to the prompt, I need to check if the patch only contains code that's unreachable in QEMU. Check! This patch is only in vendor-specific wireless drivers that require real hardware. In QEMU, there is no way to reach the target driver code, meaning it's impossible to fuzz. Given this, and the fact that the changes are only in those Broadcom drivers, I am going to return `WorthFuzzing=false`. The fuzzing effort is going to be wasted.

I quickly double checked the patch content again to be sure, and yep, it's just `drivers/net/wireless/broadcom/brcm80211/`.

I'm ready to move on. Let's use the `set-results` tool and close this one out.



50/2 2026/08/01 05:52 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the brcmfmac and brcmsmac Broadcom wireless drivers. These are vendor-specific drivers that require physical Broadcom Wi-Fi hardware (PCIe, SDIO, or BCMA) to initialize and function. While brcmfmac supports USB, reaching the modified data paths (RX/TX) and cfg80211 callbacks requires passing a complex firmware loading and initialization handshake, which is impossible to achieve via random USB gadget fuzzing without a dedicated firmware emulator. Therefore, the modified code paths are unreachable in standard virtualized environments like QEMU.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the brcmfmac and brcmsmac Broadcom wireless drivers. These are vendor-specific drivers that require physical Broadcom Wi-Fi hardware (PCIe, SDIO, or BCMA) to initialize and function. While brcmfmac supports USB, reaching the modified data paths (RX/TX) and cfg80211 callbacks requires passing a complex firmware loading and initialization handshake, which is impossible to achieve via random USB gadget fuzzing without a dedicated firmware emulator. Therefore, the modified code paths are unreachable in standard virtualized environments like QEMU.",
  "WorthFuzzing": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)