AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/27 06:39 flow patch-triage
4m Args:
null

Results:
{
  "EnableConfigs": [
    "MM81X_USB",
    "MAC80211"
  ],
  "FocusSymbols": [
    "mm81x_mac_ops_sta_state",
    "mm81x_mac_ops_tx_frames_pending",
    "mm81x_mac_beacon_work"
  ],
  "KMSANReasoning": "The patch modifies the mm81x wireless driver to limit TX bandwidth based on the station's maximum RX bandwidth, send buffered broadcast frames after a DTIM beacon, and implement the tx_frames_pending callback. All newly introduced local structures (e.g., `struct ieee80211_tx_control control` and `struct mm81x_skb_tx_info tx_info`) are explicitly zero-initialized using `{ 0 }`. The `max_rx_bw_mhz` field added to `struct mm81x_sta` is initialized from the mac80211 station capabilities during association. The patch does not introduce any new kernel-to-user copies, nor does it add complex data structures that could be partially uninitialized. There is no risk of uninitialized memory being used in control flow or leaked to userspace. Standard KASAN and other bug detectors are sufficient to catch any potential memory corruption or out-of-bounds access.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch makes functional changes to the Morse Micro MM81x wireless driver's MAC operations, including TX bandwidth calculation, broadcast frame buffering in AP mode, and power save filtering. The driver supports a USB interface (CONFIG_MM81X_USB) which can be reached and fuzzed in virtualized environments via USB emulation.",
  "WorthFuzzing": true
}

1/1 2026/08/27 06:39 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 0e95e0c8e04da9de175f2e9e3a17de18198ef59a\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Aug 27 06:39:53 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/morsemicro/mm81x/core.h b/drivers/net/wireless/morsemicro/mm81x/core.h\nindex 2fd4b4786e777..75e998e8e3241 100644\n--- a/drivers/net/wireless/morsemicro/mm81x/core.h\n+++ b/drivers/net/wireless/morsemicro/mm81x/core.h\n@@ -192,7 +192,12 @@ struct mm81x_sta {\n \tbool tid_tx[IEEE80211_NUM_TIDS];\n \tbool tid_start_tx[IEEE80211_NUM_TIDS];\n \tu8 tid_params[IEEE80211_NUM_TIDS];\n-\tint max_bw_mhz;\n+\n+\t/*\n+\t * We really should be using link_sta::bandwidth but\n+\t * that requires non-trivial work.\n+\t */\n+\tint max_rx_bw_mhz;\n \tstruct mm81x_rc_sta rc;\n \tstruct mmrc_rate last_sta_tx_rate;\n \ts16 avg_rssi;\ndiff --git a/drivers/net/wireless/morsemicro/mm81x/mac.c b/drivers/net/wireless/morsemicro/mm81x/mac.c\nindex 08ca116a68b47..4485748518b4a 100644\n--- a/drivers/net/wireless/morsemicro/mm81x/mac.c\n+++ b/drivers/net/wireless/morsemicro/mm81x/mac.c\n@@ -66,6 +66,9 @@\n /* HW restart delay time before terminating hardware IF work items */\n #define MM81X_HW_RESTART_DELAY_MS 20\n \n+/* Maximum number of multicast frames to release after a DTIM beacon */\n+#define MM81X_MAX_MC_FRAMES_AFTER_DTIM 4\n+\n /* clang-format off */\n \n /* mm81x chips do not support 16MHz */\n@@ -322,7 +325,7 @@ static int mm81x_mac_ops_start(struct ieee80211_hw *hw)\n \treturn 0;\n }\n \n-static int mm81x_tx_h_get_max_bw(struct mm81x *mors)\n+static int mm81x_tx_h_get_max_tx_bw(struct mm81x *mors)\n {\n \treturn MM81X_FW_SUPP(\u0026mors-\u003efw_caps, 8MHZ) ? 8 :\n \t       MM81X_FW_SUPP(\u0026mors-\u003efw_caps, 4MHZ) ? 4 :\n@@ -445,39 +448,6 @@ static void mm81x_beacon_h_fill_tx_info(struct mm81x *mors,\n \t\t\tcpu_to_le32(MM81X_TX_CONF_FLAGS_IMMEDIATE_REPORT);\n }\n \n-static void mm81x_mac_beacon_work(struct work_struct *work)\n-{\n-\tstruct mm81x_vif *mors_vif =\n-\t\tfrom_work(mors_vif, work, u.ap.beacon_work);\n-\tstruct mm81x *mors = mm81x_vif_to_mors(mors_vif);\n-\tstruct mm81x_skbq *mq;\n-\tstruct sk_buff *beacon;\n-\tstruct ieee80211_vif *vif = mm81x_vif_to_ieee80211_vif(mors_vif);\n-\tstruct mm81x_skb_tx_info tx_info = { 0 };\n-\tint num_bcn_vifs = atomic_read(\u0026mors-\u003enum_bcn_vifs);\n-\n-\tmq = mm81x_hif_get_tx_beacon_queue(mors);\n-\tif (!mq) {\n-\t\tdev_err(mors-\u003edev, \"no matching beacon Q found\");\n-\t\treturn;\n-\t}\n-\n-\tif (mm81x_skbq_count(mq) \u003e= num_bcn_vifs) {\n-\t\tdev_err(mors-\u003edev,\n-\t\t\t\"previous beacon not consumed, dropping req [id:%d]\",\n-\t\t\tmors_vif-\u003eid);\n-\t\treturn;\n-\t}\n-\n-\tbeacon = ieee80211_beacon_get(mors-\u003ehw, vif, false);\n-\tif (!beacon)\n-\t\treturn;\n-\n-\tmm81x_beacon_h_fill_tx_info(mors, \u0026tx_info, mors_vif,\n-\t\t\t\t    cfg80211_chandef_s1g_pri_width(\u0026mors-\u003echandef));\n-\tmm81x_skbq_skb_tx(mq, \u0026beacon, \u0026tx_info, MM81X_SKB_CHAN_BEACON);\n-}\n-\n void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)\n {\n \tint vif_id;\n@@ -497,15 +467,6 @@ void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)\n \t}\n }\n \n-static void mm81x_mac_beacon_init(struct mm81x_vif *mors_vif)\n-{\n-\tstruct mm81x *mors = mm81x_vif_to_mors(mors_vif);\n-\n-\tINIT_WORK(\u0026mors_vif-\u003eu.ap.beacon_work, mm81x_mac_beacon_work);\n-\tmm81x_mac_beacon_irq_enable(mors_vif, true);\n-\tatomic_inc(\u0026mors-\u003enum_bcn_vifs);\n-}\n-\n static struct hw_scan_tlv_hdr mm81x_hw_scan_h_pack_tlv_hdr(u16 tag, u16 len)\n {\n \tstruct hw_scan_tlv_hdr hdr = { .tag = cpu_to_le16(tag),\n@@ -1282,38 +1243,54 @@ static void mm81x_tx_h_fill_info(struct mm81x *mors,\n \t}\n }\n \n+static int mm81x_tx_h_get_bw(struct mm81x *mors, struct ieee80211_sta *sta,\n+\t\t\t     struct sk_buff *skb, bool is_mgmt)\n+{\n+\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n+\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n+\tstruct mm81x_sta *mors_sta = NULL;\n+\tint tx_bw_mhz;\n+\n+\tif (ieee80211_is_probe_resp(hdr-\u003eframe_control))\n+\t\treturn 1;\n+\n+\tif (is_mgmt || info-\u003econtrol.flags \u0026 IEEE80211_TX_CTRL_PORT_CTRL_PROTO)\n+\t\treturn cfg80211_chandef_s1g_pri_width(\u0026mors-\u003echandef);\n+\n+\t/*\n+\t * In AP mode group addressed frames go out at the primary width so\n+\t * that every associated STA can receive them, including any that\n+\t * cannot support the operating width.\n+\t */\n+\tif (info-\u003econtrol.vif-\u003etype == NL80211_IFTYPE_AP \u0026\u0026\n+\t    is_multicast_ether_addr(ieee80211_get_DA(hdr)))\n+\t\treturn cfg80211_chandef_s1g_pri_width(\u0026mors-\u003echandef);\n+\n+\tif (sta)\n+\t\tmors_sta = (struct mm81x_sta *)sta-\u003edrv_priv;\n+\n+\ttx_bw_mhz = min(mm81x_tx_h_get_max_tx_bw(mors),\n+\t\t\tcfg80211_chandef_get_width(\u0026mors-\u003echandef));\n+\tif (mors_sta \u0026\u0026 mors_sta-\u003emax_rx_bw_mhz)\n+\t\ttx_bw_mhz = min(tx_bw_mhz, mors_sta-\u003emax_rx_bw_mhz);\n+\n+\treturn tx_bw_mhz;\n+}\n+\n static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,\n \t\t\t     struct ieee80211_tx_control *control,\n \t\t\t     struct sk_buff *skb)\n {\n-\tstruct mm81x *mors = hw-\u003epriv;\n-\tstruct mm81x_skbq *mq = NULL;\n-\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n-\tstruct ieee80211_vif *vif = info-\u003econtrol.vif;\n-\tstruct mm81x_skb_tx_info tx_info = { 0 };\n \tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n+\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n \tbool is_mgmt = ieee80211_is_mgmt(hdr-\u003eframe_control);\n-\tint tx_bw_mhz = cfg80211_chandef_get_width(\u0026mors-\u003echandef);\n \tstruct ieee80211_sta *sta = control-\u003esta;\n-\tint max_tx_bw = 0, sta_max_bw_mhz = 0;\n-\n-\tif (sta) {\n-\t\tstruct mm81x_sta *mors_sta = (struct mm81x_sta *)sta-\u003edrv_priv;\n-\n-\t\tsta_max_bw_mhz = mors_sta-\u003emax_bw_mhz;\n-\t}\n-\n-\tmax_tx_bw = mm81x_tx_h_get_max_bw(mors);\n-\ttx_bw_mhz = min(max_tx_bw, tx_bw_mhz);\n-\n-\tif (is_mgmt)\n-\t\ttx_bw_mhz = cfg80211_chandef_s1g_pri_width(\u0026mors-\u003echandef);\n-\tif (sta_max_bw_mhz)\n-\t\ttx_bw_mhz = min(tx_bw_mhz, sta_max_bw_mhz);\n-\tif (ieee80211_is_probe_resp(hdr-\u003eframe_control))\n-\t\ttx_bw_mhz = 1;\n+\tstruct mm81x_skb_tx_info tx_info = { 0 };\n+\tstruct mm81x *mors = hw-\u003epriv;\n+\tstruct mm81x_skbq *mq;\n \n-\tmm81x_tx_h_fill_info(mors, \u0026tx_info, skb, vif, tx_bw_mhz, sta);\n+\tmm81x_tx_h_fill_info(mors, \u0026tx_info, skb, info-\u003econtrol.vif,\n+\t\t\t     mm81x_tx_h_get_bw(mors, sta, skb, is_mgmt), sta);\n \n \tif (mm81x_tx_h_ps_filtered_for_sta(mors, skb, sta))\n \t\treturn;\n@@ -1329,6 +1306,65 @@ static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,\n \t\t\t\t      MM81X_SKB_CHAN_DATA);\n }\n \n+static void mm81x_mac_send_buffered_bc(struct mm81x *mors,\n+\t\t\t\t       struct ieee80211_vif *vif)\n+{\n+\tint count = MM81X_MAX_MC_FRAMES_AFTER_DTIM;\n+\tstruct ieee80211_tx_control control = { 0 };\n+\tstruct sk_buff *bc_frame;\n+\n+\twhile (count-- \u0026\u0026\n+\t       (bc_frame = ieee80211_get_buffered_bc(mors-\u003ehw, vif))) {\n+\t\tIEEE80211_SKB_CB(bc_frame)-\u003econtrol.vif = vif;\n+\t\tmm81x_mac_ops_tx(mors-\u003ehw, \u0026control, bc_frame);\n+\t}\n+}\n+\n+static void mm81x_mac_beacon_work(struct work_struct *work)\n+{\n+\tstruct mm81x_vif *mors_vif =\n+\t\tfrom_work(mors_vif, work, u.ap.beacon_work);\n+\tstruct mm81x *mors = mm81x_vif_to_mors(mors_vif);\n+\tstruct mm81x_skbq *mq;\n+\tstruct sk_buff *beacon;\n+\tstruct ieee80211_vif *vif = mm81x_vif_to_ieee80211_vif(mors_vif);\n+\tstruct mm81x_skb_tx_info tx_info = { 0 };\n+\tint num_bcn_vifs = atomic_read(\u0026mors-\u003enum_bcn_vifs);\n+\n+\tmq = mm81x_hif_get_tx_beacon_queue(mors);\n+\tif (!mq) {\n+\t\tdev_err(mors-\u003edev, \"no matching beacon Q found\");\n+\t\treturn;\n+\t}\n+\n+\tif (mm81x_skbq_count(mq) \u003e= num_bcn_vifs) {\n+\t\tdev_err(mors-\u003edev,\n+\t\t\t\"previous beacon not consumed, dropping req [id:%d]\",\n+\t\t\tmors_vif-\u003eid);\n+\t\treturn;\n+\t}\n+\n+\tbeacon = ieee80211_beacon_get(mors-\u003ehw, vif, false);\n+\tif (!beacon)\n+\t\treturn;\n+\n+\tmm81x_beacon_h_fill_tx_info(mors, \u0026tx_info, mors_vif,\n+\t\t\t\t    cfg80211_chandef_s1g_pri_width(\u0026mors-\u003echandef));\n+\tmm81x_skbq_skb_tx(mq, \u0026beacon, \u0026tx_info, MM81X_SKB_CHAN_BEACON);\n+\n+\tif (!test_bit(MM81X_STATE_DATA_QS_STOPPED, \u0026mors-\u003estate_flags))\n+\t\tmm81x_mac_send_buffered_bc(mors, vif);\n+}\n+\n+static void mm81x_mac_beacon_init(struct mm81x_vif *mors_vif)\n+{\n+\tstruct mm81x *mors = mm81x_vif_to_mors(mors_vif);\n+\n+\tINIT_WORK(\u0026mors_vif-\u003eu.ap.beacon_work, mm81x_mac_beacon_work);\n+\tmm81x_mac_beacon_irq_enable(mors_vif, true);\n+\tatomic_inc(\u0026mors-\u003enum_bcn_vifs);\n+}\n+\n static void mm81x_mac_ops_stop(struct ieee80211_hw *hw, bool suspend)\n {\n \tstruct mm81x *mors = hw-\u003epriv;\n@@ -1691,6 +1727,9 @@ static int mm81x_mac_ops_sta_state(struct ieee80211_hw *hw,\n \t\t\tmors_vif-\u003eu.ap.num_stas++;\n \t\telse if (vif-\u003etype == NL80211_IFTYPE_STATION)\n \t\t\tmors_vif-\u003eu.sta.is_assoc = true;\n+\n+\t\tmors_sta-\u003emax_rx_bw_mhz =\n+\t\t\tS1G_SUPP_CH_WIDTH_MAX(sta-\u003edeflink.s1g_cap.cap);\n \t}\n \n \tif (new_state \u003c old_state \u0026\u0026 new_state == IEEE80211_STA_NONE) {\n@@ -2015,6 +2054,13 @@ static void mm81x_mac_ops_flush(struct ieee80211_hw *hw,\n \t\tmm81x_mac_wait_queues(mors);\n }\n \n+static bool mm81x_mac_ops_tx_frames_pending(struct ieee80211_hw *hw)\n+{\n+\tstruct mm81x *mors = hw-\u003epriv;\n+\n+\treturn mm81x_mac_has_tx_pending(mors);\n+}\n+\n static int mm81x_mac_ops_set_rts_threshold(struct ieee80211_hw *hw,\n \t\t\t\t\t   int radio_idx, u32 value)\n {\n@@ -2240,6 +2286,7 @@ static const struct ieee80211_ops mm81x_ops = {\n \t.configure_filter = mm81x_mac_ops_configure_filter,\n \t.sta_state = mm81x_mac_ops_sta_state,\n \t.flush = mm81x_mac_ops_flush,\n+\t.tx_frames_pending = mm81x_mac_ops_tx_frames_pending,\n \t.set_frag_threshold = mm81x_mac_set_frag_threshold,\n \t.set_rts_threshold = mm81x_mac_ops_set_rts_threshold,\n \t.sta_statistics = mm81x_mac_ops_sta_statistics,\ndiff --git a/drivers/net/wireless/morsemicro/mm81x/skbq.c b/drivers/net/wireless/morsemicro/mm81x/skbq.c\nindex 25655bd56d140..3bf15e7c38d80 100644\n--- a/drivers/net/wireless/morsemicro/mm81x/skbq.c\n+++ b/drivers/net/wireless/morsemicro/mm81x/skbq.c\n@@ -231,10 +231,9 @@ static bool mm81x_tx_h_is_ps_filtered(struct mm81x_skbq *mq,\n \tWARN_ON_ONCE(!(le32_to_cpu(tx_sts-\u003eflags) \u0026\n \t\t       MM81X_TX_STATUS_FLAGS_PS_FILTERED));\n \n-\tif (vif-\u003etype == NL80211_IFTYPE_AP) {\n-\t\t__mm81x_skbq_drop_pending_skb(mq, skb);\n-\t\treturn true;\n-\t}\n+\t/* mac80211 buffers frames in AP mode */\n+\tif (vif-\u003etype == NL80211_IFTYPE_AP)\n+\t\treturn false;\n \n \tif (vif-\u003etype == NL80211_IFTYPE_STATION) {\n \t\tmm81x_skbq_insert_pending(mq, skb, tx_sts-\u003epkt_id);\n"
}

2/1 2026/08/27 06:39 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "MM81X_USB",
    "MAC80211"
  ],
  "FocusSymbols": [
    "mm81x_mac_ops_sta_state",
    "mm81x_mac_ops_tx_frames_pending",
    "mm81x_mac_beacon_work"
  ],
  "Reasoning": "The patch makes functional changes to the Morse Micro MM81x wireless driver's MAC operations, including TX bandwidth calculation, broadcast frame buffering in AP mode, and power save filtering. The driver supports a USB interface (CONFIG_MM81X_USB) which can be reached and fuzzed in virtualized environments via USB emulation.",
  "WorthFuzzing": true
}

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 0e95e0c8e04da9de175f2e9e3a17de18198ef59a
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Aug 27 06:39:53 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/morsemicro/mm81x/core.h b/drivers/net/wireless/morsemicro/mm81x/core.h
index 2fd4b4786e777..75e998e8e3241 100644
--- a/drivers/net/wireless/morsemicro/mm81x/core.h
+++ b/drivers/net/wireless/morsemicro/mm81x/core.h
@@ -192,7 +192,12 @@ struct mm81x_sta {
 	bool tid_tx[IEEE80211_NUM_TIDS];
 	bool tid_start_tx[IEEE80211_NUM_TIDS];
 	u8 tid_params[IEEE80211_NUM_TIDS];
-	int max_bw_mhz;
+
+	/*
+	 * We really should be using link_sta::bandwidth but
+	 * that requires non-trivial work.
+	 */
+	int max_rx_bw_mhz;
 	struct mm81x_rc_sta rc;
 	struct mmrc_rate last_sta_tx_rate;
 	s16 avg_rssi;
diff --git a/drivers/net/wireless/morsemicro/mm81x/mac.c b/drivers/net/wireless/morsemicro/mm81x/mac.c
index 08ca116a68b47..4485748518b4a 100644
--- a/drivers/net/wireless/morsemicro/mm81x/mac.c
+++ b/drivers/net/wireless/morsemicro/mm81x/mac.c
@@ -66,6 +66,9 @@
 /* HW restart delay time before terminating hardware IF work items */
 #define MM81X_HW_RESTART_DELAY_MS 20
 
+/* Maximum number of multicast frames to release after a DTIM beacon */
+#define MM81X_MAX_MC_FRAMES_AFTER_DTIM 4
+
 /* clang-format off */
 
 /* mm81x chips do not support 16MHz */
@@ -322,7 +325,7 @@ static int mm81x_mac_ops_start(struct ieee80211_hw *hw)
 	return 0;
 }
 
-static int mm81x_tx_h_get_max_bw(struct mm81x *mors)
+static int mm81x_tx_h_get_max_tx_bw(struct mm81x *mors)
 {
 	return MM81X_FW_SUPP(&mors->fw_caps, 8MHZ) ? 8 :
 	       MM81X_FW_SUPP(&mors->fw_caps, 4MHZ) ? 4 :
@@ -445,39 +448,6 @@ static void mm81x_beacon_h_fill_tx_info(struct mm81x *mors,
 			cpu_to_le32(MM81X_TX_CONF_FLAGS_IMMEDIATE_REPORT);
 }
 
-static void mm81x_mac_beacon_work(struct work_struct *work)
-{
-	struct mm81x_vif *mors_vif =
-		from_work(mors_vif, work, u.ap.beacon_work);
-	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
-	struct mm81x_skbq *mq;
-	struct sk_buff *beacon;
-	struct ieee80211_vif *vif = mm81x_vif_to_ieee80211_vif(mors_vif);
-	struct mm81x_skb_tx_info tx_info = { 0 };
-	int num_bcn_vifs = atomic_read(&mors->num_bcn_vifs);
-
-	mq = mm81x_hif_get_tx_beacon_queue(mors);
-	if (!mq) {
-		dev_err(mors->dev, "no matching beacon Q found");
-		return;
-	}
-
-	if (mm81x_skbq_count(mq) >= num_bcn_vifs) {
-		dev_err(mors->dev,
-			"previous beacon not consumed, dropping req [id:%d]",
-			mors_vif->id);
-		return;
-	}
-
-	beacon = ieee80211_beacon_get(mors->hw, vif, false);
-	if (!beacon)
-		return;
-
-	mm81x_beacon_h_fill_tx_info(mors, &tx_info, mors_vif,
-				    cfg80211_chandef_s1g_pri_width(&mors->chandef));
-	mm81x_skbq_skb_tx(mq, &beacon, &tx_info, MM81X_SKB_CHAN_BEACON);
-}
-
 void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)
 {
 	int vif_id;
@@ -497,15 +467,6 @@ void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)
 	}
 }
 
-static void mm81x_mac_beacon_init(struct mm81x_vif *mors_vif)
-{
-	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
-
-	INIT_WORK(&mors_vif->u.ap.beacon_work, mm81x_mac_beacon_work);
-	mm81x_mac_beacon_irq_enable(mors_vif, true);
-	atomic_inc(&mors->num_bcn_vifs);
-}
-
 static struct hw_scan_tlv_hdr mm81x_hw_scan_h_pack_tlv_hdr(u16 tag, u16 len)
 {
 	struct hw_scan_tlv_hdr hdr = { .tag = cpu_to_le16(tag),
@@ -1282,38 +1243,54 @@ static void mm81x_tx_h_fill_info(struct mm81x *mors,
 	}
 }
 
+static int mm81x_tx_h_get_bw(struct mm81x *mors, struct ieee80211_sta *sta,
+			     struct sk_buff *skb, bool is_mgmt)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct mm81x_sta *mors_sta = NULL;
+	int tx_bw_mhz;
+
+	if (ieee80211_is_probe_resp(hdr->frame_control))
+		return 1;
+
+	if (is_mgmt || info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
+		return cfg80211_chandef_s1g_pri_width(&mors->chandef);
+
+	/*
+	 * In AP mode group addressed frames go out at the primary width so
+	 * that every associated STA can receive them, including any that
+	 * cannot support the operating width.
+	 */
+	if (info->control.vif->type == NL80211_IFTYPE_AP &&
+	    is_multicast_ether_addr(ieee80211_get_DA(hdr)))
+		return cfg80211_chandef_s1g_pri_width(&mors->chandef);
+
+	if (sta)
+		mors_sta = (struct mm81x_sta *)sta->drv_priv;
+
+	tx_bw_mhz = min(mm81x_tx_h_get_max_tx_bw(mors),
+			cfg80211_chandef_get_width(&mors->chandef));
+	if (mors_sta && mors_sta->max_rx_bw_mhz)
+		tx_bw_mhz = min(tx_bw_mhz, mors_sta->max_rx_bw_mhz);
+
+	return tx_bw_mhz;
+}
+
 static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,
 			     struct ieee80211_tx_control *control,
 			     struct sk_buff *skb)
 {
-	struct mm81x *mors = hw->priv;
-	struct mm81x_skbq *mq = NULL;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_vif *vif = info->control.vif;
-	struct mm81x_skb_tx_info tx_info = { 0 };
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	bool is_mgmt = ieee80211_is_mgmt(hdr->frame_control);
-	int tx_bw_mhz = cfg80211_chandef_get_width(&mors->chandef);
 	struct ieee80211_sta *sta = control->sta;
-	int max_tx_bw = 0, sta_max_bw_mhz = 0;
-
-	if (sta) {
-		struct mm81x_sta *mors_sta = (struct mm81x_sta *)sta->drv_priv;
-
-		sta_max_bw_mhz = mors_sta->max_bw_mhz;
-	}
-
-	max_tx_bw = mm81x_tx_h_get_max_bw(mors);
-	tx_bw_mhz = min(max_tx_bw, tx_bw_mhz);
-
-	if (is_mgmt)
-		tx_bw_mhz = cfg80211_chandef_s1g_pri_width(&mors->chandef);
-	if (sta_max_bw_mhz)
-		tx_bw_mhz = min(tx_bw_mhz, sta_max_bw_mhz);
-	if (ieee80211_is_probe_resp(hdr->frame_control))
-		tx_bw_mhz = 1;
+	struct mm81x_skb_tx_info tx_info = { 0 };
+	struct mm81x *mors = hw->priv;
+	struct mm81x_skbq *mq;
 
-	mm81x_tx_h_fill_info(mors, &tx_info, skb, vif, tx_bw_mhz, sta);
+	mm81x_tx_h_fill_info(mors, &tx_info, skb, info->control.vif,
+			     mm81x_tx_h_get_bw(mors, sta, skb, is_mgmt), sta);
 
 	if (mm81x_tx_h_ps_filtered_for_sta(mors, skb, sta))
 		return;
@@ -1329,6 +1306,65 @@ static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,
 				      MM81X_SKB_CHAN_DATA);
 }
 
+static void mm81x_mac_send_buffered_bc(struct mm81x *mors,
+				       struct ieee80211_vif *vif)
+{
+	int count = MM81X_MAX_MC_FRAMES_AFTER_DTIM;
+	struct ieee80211_tx_control control = { 0 };
+	struct sk_buff *bc_frame;
+
+	while (count-- &&
+	       (bc_frame = ieee80211_get_buffered_bc(mors->hw, vif))) {
+		IEEE80211_SKB_CB(bc_frame)->control.vif = vif;
+		mm81x_mac_ops_tx(mors->hw, &control, bc_frame);
+	}
+}
+
+static void mm81x_mac_beacon_work(struct work_struct *work)
+{
+	struct mm81x_vif *mors_vif =
+		from_work(mors_vif, work, u.ap.beacon_work);
+	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
+	struct mm81x_skbq *mq;
+	struct sk_buff *beacon;
+	struct ieee80211_vif *vif = mm81x_vif_to_ieee80211_vif(mors_vif);
+	struct mm81x_skb_tx_info tx_info = { 0 };
+	int num_bcn_vifs = atomic_read(&mors->num_bcn_vifs);
+
+	mq = mm81x_hif_get_tx_beacon_queue(mors);
+	if (!mq) {
+		dev_err(mors->dev, "no matching beacon Q found");
+		return;
+	}
+
+	if (mm81x_skbq_count(mq) >= num_bcn_vifs) {
+		dev_err(mors->dev,
+			"previous beacon not consumed, dropping req [id:%d]",
+			mors_vif->id);
+		return;
+	}
+
+	beacon = ieee80211_beacon_get(mors->hw, vif, false);
+	if (!beacon)
+		return;
+
+	mm81x_beacon_h_fill_tx_info(mors, &tx_info, mors_vif,
+				    cfg80211_chandef_s1g_pri_width(&mors->chandef));
+	mm81x_skbq_skb_tx(mq, &beacon, &tx_info, MM81X_SKB_CHAN_BEACON);
+
+	if (!test_bit(MM81X_STATE_DATA_QS_STOPPED, &mors->state_flags))
+		mm81x_mac_send_buffered_bc(mors, vif);
+}
+
+static void mm81x_mac_beacon_init(struct mm81x_vif *mors_vif)
+{
+	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
+
+	INIT_WORK(&mors_vif->u.ap.beacon_work, mm81x_mac_beacon_work);
+	mm81x_mac_beacon_irq_enable(mors_vif, true);
+	atomic_inc(&mors->num_bcn_vifs);
+}
+
 static void mm81x_mac_ops_stop(struct ieee80211_hw *hw, bool suspend)
 {
 	struct mm81x *mors = hw->priv;
@@ -1691,6 +1727,9 @@ static int mm81x_mac_ops_sta_state(struct ieee80211_hw *hw,
 			mors_vif->u.ap.num_stas++;
 		else if (vif->type == NL80211_IFTYPE_STATION)
 			mors_vif->u.sta.is_assoc = true;
+
+		mors_sta->max_rx_bw_mhz =
+			S1G_SUPP_CH_WIDTH_MAX(sta->deflink.s1g_cap.cap);
 	}
 
 	if (new_state < old_state && new_state == IEEE80211_STA_NONE) {
@@ -2015,6 +2054,13 @@ static void mm81x_mac_ops_flush(struct ieee80211_hw *hw,
 		mm81x_mac_wait_queues(mors);
 }
 
+static bool mm81x_mac_ops_tx_frames_pending(struct ieee80211_hw *hw)
+{
+	struct mm81x *mors = hw->priv;
+
+	return mm81x_mac_has_tx_pending(mors);
+}
+
 static int mm81x_mac_ops_set_rts_threshold(struct ieee80211_hw *hw,
 					   int radio_idx, u32 value)
 {
@@ -2240,6 +2286,7 @@ static const struct ieee80211_ops mm81x_ops = {
 	.configure_filter = mm81x_mac_ops_configure_filter,
 	.sta_state = mm81x_mac_ops_sta_state,
 	.flush = mm81x_mac_ops_flush,
+	.tx_frames_pending = mm81x_mac_ops_tx_frames_pending,
 	.set_frag_threshold = mm81x_mac_set_frag_threshold,
 	.set_rts_threshold = mm81x_mac_ops_set_rts_threshold,
 	.sta_statistics = mm81x_mac_ops_sta_statistics,
diff --git a/drivers/net/wireless/morsemicro/mm81x/skbq.c b/drivers/net/wireless/morsemicro/mm81x/skbq.c
index 25655bd56d140..3bf15e7c38d80 100644
--- a/drivers/net/wireless/morsemicro/mm81x/skbq.c
+++ b/drivers/net/wireless/morsemicro/mm81x/skbq.c
@@ -231,10 +231,9 @@ static bool mm81x_tx_h_is_ps_filtered(struct mm81x_skbq *mq,
 	WARN_ON_ONCE(!(le32_to_cpu(tx_sts->flags) &
 		       MM81X_TX_STATUS_FLAGS_PS_FILTERED));
 
-	if (vif->type == NL80211_IFTYPE_AP) {
-		__mm81x_skbq_drop_pending_skb(mq, skb);
-		return true;
-	}
+	/* mac80211 buffers frames in AP mode */
+	if (vif->type == NL80211_IFTYPE_AP)
+		return false;
 
 	if (vif->type == NL80211_IFTYPE_STATION) {
 		mm81x_skbq_insert_pending(mq, skb, tx_sts->pkt_id);

3/2 2026/08/27 06:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6710
							output: 32
							thoughts: 175
						

Thoughts:
**Analyzing this Wireless Driver Patch**

Okay, so I've got this patch – seems it touches a few files: `mac.c`, `core.h`, and `skbq.c` – all under `drivers/net/wireless/morsemicro/mm81x`. Right off the bat, that's telling me it's related to the `morsemicro/mm81x` wireless driver. My immediate concern is, can this even *run* in a virtualized environment? Wireless drivers are notorious for needing direct hardware access, though some can be emulated or are entirely software-based. But *wait*, this is a specific hardware driver, isn't it? `morsemicro/mm81x` rings a bell as something that relies on actual hardware. Hmm, is this a USB device, PCI, or maybe even SDIO? I should probably take a closer look at that directory structure – `drivers/net/wireless/morsemicro/mm81x/` – to get a better handle on the hardware interface involved. Gotta know where this patch is heading before I go any further.



4/2 2026/08/27 06:40 tool codesearch-dir-index
0m Args:
{
  "Dir": "drivers/net/wireless/morsemicro/mm81x"
}

Results:
{
  "Files": [
    "bus.h",
    "command.c",
    "command.h",
    "command_defs.h",
    "core.c",
    "core.h",
    "fw.c",
    "fw.h",
    "hif.h",
    "hw.c",
    "hw.h",
    "mac.c",
    "mac.h",
    "mmrc.c",
    "mmrc.h",
    "ps.c",
    "ps.h",
    "rate_code.h",
    "rc.c",
    "rc.h",
    "sdio.c",
    "skbq.c",
    "skbq.h",
    "usb.c",
    "yaps.c",
    "yaps.h",
    "yaps_hw.c",
    "yaps_hw.h"
  ],
  "Subdirs": null
}

5/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7354
							output: 41
							thoughts: 139
						

Thoughts:
**My Initial Assessment**

Okay, so I see `usb.c` and `sdio.c` mentioned. My mind immediately jumps to USB. Excellent! USB drivers are a classic target for fuzzing. I can easily leverage USB gadget emulation like dummy_hcd, or even syzkaller's USB fuzzing capabilities to attack that code.

Hold on a second... the prompt specifies a challenge with code paths seemingly unreachable in virtualized environments like GCE or QEMU, even with software-emulated hardware. But wait, since `usb.c` is present, that changes things! USB fuzzing is the perfect solution for this. Virtualization constraints don't necessarily apply here. Let's dig into `usb.c` and see if it actually registers a USB driver. This could be my entry point. This is going to be my approach.



6/2 2026/08/27 06:40 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "usb_register",
  "PathPrefix": "drivers/net/wireless/morsemicro/mm81x/usb.c"
}

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

7/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7729
							output: 43
							thoughts: 15
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Kernel Module Investigation**

Alright, my first instinct is to zero in on the usual suspects. I'm going to quickly scan the code, or system logs, depending on the context I'm working in, looking specifically for references to the kernel module in question. Specifically, I'm thinking I'll start with something like `module_usb_driver` or something that is similar. I will consider any potentially relevant modules with similar naming conventions that could be a relevant module to the process. This isn't necessarily a deep dive, more of a quick triage to see if this module, or something related, is even in play. This is the first, fastest step, before considering any broader analysis.



8/2 2026/08/27 06:40 tool grepper
0m Args:
{
  "Expression": "module_usb_driver",
  "PathPrefix": "drivers/net/wireless/morsemicro/mm81x/usb.c"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/usb.c=925=static struct usb_driver mm81x_usb_driver = {\n--\ndrivers/net/wireless/morsemicro/mm81x/usb.c-938-\ndrivers/net/wireless/morsemicro/mm81x/usb.c:939:module_usb_driver(mm81x_usb_driver);\ndrivers/net/wireless/morsemicro/mm81x/usb.c-940-\n"
}

9/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8091
							output: 40
							thoughts: 158
						

Thoughts:
**Analyzing the Target Driver**

Okay, so this is definitely a USB driver. That immediately opens up fuzzing possibilities using USB emulation, which is a good starting point. I see the patch is touching core MAC operations. Specifically, it's modifying functions like `mm81x_mac_ops_tx`, `mm81x_mac_beacon_work`, `mm81x_mac_ops_sta_state`, and `mm81x_tx_h_is_ps_filtered`. These are all crucial parts of the driver's MAC functionality, so any vulnerability here could have significant impact.

Before getting too far down the fuzzing path, it's essential to confirm the driver's provenance. Is this upstream kernel code, or is it a staging or out-of-tree driver? Knowing this will inform my approach. Looking at the path, it looks to be in `drivers/net/wireless/morsemicro/mm81x/`. Now, the next step is to examine the Kconfig file for this driver. I need to find the specific `CONFIG` option to confirm its configuration within the kernel build.



10/2 2026/08/27 06:40 tool grepper
0m Args:
{
  "Expression": "config MM81X",
  "PathPrefix": "drivers/net/wireless/morsemicro/mm81x/"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/Kconfig-2-\ndrivers/net/wireless/morsemicro/mm81x/Kconfig:3:config MM81X\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-4-\ttristate \"Morse Micro MM81x wireless devices\" if COMPILE_TEST\n--\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-11-\ndrivers/net/wireless/morsemicro/mm81x/Kconfig:12:config MM81X_USB\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-13-\ttristate \"Morse Micro MM81x USB support\"\n--\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-19-\ndrivers/net/wireless/morsemicro/mm81x/Kconfig:20:config MM81X_SDIO\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-21-\ttristate \"Morse Micro MM81x SDIO support\"\n"
}

11/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8810
							output: 43
							thoughts: 35
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Checking Configuration Dependencies**

Alright, so we're dealing with two key configurations here: `MM81X` and `MM81X_USB`. My immediate thought is, "Let's dig into the dependencies for `MM81X_USB` first." It's likely the USB variant is built upon a base configuration, so understanding its dependencies will give us a good sense of the overall architecture. I want to see what core features are inherited and what specific USB-related modules are added or modified. Starting with `MM81X_USB` allows us to understand the more specialized use case and its potential interactions with the base. I'll need to know whether its dependencies are well-defined, and whether there are any potential conflicts or areas that require special attention.



12/2 2026/08/27 06:40 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/morsemicro/mm81x/Kconfig",
  "FirstLine": 1,
  "LineCount": 50
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0\n   2:\t\n   3:\tconfig MM81X\n   4:\t\ttristate \"Morse Micro MM81x wireless devices\" if COMPILE_TEST\n   5:\t\tdepends on MAC80211\n   6:\t\tselect FW_LOADER\n   7:\t\tselect CRC7\n   8:\t\thelp\n   9:\t\t  This module adds support for wireless devices based\n  10:\t\t  on Morse Micro MM81xx chipsets.\n  11:\t\n  12:\tconfig MM81X_USB\n  13:\t\ttristate \"Morse Micro MM81x USB support\"\n  14:\t\tdepends on MAC80211 \u0026\u0026 USB\n  15:\t\tselect MM81X\n  16:\t\thelp\n  17:\t\t  This module adds support for the USB interface of\n  18:\t\t  devices using the Morse Micro MM81x chipset.\n  19:\t\n  20:\tconfig MM81X_SDIO\n  21:\t\ttristate \"Morse Micro MM81x SDIO support\"\n  22:\t\tdepends on MAC80211 \u0026\u0026 MMC\n  23:\t\tselect MM81X\n  24:\t\thelp\n  25:\t\t  This module adds support for the SDIO interface of\n  26:\t\t  devices using the Morse Micro MM81x chipset.\n"
}

13/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9424
							output: 50
							thoughts: 529
						

Thoughts:
**Fuzzing Focus: Kernel Functions in mm81x Driver**

Okay, so I've quickly scoped out the relevant configuration requirements; it looks like `MM81X_USB`, `MAC80211`, and `USB` are needed. Actually, `MM81X_USB` also implies `MM81X`, so that's the key one.

Now I need to refine the fuzzing target. Let's look at the functions that have been modified. I see `mm81x_tx_h_get_max_tx_bw`, `mm81x_mac_beacon_irq_handle`, `mm81x_hw_scan_h_pack_tlv_hdr`, `mm81x_tx_h_fill_info`, `mm81x_tx_h_get_bw`, `mm81x_mac_ops_tx`, `mm81x_mac_send_buffered_bc`, `mm81x_mac_beacon_work`, `mm81x_mac_beacon_init`, `mm81x_mac_ops_stop`, `mm81x_mac_ops_sta_state`, `mm81x_mac_ops_flush`, `mm81x_mac_ops_tx_frames_pending`, `mm81x_mac_ops_set_rts_threshold`, and `mm81x_tx_h_is_ps_filtered`.

My strategy here is to focus on specific non-hot-path kernel functions, and I'm using the typical "hot path vs. not" analysis to determine the best candidates.
`mm81x_mac_ops_tx` is a hot path; it's the TX path.
`mm81x_mac_beacon_work` is a workqueue function, it's called periodically, and probably not a hot path, but it will be a good candidate.
`mm81x_mac_ops_sta_state` will be called on station state changes, like when there is an association or disassociation; that looks like a great candidate.
`mm81x_mac_ops_tx_frames_pending` is a mac80211 callback.
`mm81x_mac_beacon_init` is called during AP setup.
`mm81x_tx_h_is_ps_filtered` is called during TX, so it's probably hot path.

Alright, I'll check `mm81x_mac_ops_sta_state` and `mm81x_mac_ops_tx_frames_pending` in `drivers/net/wireless/morsemicro/mm81x/mac.c`. I have a feeling those are going to be fruitful starting points.



14/2 2026/08/27 06:40 tool grepper
0m Args:
{
  "Expression": "mm81x_mac_ops_sta_state",
  "PathPrefix": "drivers/net/wireless/morsemicro/mm81x/mac.c"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=1669=static int mm81x_mac_ops_conf_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1693-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:1694:static int mm81x_mac_ops_sta_state(struct ieee80211_hw *hw,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1695-\t\t\t\t   struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2278=static const struct ieee80211_ops mm81x_ops = {\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2286-\t.configure_filter = mm81x_mac_ops_configure_filter,\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2287:\t.sta_state = mm81x_mac_ops_sta_state,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2288-\t.flush = mm81x_mac_ops_flush,\n"
}

15/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10984
							output: 52
							thoughts: 21
						

Thoughts:
Here's my summary, as though I'm thinking through this:

**Analyzing the Callback Function: `mm81x_mac_ops_tx_frames_pending`**

Okay, so I'm looking at this `mm81x_mac_ops_tx_frames_pending` function. I see it's another callback, which is what I suspected given the naming convention. That's good to know and reinforces the design pattern I'm familiar with in this kind of driver. It means the MAC layer has a way to signal back to the higher-level driver about pending transmission frames. Now I need to figure out *what* signals and how it's used. Is it a polling mechanism or some kind of interrupt? Is it tied into the TX ring management or frame queueing? This is key information for optimizing throughput or debugging TX issues. My next steps are to trace the calls around this function and to check the data structures that is working with. From there I can determine the exact role of this callback in the entire TX process.



16/2 2026/08/27 06:40 tool grepper
0m Args:
{
  "Expression": "mm81x_mac_ops_tx_frames_pending",
  "PathPrefix": "drivers/net/wireless/morsemicro/mm81x/mac.c"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=2044=static void mm81x_mac_ops_flush(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2056-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2057:static bool mm81x_mac_ops_tx_frames_pending(struct ieee80211_hw *hw)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2058-{\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2278=static const struct ieee80211_ops mm81x_ops = {\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2288-\t.flush = mm81x_mac_ops_flush,\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2289:\t.tx_frames_pending = mm81x_mac_ops_tx_frames_pending,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2290-\t.set_frag_threshold = mm81x_mac_set_frag_threshold,\n"
}

17/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11632
							output: 51
							thoughts: 173
						

Thoughts:
**Analyzing the Function's Visibility and Usage**

Okay, so I'm looking at `mm81x_mac_ops_tx_frames_pending`. Since it's marked as `static`, my initial thought is that it might be inlined, and therefore wouldn't show up as a discrete symbol. But then I remember that its address *is* taken within `mm81x_ops`, which means the compiler can't inline it. So, it *should* have its own symbol.

Then I get hung up on the guidance here. The prompt clearly favors non-static, non-inlined entrypoint functions over internal static helper functions (the ones that *are* inlined). This makes me question whether to use it. However, I need to remind myself that it's an API entrypoint - a callback, so in this case, it's different.

So, since the prompt makes me second guess this, maybe there is another entrypoint I can use. I should look around for another non-static function that has been modified. Ah, `mm81x_mac_beacon_irq_handle` is non-static.



18/2 2026/08/27 06:40 tool grepper
0m Args:
{
  "Expression": "mm81x_mac_beacon_irq_handle",
  "PathPrefix": "drivers/net/wireless/morsemicro/mm81x/mac.c"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=426=static void mm81x_beacon_h_fill_tx_info(struct mm81x *mors,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-450-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:451:void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-452-{\n"
}

19/2 2026/08/27 06:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 12268
							output: 161
							thoughts: 1595
						

Thoughts:
**Analysis of MM81x MAC Driver Patch for Fuzzing**

Okay, let's break this down. My initial assessment starts with identifying the functions modified and their characteristics regarding static vs. non-static, and inlining. I'm focusing on potential fuzz targets within this patch. `mm81x_mac_beacon_irq_handle` is non-static, so it immediately catches my attention as a frequent callback, and thus a potential target. However, after checking the diff, I see that while I thought it was modified, it was just adjacent to the changed code.

Next, I'm analyzing a set of static functions: `mm81x_mac_send_buffered_bc`, `mm81x_mac_beacon_work`, `mm81x_mac_beacon_init`, and `mm81x_tx_h_is_ps_filtered`. `mm81x_mac_send_buffered_bc` is static, which generally means it's not directly exposed. I'm focusing on non-static functions and those that are callbacks or involved in interrupt handling as these are more likely to be entry points for fuzzing.

I then looked at the changes in the patch: `mm81x_tx_h_get_bw` added to calculate TX bandwidth correctly, which is used by `mm81x_mac_ops_tx`. `mm81x_mac_beacon_work` has been modified to send buffered broadcast frames after a beacon. Also, `mm81x_mac_ops_sta_state` is updated to set `max_rx_bw_mhz`, and a new callback `mm81x_mac_ops_tx_frames_pending` is added. Finally, `mm81x_tx_h_is_ps_filtered` is modified to avoid dropping frames in AP mode.

Based on the functionality, these appear to be functional changes to the MAC operations of the driver. Now, the key is how to reach them. The USB emulation through `MM81X_USB` is the key. Since the driver can be fuzzed via USB, I mark this as `WorthFuzzing=true`.

Now, I'm figuring out the relevant configurations.  I confirm that `MM81X_USB` is the relevant config as it enables the USB driver, which I can fuzz. `MAC80211` and `USB` are dependencies.

My primary focus shifts to identifying the key functions. I initially considered `mm81x_mac_beacon_irq_handle`, but the diff shows that it's not the modified code.

Looking at the code and diff, I see that several functions are modified: `mm81x_mac_ops_sta_state`, `mm81x_mac_ops_tx_frames_pending`, and a change in the internal flow with `mm81x_mac_beacon_work`, where now the static `mm81x_mac_send_buffered_bc` is called.

The key entry points are the callbacks which are not inlined: `mm81x_mac_ops_sta_state` and `mm81x_mac_ops_tx_frames_pending`, which were the original focus. Additionally, `mm81x_mac_beacon_work` is a workqueue callback and unlikely to be inlined, and is likely a good point to start with.

So the final set of focus symbols will be:
*   `mm81x_mac_ops_sta_state`
*   `mm81x_mac_ops_tx_frames_pending`
*   `mm81x_mac_beacon_work`

`MM81X_USB` or `MAC80211` are the relevant configurations.
The patch introduces functional changes related to TX bandwidth calculation, broadcast frame buffering in AP mode, and power save filtering. It can be reached through USB emulation.



20/2 2026/08/27 06:41 tool set-results
0m Args:
{
  "EnableConfigs": [
    "MM81X_USB",
    "MAC80211"
  ],
  "FocusSymbols": [
    "mm81x_mac_ops_sta_state",
    "mm81x_mac_ops_tx_frames_pending",
    "mm81x_mac_beacon_work"
  ],
  "Reasoning": "The patch makes functional changes to the Morse Micro MM81x wireless driver's MAC operations, including TX bandwidth calculation, broadcast frame buffering in AP mode, and power save filtering. The driver supports a USB interface (CONFIG_MM81X_USB) which can be reached and fuzzed in virtualized environments via USB emulation.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "MM81X_USB",
    "MAC80211"
  ],
  "FocusSymbols": [
    "mm81x_mac_ops_sta_state",
    "mm81x_mac_ops_tx_frames_pending",
    "mm81x_mac_beacon_work"
  ],
  "Reasoning": "The patch makes functional changes to the Morse Micro MM81x wireless driver's MAC operations, including TX bandwidth calculation, broadcast frame buffering in AP mode, and power save filtering. The driver supports a USB interface (CONFIG_MM81X_USB) which can be reached and fuzzed in virtualized environments via USB emulation.",
  "WorthFuzzing": true
}

21/1 2026/08/27 06:41 action If
3m Args:
{
  "WorthFuzzing": true
}

Results:
null

22/2 2026/08/27 06:41 agent kmsan-evaluator
3m Model:
best-expensive

Args:
null

Results:
{
  "KMSANReasoning": "The patch modifies the mm81x wireless driver to limit TX bandwidth based on the station's maximum RX bandwidth, send buffered broadcast frames after a DTIM beacon, and implement the tx_frames_pending callback. All newly introduced local structures (e.g., `struct ieee80211_tx_control control` and `struct mm81x_skb_tx_info tx_info`) are explicitly zero-initialized using `{ 0 }`. The `max_rx_bw_mhz` field added to `struct mm81x_sta` is initialized from the mac80211 station capabilities during association. The patch does not introduce any new kernel-to-user copies, nor does it add complex data structures that could be partially uninitialized. There is no risk of uninitialized memory being used in control flow or leaked to userspace. Standard KASAN and other bug detectors are sufficient to catch any potential memory corruption or out-of-bounds access.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
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 0e95e0c8e04da9de175f2e9e3a17de18198ef59a
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Aug 27 06:39:53 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/morsemicro/mm81x/core.h b/drivers/net/wireless/morsemicro/mm81x/core.h
index 2fd4b4786e777..75e998e8e3241 100644
--- a/drivers/net/wireless/morsemicro/mm81x/core.h
+++ b/drivers/net/wireless/morsemicro/mm81x/core.h
@@ -192,7 +192,12 @@ struct mm81x_sta {
 	bool tid_tx[IEEE80211_NUM_TIDS];
 	bool tid_start_tx[IEEE80211_NUM_TIDS];
 	u8 tid_params[IEEE80211_NUM_TIDS];
-	int max_bw_mhz;
+
+	/*
+	 * We really should be using link_sta::bandwidth but
+	 * that requires non-trivial work.
+	 */
+	int max_rx_bw_mhz;
 	struct mm81x_rc_sta rc;
 	struct mmrc_rate last_sta_tx_rate;
 	s16 avg_rssi;
diff --git a/drivers/net/wireless/morsemicro/mm81x/mac.c b/drivers/net/wireless/morsemicro/mm81x/mac.c
index 08ca116a68b47..4485748518b4a 100644
--- a/drivers/net/wireless/morsemicro/mm81x/mac.c
+++ b/drivers/net/wireless/morsemicro/mm81x/mac.c
@@ -66,6 +66,9 @@
 /* HW restart delay time before terminating hardware IF work items */
 #define MM81X_HW_RESTART_DELAY_MS 20
 
+/* Maximum number of multicast frames to release after a DTIM beacon */
+#define MM81X_MAX_MC_FRAMES_AFTER_DTIM 4
+
 /* clang-format off */
 
 /* mm81x chips do not support 16MHz */
@@ -322,7 +325,7 @@ static int mm81x_mac_ops_start(struct ieee80211_hw *hw)
 	return 0;
 }
 
-static int mm81x_tx_h_get_max_bw(struct mm81x *mors)
+static int mm81x_tx_h_get_max_tx_bw(struct mm81x *mors)
 {
 	return MM81X_FW_SUPP(&mors->fw_caps, 8MHZ) ? 8 :
 	       MM81X_FW_SUPP(&mors->fw_caps, 4MHZ) ? 4 :
@@ -445,39 +448,6 @@ static void mm81x_beacon_h_fill_tx_info(struct mm81x *mors,
 			cpu_to_le32(MM81X_TX_CONF_FLAGS_IMMEDIATE_REPORT);
 }
 
-static void mm81x_mac_beacon_work(struct work_struct *work)
-{
-	struct mm81x_vif *mors_vif =
-		from_work(mors_vif, work, u.ap.beacon_work);
-	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
-	struct mm81x_skbq *mq;
-	struct sk_buff *beacon;
-	struct ieee80211_vif *vif = mm81x_vif_to_ieee80211_vif(mors_vif);
-	struct mm81x_skb_tx_info tx_info = { 0 };
-	int num_bcn_vifs = atomic_read(&mors->num_bcn_vifs);
-
-	mq = mm81x_hif_get_tx_beacon_queue(mors);
-	if (!mq) {
-		dev_err(mors->dev, "no matching beacon Q found");
-		return;
-	}
-
-	if (mm81x_skbq_count(mq) >= num_bcn_vifs) {
-		dev_err(mors->dev,
-			"previous beacon not consumed, dropping req [id:%d]",
-			mors_vif->id);
-		return;
-	}
-
-	beacon = ieee80211_beacon_get(mors->hw, vif, false);
-	if (!beacon)
-		return;
-
-	mm81x_beacon_h_fill_tx_info(mors, &tx_info, mors_vif,
-				    cfg80211_chandef_s1g_pri_width(&mors->chandef));
-	mm81x_skbq_skb_tx(mq, &beacon, &tx_info, MM81X_SKB_CHAN_BEACON);
-}
-
 void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)
 {
 	int vif_id;
@@ -497,15 +467,6 @@ void mm81x_mac_beacon_irq_handle(struct mm81x *mors, u32 status)
 	}
 }
 
-static void mm81x_mac_beacon_init(struct mm81x_vif *mors_vif)
-{
-	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
-
-	INIT_WORK(&mors_vif->u.ap.beacon_work, mm81x_mac_beacon_work);
-	mm81x_mac_beacon_irq_enable(mors_vif, true);
-	atomic_inc(&mors->num_bcn_vifs);
-}
-
 static struct hw_scan_tlv_hdr mm81x_hw_scan_h_pack_tlv_hdr(u16 tag, u16 len)
 {
 	struct hw_scan_tlv_hdr hdr = { .tag = cpu_to_le16(tag),
@@ -1282,38 +1243,54 @@ static void mm81x_tx_h_fill_info(struct mm81x *mors,
 	}
 }
 
+static int mm81x_tx_h_get_bw(struct mm81x *mors, struct ieee80211_sta *sta,
+			     struct sk_buff *skb, bool is_mgmt)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct mm81x_sta *mors_sta = NULL;
+	int tx_bw_mhz;
+
+	if (ieee80211_is_probe_resp(hdr->frame_control))
+		return 1;
+
+	if (is_mgmt || info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
+		return cfg80211_chandef_s1g_pri_width(&mors->chandef);
+
+	/*
+	 * In AP mode group addressed frames go out at the primary width so
+	 * that every associated STA can receive them, including any that
+	 * cannot support the operating width.
+	 */
+	if (info->control.vif->type == NL80211_IFTYPE_AP &&
+	    is_multicast_ether_addr(ieee80211_get_DA(hdr)))
+		return cfg80211_chandef_s1g_pri_width(&mors->chandef);
+
+	if (sta)
+		mors_sta = (struct mm81x_sta *)sta->drv_priv;
+
+	tx_bw_mhz = min(mm81x_tx_h_get_max_tx_bw(mors),
+			cfg80211_chandef_get_width(&mors->chandef));
+	if (mors_sta && mors_sta->max_rx_bw_mhz)
+		tx_bw_mhz = min(tx_bw_mhz, mors_sta->max_rx_bw_mhz);
+
+	return tx_bw_mhz;
+}
+
 static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,
 			     struct ieee80211_tx_control *control,
 			     struct sk_buff *skb)
 {
-	struct mm81x *mors = hw->priv;
-	struct mm81x_skbq *mq = NULL;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_vif *vif = info->control.vif;
-	struct mm81x_skb_tx_info tx_info = { 0 };
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	bool is_mgmt = ieee80211_is_mgmt(hdr->frame_control);
-	int tx_bw_mhz = cfg80211_chandef_get_width(&mors->chandef);
 	struct ieee80211_sta *sta = control->sta;
-	int max_tx_bw = 0, sta_max_bw_mhz = 0;
-
-	if (sta) {
-		struct mm81x_sta *mors_sta = (struct mm81x_sta *)sta->drv_priv;
-
-		sta_max_bw_mhz = mors_sta->max_bw_mhz;
-	}
-
-	max_tx_bw = mm81x_tx_h_get_max_bw(mors);
-	tx_bw_mhz = min(max_tx_bw, tx_bw_mhz);
-
-	if (is_mgmt)
-		tx_bw_mhz = cfg80211_chandef_s1g_pri_width(&mors->chandef);
-	if (sta_max_bw_mhz)
-		tx_bw_mhz = min(tx_bw_mhz, sta_max_bw_mhz);
-	if (ieee80211_is_probe_resp(hdr->frame_control))
-		tx_bw_mhz = 1;
+	struct mm81x_skb_tx_info tx_info = { 0 };
+	struct mm81x *mors = hw->priv;
+	struct mm81x_skbq *mq;
 
-	mm81x_tx_h_fill_info(mors, &tx_info, skb, vif, tx_bw_mhz, sta);
+	mm81x_tx_h_fill_info(mors, &tx_info, skb, info->control.vif,
+			     mm81x_tx_h_get_bw(mors, sta, skb, is_mgmt), sta);
 
 	if (mm81x_tx_h_ps_filtered_for_sta(mors, skb, sta))
 		return;
@@ -1329,6 +1306,65 @@ static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,
 				      MM81X_SKB_CHAN_DATA);
 }
 
+static void mm81x_mac_send_buffered_bc(struct mm81x *mors,
+				       struct ieee80211_vif *vif)
+{
+	int count = MM81X_MAX_MC_FRAMES_AFTER_DTIM;
+	struct ieee80211_tx_control control = { 0 };
+	struct sk_buff *bc_frame;
+
+	while (count-- &&
+	       (bc_frame = ieee80211_get_buffered_bc(mors->hw, vif))) {
+		IEEE80211_SKB_CB(bc_frame)->control.vif = vif;
+		mm81x_mac_ops_tx(mors->hw, &control, bc_frame);
+	}
+}
+
+static void mm81x_mac_beacon_work(struct work_struct *work)
+{
+	struct mm81x_vif *mors_vif =
+		from_work(mors_vif, work, u.ap.beacon_work);
+	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
+	struct mm81x_skbq *mq;
+	struct sk_buff *beacon;
+	struct ieee80211_vif *vif = mm81x_vif_to_ieee80211_vif(mors_vif);
+	struct mm81x_skb_tx_info tx_info = { 0 };
+	int num_bcn_vifs = atomic_read(&mors->num_bcn_vifs);
+
+	mq = mm81x_hif_get_tx_beacon_queue(mors);
+	if (!mq) {
+		dev_err(mors->dev, "no matching beacon Q found");
+		return;
+	}
+
+	if (mm81x_skbq_count(mq) >= num_bcn_vifs) {
+		dev_err(mors->dev,
+			"previous beacon not consumed, dropping req [id:%d]",
+			mors_vif->id);
+		return;
+	}
+
+	beacon = ieee80211_beacon_get(mors->hw, vif, false);
+	if (!beacon)
+		return;
+
+	mm81x_beacon_h_fill_tx_info(mors, &tx_info, mors_vif,
+				    cfg80211_chandef_s1g_pri_width(&mors->chandef));
+	mm81x_skbq_skb_tx(mq, &beacon, &tx_info, MM81X_SKB_CHAN_BEACON);
+
+	if (!test_bit(MM81X_STATE_DATA_QS_STOPPED, &mors->state_flags))
+		mm81x_mac_send_buffered_bc(mors, vif);
+}
+
+static void mm81x_mac_beacon_init(struct mm81x_vif *mors_vif)
+{
+	struct mm81x *mors = mm81x_vif_to_mors(mors_vif);
+
+	INIT_WORK(&mors_vif->u.ap.beacon_work, mm81x_mac_beacon_work);
+	mm81x_mac_beacon_irq_enable(mors_vif, true);
+	atomic_inc(&mors->num_bcn_vifs);
+}
+
 static void mm81x_mac_ops_stop(struct ieee80211_hw *hw, bool suspend)
 {
 	struct mm81x *mors = hw->priv;
@@ -1691,6 +1727,9 @@ static int mm81x_mac_ops_sta_state(struct ieee80211_hw *hw,
 			mors_vif->u.ap.num_stas++;
 		else if (vif->type == NL80211_IFTYPE_STATION)
 			mors_vif->u.sta.is_assoc = true;
+
+		mors_sta->max_rx_bw_mhz =
+			S1G_SUPP_CH_WIDTH_MAX(sta->deflink.s1g_cap.cap);
 	}
 
 	if (new_state < old_state && new_state == IEEE80211_STA_NONE) {
@@ -2015,6 +2054,13 @@ static void mm81x_mac_ops_flush(struct ieee80211_hw *hw,
 		mm81x_mac_wait_queues(mors);
 }
 
+static bool mm81x_mac_ops_tx_frames_pending(struct ieee80211_hw *hw)
+{
+	struct mm81x *mors = hw->priv;
+
+	return mm81x_mac_has_tx_pending(mors);
+}
+
 static int mm81x_mac_ops_set_rts_threshold(struct ieee80211_hw *hw,
 					   int radio_idx, u32 value)
 {
@@ -2240,6 +2286,7 @@ static const struct ieee80211_ops mm81x_ops = {
 	.configure_filter = mm81x_mac_ops_configure_filter,
 	.sta_state = mm81x_mac_ops_sta_state,
 	.flush = mm81x_mac_ops_flush,
+	.tx_frames_pending = mm81x_mac_ops_tx_frames_pending,
 	.set_frag_threshold = mm81x_mac_set_frag_threshold,
 	.set_rts_threshold = mm81x_mac_ops_set_rts_threshold,
 	.sta_statistics = mm81x_mac_ops_sta_statistics,
diff --git a/drivers/net/wireless/morsemicro/mm81x/skbq.c b/drivers/net/wireless/morsemicro/mm81x/skbq.c
index 25655bd56d140..3bf15e7c38d80 100644
--- a/drivers/net/wireless/morsemicro/mm81x/skbq.c
+++ b/drivers/net/wireless/morsemicro/mm81x/skbq.c
@@ -231,10 +231,9 @@ static bool mm81x_tx_h_is_ps_filtered(struct mm81x_skbq *mq,
 	WARN_ON_ONCE(!(le32_to_cpu(tx_sts->flags) &
 		       MM81X_TX_STATUS_FLAGS_PS_FILTERED));
 
-	if (vif->type == NL80211_IFTYPE_AP) {
-		__mm81x_skbq_drop_pending_skb(mq, skb);
-		return true;
-	}
+	/* mac80211 buffers frames in AP mode */
+	if (vif->type == NL80211_IFTYPE_AP)
+		return false;
 
 	if (vif->type == NL80211_IFTYPE_STATION) {
 		mm81x_skbq_insert_pending(mq, skb, tx_sts->pkt_id);

23/3 2026/08/27 06:41 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6707
							output: 27
							thoughts: 982
						

Thoughts:
**Analyzing a Patch to the mm81x Wireless Driver: Potential Initialization Issues**

Okay, so this patch is aimed at the `mm81x` (Morse Micro) wireless driver. I see several functional additions and modifications, including introducing `max_rx_bw_mhz` to the `mm81x_sta` struct and adding a new constant, `MM81X_MAX_MC_FRAMES_AFTER_DTIM`. We're also seeing some code reorganization – moving the beacon-related functions (`mm81x_mac_beacon_work`, `mm81x_mac_beacon_init`).

Functionally, I note new functions like `mm81x_tx_h_get_bw` for bandwidth calculation, a modification to `mm81x_mac_ops_tx` to use it, and the addition of `mm81x_mac_send_buffered_bc` for handling buffered broadcast frames. We've got another new function, `mm81x_mac_ops_tx_frames_pending`, and a change to `mm81x_tx_h_is_ps_filtered` to avoid dropping SKBs in AP mode.

My primary concern now is to perform a sanity check and check whether there are any potential memory uninitialized issues, specifically within the new broadcast frame handling. The `mm81x_mac_send_buffered_bc` function uses `ieee80211_get_buffered_bc` and then calls `mm81x_mac_ops_tx`. I notice that the `control` struct is zero-initialized with `{ 0 }`, and that `mm81x_mac_ops_tx` uses this `control` struct along with the `skb`. The key variables in the structs initialized are `tx_info` and the `control` struct. Both are initialized to 0.

However, `mm81x_tx_h_get_bw` uses `info->control.flags` and `info->control.vif`. `ieee80211_get_buffered_bc` returns an `skb`, but `IEEE80211_SKB_CB(bc_frame)->control.vif` is set to `vif`. But what about `info->control.flags`? Is that initialized by the function that buffers the broadcast frame?

I need to check how `ieee80211_get_buffered_bc` operates. Specifically, I need to know how the control information within the `skb` is populated when the frame is initially buffered. It's likely that when the frame was initially buffered, the `cb` (control block) within the `skb` was populated. So, I need to understand what information is put into the `cb` structure during that buffering process. I need to dive into the `mac80211` code and check the implementation of `ieee80211_get_buffered_bc` to ensure there are no unintended consequences or uninitialized memory reads related to those flags.



24/3 2026/08/27 06:41 tool grepper
0m Args:
{
  "Expression": "ieee80211_get_buffered_bc"
}

Results:
{
  "Output": "Documentation/driver-api/80211/mac80211-advanced.rst=75=support for powersaving clients\n--\nDocumentation/driver-api/80211/mac80211-advanced.rst-82-   :functions:\nDocumentation/driver-api/80211/mac80211-advanced.rst:83:\tieee80211_get_buffered_bc\nDocumentation/driver-api/80211/mac80211-advanced.rst-84-\tieee80211_beacon_get\n--\ndrivers/net/wireless/ath/ath5k/base.c=1974=ath5k_beacon_send(struct ath5k_hw *ah)\n--\ndrivers/net/wireless/ath/ath5k/base.c-2061-\ndrivers/net/wireless/ath/ath5k/base.c:2062:\tskb = ieee80211_get_buffered_bc(ah-\u003ehw, vif);\ndrivers/net/wireless/ath/ath5k/base.c-2063-\twhile (skb) {\n--\ndrivers/net/wireless/ath/ath5k/base.c-2068-\ndrivers/net/wireless/ath/ath5k/base.c:2069:\t\tskb = ieee80211_get_buffered_bc(ah-\u003ehw, vif);\ndrivers/net/wireless/ath/ath5k/base.c-2070-\t}\n--\ndrivers/net/wireless/ath/ath9k/beacon.c=112=static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/beacon.c-164-\ndrivers/net/wireless/ath/ath9k/beacon.c:165:\tskb = ieee80211_get_buffered_bc(hw, vif);\ndrivers/net/wireless/ath/ath9k/beacon.c-166-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=137=static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-149-\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:150:\tskb = ieee80211_get_buffered_bc(priv-\u003ehw, vif);\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-151-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-184-\tnext:\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:185:\t\tskb = ieee80211_get_buffered_bc(priv-\u003ehw, vif);\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-186-\t}\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2389=void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2430-\ndrivers/net/wireless/ath/ath9k/xmit.c:2431:\t\tskb = ieee80211_get_buffered_bc(hw, vif);\ndrivers/net/wireless/ath/ath9k/xmit.c-2432-\t} while(skb);\n--\ndrivers/net/wireless/marvell/libertas_tf/main.c=679=void lbtf_bcn_sent(struct lbtf_private *priv)\n--\ndrivers/net/wireless/marvell/libertas_tf/main.c-688-\ndrivers/net/wireless/marvell/libertas_tf/main.c:689:\t\twhile ((skb = ieee80211_get_buffered_bc(priv-\u003ehw, priv-\u003evif))) {\ndrivers/net/wireless/marvell/libertas_tf/main.c-690-\t\t\tskb_queue_tail(\u0026priv-\u003ebc_ps_buf, skb);\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/beacon.c=79=mt7603_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/beacon.c-89-\ndrivers/net/wireless/mediatek/mt76/mt7603/beacon.c:90:\tskb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);\ndrivers/net/wireless/mediatek/mt76/mt7603/beacon.c-91-\tif (!skb)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_beacon.c=156=mt76x02_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_beacon.c-166-\ndrivers/net/wireless/mediatek/mt76/mt76x02_beacon.c:167:\tskb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);\ndrivers/net/wireless/mediatek/mt76/mt76x02_beacon.c-168-\tif (!skb)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=1309=static void mm81x_mac_send_buffered_bc(struct mm81x *mors,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1316-\twhile (count-- \u0026\u0026\ndrivers/net/wireless/morsemicro/mm81x/mac.c:1317:\t       (bc_frame = ieee80211_get_buffered_bc(mors-\u003ehw, vif))) {\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1318-\t\tIEEE80211_SKB_CB(bc_frame)-\u003econtrol.vif = vif;\n--\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c=168=static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,\n--\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c-183-\t */\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c:184:\tskb = ieee80211_get_buffered_bc(rt2x00dev-\u003ehw, vif);\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c-185-\twhile (skb) {\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c-186-\t\trt2x00mac_tx(rt2x00dev-\u003ehw, \u0026control, skb);\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c:187:\t\tskb = ieee80211_get_buffered_bc(rt2x00dev-\u003ehw, vif);\ndrivers/net/wireless/ralink/rt2x00/rt2x00dev.c-188-\t}\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=2457=static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-2506-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:2507:\twhile ((skb = ieee80211_get_buffered_bc(hw, vif)) != NULL) {\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-2508-\t\tmac80211_hwsim_tx_frame(hw, skb,\n--\ndrivers/net/wireless/zydas/zd1211rw/zd_mac.c=1151=static void zd_beacon_done(struct zd_mac *mac)\n--\ndrivers/net/wireless/zydas/zd1211rw/zd_mac.c-1163-\twhile (!ieee80211_queue_stopped(mac-\u003ehw, 0)) {\ndrivers/net/wireless/zydas/zd1211rw/zd_mac.c:1164:\t\tskb = ieee80211_get_buffered_bc(mac-\u003ehw, mac-\u003evif);\ndrivers/net/wireless/zydas/zd1211rw/zd_mac.c-1165-\t\tif (!skb)\n--\ninclude/net/mac80211.h=2825=struct ieee80211_txq {\n--\ninclude/net/mac80211.h-2866- *\tmulticast frames when there are power saving stations so that\ninclude/net/mac80211.h:2867: *\tthe driver can fetch them with ieee80211_get_buffered_bc().\ninclude/net/mac80211.h-2868- *\n--\ninclude/net/mac80211.h=6129=__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,\n--\ninclude/net/mac80211.h-6135-/**\ninclude/net/mac80211.h:6136: * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames\ninclude/net/mac80211.h-6137- * @hw: pointer as obtained from ieee80211_alloc_hw().\n--\ninclude/net/mac80211.h-6150- * generated with ieee80211_beacon_get() and the low-level driver must thus\ninclude/net/mac80211.h:6151: * call ieee80211_beacon_get() first. ieee80211_get_buffered_bc() returns\ninclude/net/mac80211.h-6152- * NULL if the previous generated beacon was not DTIM, so the low-level driver\n--\ninclude/net/mac80211.h=6156=struct sk_buff *\ninclude/net/mac80211.h:6157:ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif);\ninclude/net/mac80211.h-6158-\n--\nnet/mac80211/tx.c=6273=struct sk_buff *\nnet/mac80211/tx.c:6274:ieee80211_get_buffered_bc(struct ieee80211_hw *hw,\nnet/mac80211/tx.c-6275-\t\t\t  struct ieee80211_vif *vif)\n--\nnet/mac80211/tx.c-6344-}\nnet/mac80211/tx.c:6345:EXPORT_SYMBOL(ieee80211_get_buffered_bc);\nnet/mac80211/tx.c-6346-\n"
}

25/3 2026/08/27 06:41 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11469
							output: 42
							thoughts: 658
						

Thoughts:
**Analyzing the Broadcast Frame Transmission Path**

Okay, so I'm looking at this `mm81x_mac_send_buffered_bc` function. It seems straightforward enough: it's pulling broadcast frames (`skb`s) one at a time using `ieee80211_get_buffered_bc` and then sending them. The crucial part seems to be how the `skb` is being prepped for the hardware.

Hmm, a zero-initialized `control` struct is passed to `mm81x_mac_ops_tx`. That seems odd, because `mm81x_mac_ops_tx` uses the `control` struct with `skb`, which comes from `ieee80211_get_buffered_bc`. Let's step through and see...

In `mm81x_mac_send_buffered_bc`, `IEEE80211_SKB_CB(bc_frame)->control.vif` is set to `vif` *before* the call to `mm81x_mac_ops_tx`. That makes sense. The `mm81x_mac_ops_tx` function then proceeds to grab `info->control.vif` from the `skb` control block (`IEEE80211_SKB_CB`). OK, `vif` is set properly.

But here's the kicker: `mm81x_tx_h_get_bw` uses `info->control.flags`. And where is *that* initialized? `info` comes from `IEEE80211_SKB_CB(skb)`, but the `skb` is produced by mac80211. Since this `skb` comes from `ieee80211_get_buffered_bc`, it's been queued by mac80211, which means the `IEEE80211_SKB_CB` should be populated by mac80211. I need to go look at `ieee80211_get_buffered_bc` itself, over in `net/mac80211/tx.c` to understand exactly what gets set. I have a feeling there might be a subtle bug or an implicit dependency on other mac80211 parts here. Time to check the source!



26/3 2026/08/27 06:41 tool read-file
0m Args:
{
  "File": "net/mac80211/tx.c",
  "FirstLine": 6273,
  "LineCount": 100
}

Results:
{
  "Contents": "6273:\tstruct sk_buff *\n6274:\tieee80211_get_buffered_bc(struct ieee80211_hw *hw,\n6275:\t\t\t\t  struct ieee80211_vif *vif)\n6276:\t{\n6277:\t\tstruct ieee80211_local *local = hw_to_local(hw);\n6278:\t\tstruct sk_buff *skb = NULL;\n6279:\t\tstruct ieee80211_tx_data tx;\n6280:\t\tstruct ieee80211_sub_if_data *sdata;\n6281:\t\tstruct ps_data *ps;\n6282:\t\tstruct ieee80211_tx_info *info;\n6283:\t\tstruct ieee80211_chanctx_conf *chanctx_conf;\n6284:\t\n6285:\t\tsdata = vif_to_sdata(vif);\n6286:\t\n6287:\t\trcu_read_lock();\n6288:\t\tchanctx_conf = rcu_dereference(sdata-\u003evif.bss_conf.chanctx_conf);\n6289:\t\n6290:\t\tif (!chanctx_conf)\n6291:\t\t\tgoto out;\n6292:\t\n6293:\t\tif (sdata-\u003evif.type == NL80211_IFTYPE_AP) {\n6294:\t\t\tstruct beacon_data *beacon =\n6295:\t\t\t\t\trcu_dereference(sdata-\u003edeflink.u.ap.beacon);\n6296:\t\n6297:\t\t\tif (!beacon || !beacon-\u003ehead)\n6298:\t\t\t\tgoto out;\n6299:\t\n6300:\t\t\tps = \u0026sdata-\u003eu.ap.ps;\n6301:\t\t} else if (ieee80211_vif_is_mesh(\u0026sdata-\u003evif)) {\n6302:\t\t\tps = \u0026sdata-\u003eu.mesh.ps;\n6303:\t\t} else {\n6304:\t\t\tgoto out;\n6305:\t\t}\n6306:\t\n6307:\t\tif (ps-\u003edtim_count != 0 || !ps-\u003edtim_bc_mc)\n6308:\t\t\tgoto out; /* send buffered bc/mc only after DTIM beacon */\n6309:\t\n6310:\t\twhile (1) {\n6311:\t\t\tskb = skb_dequeue(\u0026ps-\u003ebc_buf);\n6312:\t\t\tif (!skb)\n6313:\t\t\t\tgoto out;\n6314:\t\t\tlocal-\u003etotal_ps_buffered--;\n6315:\t\n6316:\t\t\tif (!skb_queue_empty(\u0026ps-\u003ebc_buf) \u0026\u0026 skb-\u003elen \u003e= 2) {\n6317:\t\t\t\tstruct ieee80211_hdr *hdr =\n6318:\t\t\t\t\t(struct ieee80211_hdr *) skb-\u003edata;\n6319:\t\t\t\t/* more buffered multicast/broadcast frames ==\u003e set\n6320:\t\t\t\t * MoreData flag in IEEE 802.11 header to inform PS\n6321:\t\t\t\t * STAs */\n6322:\t\t\t\thdr-\u003eframe_control |=\n6323:\t\t\t\t\tcpu_to_le16(IEEE80211_FCTL_MOREDATA);\n6324:\t\t\t}\n6325:\t\n6326:\t\t\tif (sdata-\u003evif.type == NL80211_IFTYPE_AP)\n6327:\t\t\t\tsdata = IEEE80211_DEV_TO_SUB_IF(skb-\u003edev);\n6328:\t\t\tif (!ieee80211_tx_prepare(sdata, \u0026tx, NULL, skb))\n6329:\t\t\t\tbreak;\n6330:\t\t\tieee80211_free_txskb(hw, skb);\n6331:\t\t}\n6332:\t\n6333:\t\tinfo = IEEE80211_SKB_CB(skb);\n6334:\t\n6335:\t\ttx.flags |= IEEE80211_TX_PS_BUFFERED;\n6336:\t\tinfo-\u003eband = chanctx_conf-\u003edef.chan-\u003eband;\n6337:\t\n6338:\t\tif (invoke_tx_handlers(\u0026tx))\n6339:\t\t\tskb = NULL;\n6340:\t out:\n6341:\t\trcu_read_unlock();\n6342:\t\n6343:\t\treturn skb;\n6344:\t}\n6345:\tEXPORT_SYMBOL(ieee80211_get_buffered_bc);\n6346:\t\n6347:\tint ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)\n6348:\t{\n6349:\t\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n6350:\t\tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n6351:\t\tstruct ieee80211_local *local = sdata-\u003elocal;\n6352:\t\tint ret;\n6353:\t\tu32 queues;\n6354:\t\n6355:\t\tlockdep_assert_wiphy(local-\u003ehw.wiphy);\n6356:\t\n6357:\t\t/* only some cases are supported right now */\n6358:\t\tswitch (sdata-\u003evif.type) {\n6359:\t\tcase NL80211_IFTYPE_STATION:\n6360:\t\tcase NL80211_IFTYPE_AP:\n6361:\t\tcase NL80211_IFTYPE_AP_VLAN:\n6362:\t\t\tbreak;\n6363:\t\tdefault:\n6364:\t\t\tWARN_ON(1);\n6365:\t\t\treturn -EINVAL;\n6366:\t\t}\n6367:\t\n6368:\t\tif (WARN_ON(tid \u003e= IEEE80211_NUM_UPS))\n6369:\t\t\treturn -EINVAL;\n6370:\t\n6371:\t\tif (sta-\u003ereserved_tid == tid) {\n6372:\t\t\tret = 0;\n"
}

27/3 2026/08/27 06:41 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14334
							output: 30
							thoughts: 1519
						

Thoughts:
**Analysis of BroadCast Frame Transmission in mm81x Driver**

Okay, let's break this down. I'm looking at how broadcast frames are handled, specifically focusing on the mm81x driver. It seems like the core flow starts with `ieee80211_get_buffered_bc`, which then feeds into `ieee80211_tx_prepare` and `invoke_tx_handlers`. From what I can tell, `info->control.flags` is getting properly initialized through `ieee80211_tx_info_init`. That's good to see.

Now, moving down the call stack to `mm81x_mac_ops_tx`, the `control` struct is passed from `mm81x_mac_send_buffered_bc`. The key here is that `mm81x_mac_send_buffered_bc` zero-initializes this `control` struct. So the `control.sta` element, which is then accessed in `mm81x_mac_ops_tx`, is NULL. This means the `sta` pointer is NULL within `mm81x_mac_ops_tx`.

The relevant code from `mm81x_tx_h_get_bw` checks the `sta` pointer before de-referencing it. That's a good defensive programming practice, preventing a NULL pointer dereference. The code looks safe in that regard.

So, while `control` and `sta` are initialized to NULL, `mm81x_tx_h_get_bw` handles that correctly with an initial check of `if (sta)`. The `mors_sta` pointer is initialized to NULL as well, so the access of `mors_sta->max_rx_bw_mhz` is safe since the `mors_sta` dereference is guarded with the appropriate check. This ensures no issues arise from a null pointer.

Now, the next function called within `mm81x_mac_ops_tx` is `mm81x_tx_h_ps_filtered_for_sta`. This function also takes the `sta` parameter which, as we established is NULL in this case. I should probably investigate *that* function to confirm it correctly handles a NULL `sta` pointer. Let me take a look at the implementation of `mm81x_tx_h_ps_filtered_for_sta`. I'd expect it to have a check similar to the one in `mm81x_tx_h_get_bw`.



28/3 2026/08/27 06:42 tool grepper
0m Args:
{
  "Expression": "mm81x_tx_h_ps_filtered_for_sta"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=221=static bool mm81x_tx_h_pkt_over_rts_threshold(struct mm81x *mors,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-240-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:241:static bool mm81x_tx_h_ps_filtered_for_sta(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-242-\t\t\t\t\t   struct sk_buff *skb,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=1280=static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1294-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:1295:\tif (mm81x_tx_h_ps_filtered_for_sta(mors, skb, sta))\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1296-\t\treturn;\n"
}

29/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16775
							output: 46
							thoughts: 22
						

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

**Analyzing `mm81x_tx_h_ps_filtered_for_sta`**

Okay, let's dive into this. The naming convention, `mm81x_tx_h_ps_filtered_for_sta`, immediately tells me a few things. "mm81x" suggests it's likely related to a specific hardware module, probably a modem or radio chip family. "tx" indicates transmit path, so we're looking at signal processing on the outbound data stream. "h_ps" hints at a handling of high-power or high-speed data, perhaps a dual-use function. The 'filtered' term indicates it is processing the data through filters. And finally, "for_sta" likely refers to functions or variables specific to a station (STA) mode, i.e., a client or receiver in a wireless network.

So, my initial hypothesis is that this function likely implements transmit-path signal conditioning, filtering, and potentially power control specifically for the STA mode of a 'mm81x' device. I'm expecting to see operations related to channel selection, filtering, gain control, potentially pre-distortion, or other STA specific signal handling to ensure it works properly, to the STA, within the constraints of the 802.11 standard. I'll be looking for any indications of adaptive filtering, pre-emphasis, or power spectral density (PSD) shaping that's been customized for this mode. And I'll need to pay close attention to the data types and the filter coefficients used, which will reveal the details of the processing. Let's see if this matches what's actually implemented.



30/3 2026/08/27 06:42 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/morsemicro/mm81x/mac.c",
  "FirstLine": 241,
  "LineCount": 20
}

Results:
{
  "Contents": " 241:\tstatic bool mm81x_tx_h_ps_filtered_for_sta(struct mm81x *mors,\n 242:\t\t\t\t\t\t   struct sk_buff *skb,\n 243:\t\t\t\t\t\t   struct ieee80211_sta *sta)\n 244:\t{\n 245:\t\tstruct mm81x_sta *mors_sta;\n 246:\t\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n 247:\t\n 248:\t\tif (!sta)\n 249:\t\t\treturn false;\n 250:\t\n 251:\t\tmors_sta = (struct mm81x_sta *)sta-\u003edrv_priv;\n 252:\t\n 253:\t\tif (!mors_sta-\u003etx_ps_filter_en)\n 254:\t\t\treturn false;\n 255:\t\n 256:\t\tdev_dbg(mors-\u003edev, \"Frame for sta[%pM] PS filtered\", mors_sta-\u003eaddr);\n 257:\t\n 258:\t\tinfo-\u003eflags |= IEEE80211_TX_STAT_TX_FILTERED;\n 259:\t\tinfo-\u003eflags \u0026= ~IEEE80211_TX_CTL_AMPDU;\n 260:\t\n"
}

31/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 17568
							output: 26
							thoughts: 638
						

Thoughts:
**Analyzing the Beacon Transmission Path**

Okay, so I'm digging into this `mm81x_mac_beacon_work` function, trying to understand the beacon transmission process. The initial check `if (!sta) return false;` is a good sign; it confirms a basic safety check, preventing issues if `sta` is somehow null.

Moving on, I see this function is responsible for the actual beacon transmission. It's retrieving the `mm81x_vif` struct from the work struct and deriving the `mm81x` struct, which is standard practice. It also gets the `ieee80211_vif`. Then it grabs the beacon queue. I'm assuming it's handling multiple Virtual Interfaces.

The first sanity check is checking to see if a matching beacon Queue is found. If it isn't, it returns with an error. Makes sense. I'm noting the `mm81x_skbq_count` check against `num_bcn_vifs`. This looks like a backpressure mechanism to prevent beacon queue overflow. It's logging a drop if a previous beacon hasn't been consumed, which is crucial for stability.

The core of the process retrieves the beacon frame using `ieee80211_beacon_get`. If that fails, it returns. `tx_info` is zero-initialized, which I like to see. It provides a clean starting point. `mm81x_beacon_h_fill_tx_info` then populates `tx_info` with transmission-related data, including channel and other relevant parameters. The filled-in `tx_info` and the beacon are passed to `mm81x_skbq_skb_tx`, so it will probably transmit the beacon. Finally, there's a check on the state flag to see if `mm81x_mac_send_buffered_bc` is called after that.

Next, I'll need to look at `mm81x_tx_h_fill_info` to completely understand what goes into `tx_info` and how the transmission is configured. Seems like a pretty standard beacon path.



32/3 2026/08/27 06:42 tool grepper
0m Args:
{
  "Expression": "mm81x_tx_h_fill_info"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=1153=int mm81x_tx_h_get_attempts(struct mm81x *mors,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1169-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:1170:static void mm81x_tx_h_fill_info(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1171-\t\t\t\t struct mm81x_skb_tx_info *tx_info,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=1280=static void mm81x_mac_ops_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1291-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:1292:\tmm81x_tx_h_fill_info(mors, \u0026tx_info, skb, info-\u003econtrol.vif,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1293-\t\t\t     mm81x_tx_h_get_bw(mors, sta, skb, is_mgmt), sta);\n"
}

33/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 19067
							output: 47
							thoughts: 18
						

Thoughts:
Okay, here's my interpretation of what's going through my mind as I approach the code:

**Diving into `mm81x_tx_h_fill_info`**

Alright, let's get into this. The function name, `mm81x_tx_h_fill_info`, immediately tells me we're dealing with the MM81x chipset and a transmission context, specifically related to filling information—likely metadata or control data—for the transmit process at the hardware level. The "h" suggests we're probably working with a higher level of the transmit process. This implies that there's a corresponding low-level TX process to this that the "h" level will interface with. Based on prior experience with similar systems, this function is responsible for preparing and setting up the parameters that the lower-level hardware driver needs to actually kick off a transmission. I'll expect to see this code take in some higher-level descriptors and translate them into hardware-understandable settings. I'll be looking for things like buffer pointers, lengths, frame control information, QoS settings, and possibly even things like CRC calculation or pre-amble insertion. I'll focus on how this function populates the data structures that the hardware uses. Any bit twiddling or shifting is going to be of prime interest. I'm keen to see the details.



34/3 2026/08/27 06:42 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/morsemicro/mm81x/mac.c",
  "FirstLine": 1170,
  "LineCount": 80
}

Results:
{
  "Contents": "1170:\tstatic void mm81x_tx_h_fill_info(struct mm81x *mors,\n1171:\t\t\t\t\t struct mm81x_skb_tx_info *tx_info,\n1172:\t\t\t\t\t struct sk_buff *skb, struct ieee80211_vif *vif,\n1173:\t\t\t\t\t int tx_bw_mhz, struct ieee80211_sta *sta)\n1174:\t{\n1175:\t\tint i;\n1176:\t\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n1177:\t\tstruct mm81x_vif *mors_vif = ieee80211_vif_to_mors_vif(vif);\n1178:\t\tstruct mm81x_sta *mors_sta = NULL;\n1179:\t\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n1180:\t\tint op_bw_mhz = cfg80211_chandef_get_width(\u0026mors-\u003echandef);\n1181:\t\tu8 tid = skb-\u003epriority \u0026 IEEE80211_QOS_CTL_TAG1D_MASK;\n1182:\t\tbool rts_allowed = op_bw_mhz \u003c 8;\n1183:\t\n1184:\t\tif (sta)\n1185:\t\t\tmors_sta = (struct mm81x_sta *)sta-\u003edrv_priv;\n1186:\t\n1187:\t\trts_allowed \u0026= mm81x_tx_h_pkt_over_rts_threshold(mors, info, skb);\n1188:\t\n1189:\t\tmm81x_rc_sta_fill_tx_rates(mors, tx_info, skb, sta, tx_bw_mhz,\n1190:\t\t\t\t\t   rts_allowed);\n1191:\t\n1192:\t\tfor (i = 0; i \u003c IEEE80211_TX_MAX_RATES; i++) {\n1193:\t\t\tif (rts_allowed)\n1194:\t\t\t\tmm81x_ratecode_enable_rts(\n1195:\t\t\t\t\t\u0026tx_info-\u003erates[i].mm81x_ratecode);\n1196:\t\n1197:\t\t\tif (info-\u003econtrol.rates[i].flags \u0026 IEEE80211_TX_RC_SHORT_GI)\n1198:\t\t\t\tmm81x_ratecode_enable_sgi(\n1199:\t\t\t\t\t\u0026tx_info-\u003erates[i].mm81x_ratecode);\n1200:\t\t}\n1201:\t\n1202:\t\t/* Apply change of MCS0 to MCS10 if required. */\n1203:\t\tmm81x_tx_h_apply_mcs10(mors, tx_info);\n1204:\t\n1205:\t\ttx_info-\u003eflags |=\n1206:\t\t\tcpu_to_le32(MM81X_TX_CONF_FLAGS_VIF_ID_SET(mors_vif-\u003eid));\n1207:\t\n1208:\t\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_AMPDU)\n1209:\t\t\ttx_info-\u003eflags |= cpu_to_le32(MM81X_TX_CONF_FLAGS_CTL_AMPDU);\n1210:\t\n1211:\t\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_SEND_AFTER_DTIM)\n1212:\t\t\ttx_info-\u003eflags |=\n1213:\t\t\t\tcpu_to_le32(MM81X_TX_CONF_FLAGS_SEND_AFTER_DTIM);\n1214:\t\n1215:\t\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_NO_PS_BUFFER) {\n1216:\t\t\ttx_info-\u003eflags |= cpu_to_le32(MM81X_TX_CONF_NO_PS_BUFFER);\n1217:\t\n1218:\t\t\tif (info-\u003eflags \u0026 IEEE80211_TX_STATUS_EOSP)\n1219:\t\t\t\ttx_info-\u003eflags |= cpu_to_le32(\n1220:\t\t\t\t\tMM81X_TX_CONF_FLAGS_IMMEDIATE_REPORT);\n1221:\t\t} else if (ieee80211_is_mgmt(hdr-\u003eframe_control) \u0026\u0026\n1222:\t\t\t   !ieee80211_is_bufferable_mmpdu(skb)) {\n1223:\t\t\ttx_info-\u003eflags |= cpu_to_le32(MM81X_TX_CONF_NO_PS_BUFFER);\n1224:\t\t}\n1225:\t\n1226:\t\tif (info-\u003econtrol.hw_key) {\n1227:\t\t\ttx_info-\u003eflags |= cpu_to_le32(MM81X_TX_CONF_FLAGS_HW_ENCRYPT);\n1228:\t\t\ttx_info-\u003eflags |= cpu_to_le32(MM81X_TX_CONF_FLAGS_KEY_IDX_SET(\n1229:\t\t\t\tinfo-\u003econtrol.hw_key-\u003ehw_key_idx));\n1230:\t\t}\n1231:\t\n1232:\t\ttx_info-\u003etid = tid;\n1233:\t\tif (mors_sta) {\n1234:\t\t\ttx_info-\u003etid_params = mors_sta-\u003etid_params[tid];\n1235:\t\n1236:\t\t\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_CLEAR_PS_FILT) {\n1237:\t\t\t\tif (mors_sta-\u003etx_ps_filter_en)\n1238:\t\t\t\t\tdev_dbg(mors-\u003edev,\n1239:\t\t\t\t\t\t\"TX ps filter cleared sta[%pM]\",\n1240:\t\t\t\t\t\tmors_sta-\u003eaddr);\n1241:\t\t\t\tmors_sta-\u003etx_ps_filter_en = false;\n1242:\t\t\t}\n1243:\t\t}\n1244:\t}\n1245:\t\n1246:\tstatic int mm81x_tx_h_get_bw(struct mm81x *mors, struct ieee80211_sta *sta,\n1247:\t\t\t\t     struct sk_buff *skb, bool is_mgmt)\n1248:\t{\n1249:\t\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n"
}

35/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 21130
							output: 27
							thoughts: 137
						

Thoughts:
**Digging into the mm81x Transmit Path**

Okay, so I'm looking at `mm81x_tx_h_fill_info` and it's pulling data from `info->control.rates`, `info->flags`, and `info->control.hw_key`. My initial reaction is, this seems straightforward, the standard data structures are being used. Now, I have to consider the potential for unexpected behavior; the critical thinking mode takes over.

Wait a second… doesn't `ieee80211_get_buffered_bc` mess around with `info->control.rates`? I need to clarify the interaction between these functions, as that could be a source of confusion or a potential bug. I can't assume that `info->control.rates` is initialized correctly at this point. Gotta keep it real.

Ah, here's a wrinkle. `ieee80211_tx_prepare` calls `ieee80211_tx_info_init`. And *that* zeroes out `info->control`. So, if `ieee80211_tx_prepare` is called before `ieee80211_get_buffered_bc` it could wipe out the `info->control.rates` data I just thought I had. So I need to go deeper.

Best to be thorough, I'm going to jump into `net/mac80211/tx.c` and take a look at the implementation of `ieee80211_tx_info_init` so I can understand the context. This is where the magic happens, and it's time to follow the trail.



36/3 2026/08/27 06:42 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "ieee80211_tx_info_init"
}

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

37/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 21675
							output: 25
							thoughts: 44
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own:

**Digging into the 802.11 TX Initialization**

Hmm, is `ieee80211_tx_info_init` *really* the right function name here? It feels a little off, like it's not quite capturing the essence of what it's doing. Let me double-check. I think a closer look at `ieee80211_tx_prepare` might illuminate things better. Perhaps that function encapsulates more of the initialization *and* pre-transmission setup, making it the more logical entry point for understanding the process. Need to confirm that that is the case.



38/3 2026/08/27 06:42 tool grepper
0m Args:
{
  "Expression": "ieee80211_tx_prepare"
}

Results:
{
  "Output": "drivers/net/wireless/ath/ath9k/channel.c=984=static void ath_scan_send_probe(struct ath_softc *sc,\n--\ndrivers/net/wireless/ath/ath9k/channel.c-1007-\ndrivers/net/wireless/ath/ath9k/channel.c:1008:\tif (!ieee80211_tx_prepare_skb(sc-\u003ehw, vif, skb, band, NULL))\ndrivers/net/wireless/ath/ath9k/channel.c-1009-\t\treturn;\n--\ndrivers/net/wireless/ath/ath9k/channel.c=1096=ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,\n--\ndrivers/net/wireless/ath/ath9k/channel.c-1121-\t\tskb_set_queue_mapping(skb, IEEE80211_AC_VO);\ndrivers/net/wireless/ath/ath9k/channel.c:1122:\t\tif (!ieee80211_tx_prepare_skb(sc-\u003ehw, vif, skb, band, \u0026sta))\ndrivers/net/wireless/ath/ath9k/channel.c-1123-\t\t\treturn false;\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c=2173=mt76_offchannel_send_nullfunc(struct mt76_offchannel_cb_data *data,\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-2193-\ndrivers/net/wireless/mediatek/mt76/mac80211.c:2194:\tif (!ieee80211_tx_prepare_skb(phy-\u003ehw, vif, skb,\ndrivers/net/wireless/mediatek/mt76/mac80211.c-2195-\t\t\t\t      phy-\u003emain_chandef.chan-\u003eband,\n--\ndrivers/net/wireless/mediatek/mt76/scan.c=54=mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)\n--\ndrivers/net/wireless/mediatek/mt76/scan.c-84-\ndrivers/net/wireless/mediatek/mt76/scan.c:85:\tif (!ieee80211_tx_prepare_skb(phy-\u003ehw, vif, skb, band, NULL))\ndrivers/net/wireless/mediatek/mt76/scan.c-86-\t\tgoto out;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=3118=static void hw_scan_work(struct work_struct *work)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3172-\t\t\trcu_read_lock();\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:3173:\t\t\tif (!ieee80211_tx_prepare_skb(hwsim-\u003ehw,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3174-\t\t\t\t\t\t      hwsim-\u003ehw_scan_vif,\n--\ninclude/net/mac80211.h=7609=void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,\n--\ninclude/net/mac80211.h-7613-/**\ninclude/net/mac80211.h:7614: * ieee80211_tx_prepare_skb - prepare an 802.11 skb for transmission\ninclude/net/mac80211.h-7615- * @hw: pointer as obtained from ieee80211_alloc_hw()\n--\ninclude/net/mac80211.h-7626- */\ninclude/net/mac80211.h:7627:bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,\ninclude/net/mac80211.h-7628-\t\t\t      struct ieee80211_vif *vif, struct sk_buff *skb,\n--\nnet/mac80211/tx.c=952=ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)\n--\nnet/mac80211/tx.c-972-\t * Warn when submitting a fragmented A-MPDU frame and drop it.\nnet/mac80211/tx.c:973:\t * This scenario is handled in ieee80211_tx_prepare but extra\nnet/mac80211/tx.c-974-\t * caution taken here as fragmented ampdu may cause Tx stop.\n--\nnet/mac80211/tx.c=1207=static ieee80211_tx_result\nnet/mac80211/tx.c:1208:ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,\nnet/mac80211/tx.c-1209-\t\t     struct ieee80211_tx_data *tx,\n--\nnet/mac80211/tx.c=1900=static int invoke_tx_handlers(struct ieee80211_tx_data *tx)\n--\nnet/mac80211/tx.c-1908-\nnet/mac80211/tx.c:1909:bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,\nnet/mac80211/tx.c-1910-\t\t\t      struct ieee80211_vif *vif, struct sk_buff *skb,\n--\nnet/mac80211/tx.c-1917-\nnet/mac80211/tx.c:1918:\tif (ieee80211_tx_prepare(sdata, \u0026tx, NULL, skb) == TX_DROP) {\nnet/mac80211/tx.c-1919-\t\tkfree_skb(skb);\n--\nnet/mac80211/tx.c-1946-}\nnet/mac80211/tx.c:1947:EXPORT_SYMBOL(ieee80211_tx_prepare_skb);\nnet/mac80211/tx.c-1948-\n--\nnet/mac80211/tx.c=1952=static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/tx.c-1967-\t/* initialises tx */\nnet/mac80211/tx.c:1968:\tres_prepare = ieee80211_tx_prepare(sdata, \u0026tx, sta, skb);\nnet/mac80211/tx.c-1969-\n--\nnet/mac80211/tx.c=6274=ieee80211_get_buffered_bc(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-6327-\t\t\tsdata = IEEE80211_DEV_TO_SUB_IF(skb-\u003edev);\nnet/mac80211/tx.c:6328:\t\tif (!ieee80211_tx_prepare(sdata, \u0026tx, NULL, skb))\nnet/mac80211/tx.c-6329-\t\t\tbreak;\n"
}

39/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23928
							output: 42
							thoughts: 32
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm already quite familiar with networking and the 802.11 standard:

**Diving into the 802.11 TX Preparation**

Alright, time to crack into the code. I'm going to take a look at the `ieee80211_tx_prepare` function. My brain immediately jumps to `net/mac80211/tx.c` – that's where I expect to find the core of the MAC layer's transmit path. I need to refresh my understanding of *precisely* how a frame gets prepped for transmission within this context. I'm going to assume this is for an 802.11 stack built into Linux, but that helps me, as I already know the Linux networking stack quite well. I want to see how the software manipulates the frame, potentially adds headers, sets flags, and interacts with the hardware queues before it's actually sent over the air. What are the key data structures being manipulated here? Are we dealing with skbs? What kind of fragmentation or aggregation logic is at play? Let's get to the specifics and see how the standard is handled in practice. Hopefully, this routine can illuminate my current investigation's specific issues.



40/3 2026/08/27 06:42 tool read-file
0m Args:
{
  "File": "net/mac80211/tx.c",
  "FirstLine": 1207,
  "LineCount": 100
}

Results:
{
  "Contents": "1207:\tstatic ieee80211_tx_result\n1208:\tieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,\n1209:\t\t\t     struct ieee80211_tx_data *tx,\n1210:\t\t\t     struct sta_info *sta, struct sk_buff *skb)\n1211:\t{\n1212:\t\tstruct ieee80211_local *local = sdata-\u003elocal;\n1213:\t\tstruct ieee80211_hdr *hdr;\n1214:\t\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n1215:\t\tbool aggr_check = false;\n1216:\t\tint tid;\n1217:\t\n1218:\t\tmemset(tx, 0, sizeof(*tx));\n1219:\t\ttx-\u003eskb = skb;\n1220:\t\ttx-\u003elocal = local;\n1221:\t\ttx-\u003esdata = sdata;\n1222:\t\t__skb_queue_head_init(\u0026tx-\u003eskbs);\n1223:\t\n1224:\t\t/*\n1225:\t\t * If this flag is set to true anywhere, and we get here,\n1226:\t\t * we are doing the needed processing, so remove the flag\n1227:\t\t * now.\n1228:\t\t */\n1229:\t\tinfo-\u003econtrol.flags \u0026= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING;\n1230:\t\n1231:\t\thdr = (struct ieee80211_hdr *) skb-\u003edata;\n1232:\t\n1233:\t\tif (likely(sta)) {\n1234:\t\t\tif (!IS_ERR(sta))\n1235:\t\t\t\ttx-\u003esta = sta;\n1236:\t\t} else {\n1237:\t\t\tif (sdata-\u003evif.type == NL80211_IFTYPE_AP_VLAN) {\n1238:\t\t\t\ttx-\u003esta = rcu_dereference(sdata-\u003eu.vlan.sta);\n1239:\t\t\t\tif (!tx-\u003esta \u0026\u0026 sdata-\u003ewdev.use_4addr)\n1240:\t\t\t\t\treturn TX_DROP;\n1241:\t\t\t} else if (tx-\u003esdata-\u003econtrol_port_protocol == tx-\u003eskb-\u003eprotocol) {\n1242:\t\t\t\ttx-\u003esta = sta_info_get_bss(sdata, hdr-\u003eaddr1);\n1243:\t\t\t}\n1244:\t\t\tif (!tx-\u003esta \u0026\u0026 !is_multicast_ether_addr(hdr-\u003eaddr1)) {\n1245:\t\t\t\ttx-\u003esta = sta_info_get(sdata, hdr-\u003eaddr1);\n1246:\t\t\t\taggr_check = true;\n1247:\t\t\t}\n1248:\t\t}\n1249:\t\n1250:\t\tif (tx-\u003esta \u0026\u0026 ieee80211_is_data_qos(hdr-\u003eframe_control) \u0026\u0026\n1251:\t\t    !ieee80211_is_qos_nullfunc(hdr-\u003eframe_control) \u0026\u0026\n1252:\t\t    ieee80211_hw_check(\u0026local-\u003ehw, AMPDU_AGGREGATION) \u0026\u0026\n1253:\t\t    !ieee80211_hw_check(\u0026local-\u003ehw, TX_AMPDU_SETUP_IN_HW)) {\n1254:\t\t\tstruct tid_ampdu_tx *tid_tx;\n1255:\t\n1256:\t\t\ttid = ieee80211_get_tid(hdr);\n1257:\t\t\ttid_tx = rcu_dereference(tx-\u003esta-\u003eampdu_mlme.tid_tx[tid]);\n1258:\t\t\tif (!tid_tx \u0026\u0026 aggr_check) {\n1259:\t\t\t\tieee80211_aggr_check(sdata, tx-\u003esta, skb);\n1260:\t\t\t\ttid_tx = rcu_dereference(tx-\u003esta-\u003eampdu_mlme.tid_tx[tid]);\n1261:\t\t\t}\n1262:\t\n1263:\t\t\tif (tid_tx) {\n1264:\t\t\t\tbool queued;\n1265:\t\n1266:\t\t\t\tqueued = ieee80211_tx_prep_agg(tx, skb, info,\n1267:\t\t\t\t\t\t\t       tid_tx, tid);\n1268:\t\n1269:\t\t\t\tif (unlikely(queued))\n1270:\t\t\t\t\treturn TX_QUEUED;\n1271:\t\t\t}\n1272:\t\t}\n1273:\t\n1274:\t\tif (is_multicast_ether_addr(hdr-\u003eaddr1)) {\n1275:\t\t\ttx-\u003eflags \u0026= ~IEEE80211_TX_UNICAST;\n1276:\t\t\tinfo-\u003eflags |= IEEE80211_TX_CTL_NO_ACK;\n1277:\t\t} else\n1278:\t\t\ttx-\u003eflags |= IEEE80211_TX_UNICAST;\n1279:\t\n1280:\t\tif (!(info-\u003eflags \u0026 IEEE80211_TX_CTL_DONTFRAG)) {\n1281:\t\t\tif (!(tx-\u003eflags \u0026 IEEE80211_TX_UNICAST) ||\n1282:\t\t\t    skb-\u003elen + FCS_LEN \u003c= local-\u003ehw.wiphy-\u003efrag_threshold ||\n1283:\t\t\t    info-\u003eflags \u0026 IEEE80211_TX_CTL_AMPDU)\n1284:\t\t\t\tinfo-\u003eflags |= IEEE80211_TX_CTL_DONTFRAG;\n1285:\t\t}\n1286:\t\n1287:\t\tif (!tx-\u003esta)\n1288:\t\t\tinfo-\u003eflags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;\n1289:\t\telse if (test_and_clear_sta_flag(tx-\u003esta, WLAN_STA_CLEAR_PS_FILT)) {\n1290:\t\t\tinfo-\u003eflags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;\n1291:\t\t\tieee80211_check_fast_xmit(tx-\u003esta);\n1292:\t\t}\n1293:\t\n1294:\t\tinfo-\u003eflags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;\n1295:\t\n1296:\t\treturn TX_CONTINUE;\n1297:\t}\n1298:\t\n1299:\tstatic struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,\n1300:\t\t\t\t\t\t  struct ieee80211_vif *vif,\n1301:\t\t\t\t\t\t  struct sta_info *sta,\n1302:\t\t\t\t\t\t  struct sk_buff *skb)\n1303:\t{\n1304:\t\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb-\u003edata;\n1305:\t\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n1306:\t\tstruct ieee80211_txq *txq = NULL;\n"
}

41/3 2026/08/27 06:42 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26167
							output: 25
							thoughts: 63
						

Thoughts:
**Digging into the IEEE 802.11 TX Preparation**

Okay, hold on a second. I was under the impression that `ieee80211_tx_prepare` was responsible for clearing out the `info->control` field in that transmit information structure. But after a closer look, it seems like it's only touching `tx`. That's a crucial distinction. Now, the question is, *where* is `info->control` actually initialized? It has to be set to *something*, somewhere.

My next move is clear: I need to trace back and find its origin. Let's start by scrutinizing functions with similar names, likely within that module or related ones. I'll zero in on `ieee80211_tx_info_init` – or perhaps a very similar initialization routine. I have a feeling the answer lies in how that particular struct is initially set up.



42/3 2026/08/27 06:43 tool grepper
0m Args:
{
  "Expression": "IEEE80211_SKB_CB"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 3010 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/admtek/adm8211.c=302=static void adm8211_interrupt_tci(struct ieee80211_hw *dev)\n--\ndrivers/net/wireless/admtek/adm8211.c-321-\t\tskb = info-\u003eskb;\ndrivers/net/wireless/admtek/adm8211.c:322:\t\ttxi = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/admtek/adm8211.c-323-\n--\ndrivers/net/wireless/admtek/adm8211.c=1672=static void adm8211_tx(struct ieee80211_hw *dev,\n--\ndrivers/net/wireless/admtek/adm8211.c-1679-\tstruct ieee80211_hdr *hdr;\ndrivers/net/wireless/admtek/adm8211.c:1680:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/admtek/adm8211.c-1681-\tstruct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info);\n--\ndrivers/net/wireless/ath/ar5523/ar5523.c=746=static void ar5523_data_tx_cb(struct urb *urb)\n--\ndrivers/net/wireless/ath/ar5523/ar5523.c-748-\tstruct sk_buff *skb = urb-\u003econtext;\ndrivers/net/wireless/ath/ar5523/ar5523.c:749:\tstruct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ar5523/ar5523.c-750-\tstruct ar5523_tx_data *data = (struct ar5523_tx_data *)\n--\ndrivers/net/wireless/ath/ar5523/ar5523.c=772=static void ar5523_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ar5523/ar5523.c-775-{\ndrivers/net/wireless/ath/ar5523/ar5523.c:776:\tstruct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ar5523/ar5523.c-777-\tstruct ar5523_tx_data *data = (struct ar5523_tx_data *)\n--\ndrivers/net/wireless/ath/ath10k/core.h=140=static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath10k/core.h-143-\t\t     IEEE80211_TX_INFO_DRIVER_DATA_SIZE);\ndrivers/net/wireless/ath/ath10k/core.h:144:\treturn (struct ath10k_skb_cb *)\u0026IEEE80211_SKB_CB(skb)-\u003edriver_data;\ndrivers/net/wireless/ath/ath10k/core.h-145-}\n--\ndrivers/net/wireless/ath/ath10k/htt_tx.c=1149=static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb)\ndrivers/net/wireless/ath/ath10k/htt_tx.c-1150-{\ndrivers/net/wireless/ath/ath10k/htt_tx.c:1151:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/htt_tx.c-1152-\tstruct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);\n--\ndrivers/net/wireless/ath/ath10k/htt_tx.c=1384=static int ath10k_htt_tx_32(struct ath10k_htt *htt,\n--\ndrivers/net/wireless/ath/ath10k/htt_tx.c-1389-\tstruct device *dev = ar-\u003edev;\ndrivers/net/wireless/ath/ath10k/htt_tx.c:1390:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath10k/htt_tx.c-1391-\tstruct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);\n--\ndrivers/net/wireless/ath/ath10k/htt_tx.c=1589=static int ath10k_htt_tx_64(struct ath10k_htt *htt,\n--\ndrivers/net/wireless/ath/ath10k/htt_tx.c-1594-\tstruct device *dev = ar-\u003edev;\ndrivers/net/wireless/ath/ath10k/htt_tx.c:1595:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath10k/htt_tx.c-1596-\tstruct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);\n--\ndrivers/net/wireless/ath/ath10k/mac.c=3738=ath10k_mac_tx_h_get_txmode(struct ath10k *ar,\n--\ndrivers/net/wireless/ath/ath10k/mac.c-3746-\ndrivers/net/wireless/ath/ath10k/mac.c:3747:\tif (IEEE80211_SKB_CB(skb)-\u003eflags \u0026 IEEE80211_TX_CTL_HW_80211_ENCAP)\ndrivers/net/wireless/ath/ath10k/mac.c-3748-\t\treturn ATH10K_HW_TXRX_ETHERNET;\n--\ndrivers/net/wireless/ath/ath10k/mac.c=3796=static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/ath/ath10k/mac.c-3798-{\ndrivers/net/wireless/ath/ath10k/mac.c:3799:\tconst struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/mac.c-3800-\tconst struct ieee80211_hdr *hdr = (void *)skb-\u003edata;\n--\ndrivers/net/wireless/ath/ath10k/mac.c=3893=static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,\n--\ndrivers/net/wireless/ath/ath10k/mac.c-3900-\tstruct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/mac.c:3901:\tconst struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/mac.c-3902-\tbool is_data = ieee80211_is_data(hdr-\u003eframe_control) ||\n--\ndrivers/net/wireless/ath/ath10k/mac.c=4055=static int ath10k_mac_tx(struct ath10k *ar,\n--\ndrivers/net/wireless/ath/ath10k/mac.c-4061-\tstruct ieee80211_hw *hw = ar-\u003ehw;\ndrivers/net/wireless/ath/ath10k/mac.c:4062:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/mac.c-4063-\tconst struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);\n--\ndrivers/net/wireless/ath/ath10k/mac.c=4686=static void ath10k_mac_op_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath10k/mac.c-4691-\tstruct ath10k_htt *htt = \u0026ar-\u003ehtt;\ndrivers/net/wireless/ath/ath10k/mac.c:4692:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/mac.c-4693-\tstruct ieee80211_vif *vif = info-\u003econtrol.vif;\n--\ndrivers/net/wireless/ath/ath10k/mac.h=77=static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/ath/ath10k/mac.h-79-{\ndrivers/net/wireless/ath/ath10k/mac.h:80:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/mac.h-81-\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n--\ndrivers/net/wireless/ath/ath10k/txrx.c=14=static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)\ndrivers/net/wireless/ath/ath10k/txrx.c-15-{\ndrivers/net/wireless/ath/ath10k/txrx.c:16:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath10k/txrx.c-17-\n--\ndrivers/net/wireless/ath/ath10k/txrx.c=43=int ath10k_txrx_tx_unref(struct ath10k_htt *htt,\n--\ndrivers/net/wireless/ath/ath10k/txrx.c-98-\ndrivers/net/wireless/ath/ath10k/txrx.c:99:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath10k/txrx.c-100-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath10k/wmi-ops.h=489=ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)\ndrivers/net/wireless/ath/ath10k/wmi-ops.h-490-{\ndrivers/net/wireless/ath/ath10k/wmi-ops.h:491:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath10k/wmi-ops.h-492-\tstruct sk_buff *skb;\n--\ndrivers/net/wireless/ath/ath10k/wmi.c=2428=wmi_process_mgmt_tx_comp(struct ath10k *ar, struct mgmt_tx_compl_params *param)\n--\ndrivers/net/wireless/ath/ath10k/wmi.c-2448-\t\t\t msdu-\u003elen, DMA_TO_DEVICE);\ndrivers/net/wireless/ath/ath10k/wmi.c:2449:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath10k/wmi.c-2450-\tkfree(pkt_addr);\n--\ndrivers/net/wireless/ath/ath11k/core.h=1313=static inline struct ath11k_skb_cb *ATH11K_SKB_CB(struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath11k/core.h-1316-\t\t     IEEE80211_TX_INFO_DRIVER_DATA_SIZE);\ndrivers/net/wireless/ath/ath11k/core.h:1317:\treturn (struct ath11k_skb_cb *)\u0026IEEE80211_SKB_CB(skb)-\u003edriver_data;\ndrivers/net/wireless/ath/ath11k/core.h-1318-}\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c=16=ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)\ndrivers/net/wireless/ath/ath11k/dp_tx.c-17-{\ndrivers/net/wireless/ath/ath11k/dp_tx.c:18:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath11k/dp_tx.c-19-\tstruct ath11k_base *ab = arvif-\u003ear-\u003eab;\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c=82=int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c-87-\tstruct hal_tx_info ti = {};\ndrivers/net/wireless/ath/ath11k/dp_tx.c:88:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath11k/dp_tx.c-89-\tstruct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c=316=ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c-337-\tskb_cb = ATH11K_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath11k/dp_tx.c:338:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath11k/dp_tx.c-339-\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c=551=static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,\n--\ndrivers/net/wireless/ath/ath11k/dp_tx.c-582-\ndrivers/net/wireless/ath/ath11k/dp_tx.c:583:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath11k/dp_tx.c-584-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath11k/mac.c=6132=static void ath11k_mac_tx_mgmt_free(struct ath11k *ar, int buf_id)\n--\ndrivers/net/wireless/ath/ath11k/mac.c-6146-\ndrivers/net/wireless/ath/ath11k/mac.c:6147:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath11k/mac.c-6148-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath11k/mac.c=6174=static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif,\n--\ndrivers/net/wireless/ath/ath11k/mac.c-6201-\ndrivers/net/wireless/ath/ath11k/mac.c:6202:\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath11k/mac.c-6203-\tif (!(info-\u003eflags \u0026 IEEE80211_TX_CTL_HW_80211_ENCAP)) {\n--\ndrivers/net/wireless/ath/ath11k/mac.c=6502=static void ath11k_mac_op_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath11k/mac.c-6507-\tstruct ath11k *ar = hw-\u003epriv;\ndrivers/net/wireless/ath/ath11k/mac.c:6508:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath11k/mac.c-6509-\tstruct ieee80211_vif *vif = info-\u003econtrol.vif;\n--\ndrivers/net/wireless/ath/ath11k/wmi.c=662=int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,\n--\ndrivers/net/wireless/ath/ath11k/wmi.c-665-\tstruct ath11k_pdev_wmi *wmi = ar-\u003ewmi;\ndrivers/net/wireless/ath/ath11k/wmi.c:666:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame);\ndrivers/net/wireless/ath/ath11k/wmi.c-667-\tstruct wmi_mgmt_send_cmd *cmd;\n--\ndrivers/net/wireless/ath/ath11k/wmi.c=6014=static int wmi_process_mgmt_tx_comp(struct ath11k *ar,\n--\ndrivers/net/wireless/ath/ath11k/wmi.c-6037-\ndrivers/net/wireless/ath/ath11k/wmi.c:6038:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath11k/wmi.c-6039-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath12k/core.h=1316=static inline struct ath12k_skb_cb *ATH12K_SKB_CB(struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath12k/core.h-1319-\t\t     IEEE80211_TX_INFO_DRIVER_DATA_SIZE);\ndrivers/net/wireless/ath/ath12k/core.h:1320:\treturn (struct ath12k_skb_cb *)\u0026IEEE80211_SKB_CB(skb)-\u003edriver_data;\ndrivers/net/wireless/ath/ath12k/core.h-1321-}\n--\ndrivers/net/wireless/ath/ath12k/dp_tx.c=16=ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb)\ndrivers/net/wireless/ath/ath12k/dp_tx.c-17-{\ndrivers/net/wireless/ath/ath12k/dp_tx.c:18:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath12k/dp_tx.c-19-\n--\ndrivers/net/wireless/ath/ath12k/mac.c=9169=static void ath12k_mac_tx_mgmt_free(struct ath12k *ar, int buf_id)\n--\ndrivers/net/wireless/ath/ath12k/mac.c-9183-\ndrivers/net/wireless/ath/ath12k/mac.c:9184:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath12k/mac.c-9185-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath12k/mac.c=9211=static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_link_vif *arvif,\n--\ndrivers/net/wireless/ath/ath12k/mac.c-9233-\ndrivers/net/wireless/ath/ath12k/mac.c:9234:\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath12k/mac.c-9235-\tif ((skb_cb-\u003eflags \u0026 ATH12K_SKB_CIPHER_SET) \u0026\u0026\n--\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c=106=int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif,\n--\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c-114-\tstruct ath12k_tx_desc_info *tx_desc;\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c:115:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c-116-\tstruct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);\n--\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c=476=ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_dp *dp,\n--\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c-495-\tskb_cb = ATH12K_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c:496:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c-497-\n--\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c=737=static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev,\n--\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c-793-\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c:794:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath12k/wifi7/dp_tx.c-795-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath12k/wifi7/hw.c=901=static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath12k/wifi7/hw.c-905-\tstruct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);\ndrivers/net/wireless/ath/ath12k/wifi7/hw.c:906:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath12k/wifi7/hw.c-907-\tstruct ieee80211_vif *vif = info-\u003econtrol.vif;\n--\ndrivers/net/wireless/ath/ath12k/wmi.c=780=int ath12k_wmi_mgmt_send(struct ath12k_link_vif *arvif, u32 buf_id,\n--\ndrivers/net/wireless/ath/ath12k/wmi.c-785-\tstruct wmi_mgmt_send_cmd *cmd;\ndrivers/net/wireless/ath/ath12k/wmi.c:786:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame);\ndrivers/net/wireless/ath/ath12k/wmi.c-787-\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)frame-\u003edata;\n--\ndrivers/net/wireless/ath/ath12k/wmi.c=6436=static int wmi_process_mgmt_tx_comp(struct ath12k *ar, u32 desc_id,\n--\ndrivers/net/wireless/ath/ath12k/wmi.c-6459-\ndrivers/net/wireless/ath/ath12k/wmi.c:6460:\tinfo = IEEE80211_SKB_CB(msdu);\ndrivers/net/wireless/ath/ath12k/wmi.c-6461-\tmemset(\u0026info-\u003estatus, 0, sizeof(info-\u003estatus));\n--\ndrivers/net/wireless/ath/ath5k/base.c=768=ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,\n--\ndrivers/net/wireless/ath/ath5k/base.c-773-\tstruct sk_buff *skb = bf-\u003eskb;\ndrivers/net/wireless/ath/ath5k/base.c:774:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath5k/base.c-775-\tunsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;\n--\ndrivers/net/wireless/ath/ath5k/base.c=1711=ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,\n--\ndrivers/net/wireless/ath/ath5k/base.c-1721-\tah-\u003estats.tx_bytes_count += skb-\u003elen;\ndrivers/net/wireless/ath/ath5k/base.c:1722:\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath5k/base.c-1723-\n--\ndrivers/net/wireless/ath/ath5k/base.c=1855=ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf)\n--\ndrivers/net/wireless/ath/ath5k/base.c-1857-\tstruct sk_buff *skb = bf-\u003eskb;\ndrivers/net/wireless/ath/ath5k/base.c:1858:\tstruct\tieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath5k/base.c-1859-\tstruct ath5k_desc *ds;\n--\ndrivers/net/wireless/ath/ath9k/beacon.c=112=static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/beacon.c-146-\ndrivers/net/wireless/ath/ath9k/beacon.c:147:\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/beacon.c-148-\n--\ndrivers/net/wireless/ath/ath9k/channel.c=984=static void ath_scan_send_probe(struct ath_softc *sc,\n--\ndrivers/net/wireless/ath/ath9k/channel.c-998-\ndrivers/net/wireless/ath/ath9k/channel.c:999:\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/channel.c-1000-\tif (req-\u003eno_cck)\n--\ndrivers/net/wireless/ath/ath9k/common.c=276=int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)\ndrivers/net/wireless/ath/ath9k/common.c-277-{\ndrivers/net/wireless/ath/ath9k/common.c:278:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/common.c-279-\n--\ndrivers/net/wireless/ath/ath9k/dynack.c=207=void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,\n--\ndrivers/net/wireless/ath/ath9k/dynack.c-213-\tstruct ath_common *common = ath9k_hw_common(ah);\ndrivers/net/wireless/ath/ath9k/dynack.c:214:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/dynack.c-215-\tu32 dur = ts-\u003eduration;\n--\ndrivers/net/wireless/ath/ath9k/htc.h=319=static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)\ndrivers/net/wireless/ath/ath9k/htc.h-320-{\ndrivers/net/wireless/ath/ath9k/htc.h:321:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/htc.h-322-\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c=191=static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-230-\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c:231:\tinfo = IEEE80211_SKB_CB(beacon);\ndrivers/net/wireless/ath/ath9k/htc_drv_beacon.c-232-\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_ASSIGN_SEQ) {\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=214=static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-218-{\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:219:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-220-\tstruct ieee80211_mgmt *mgmt;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=260=static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-265-{\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:266:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-267-\tstruct ieee80211_hdr *hdr;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=340=int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-345-\tstruct ieee80211_hdr *hdr;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:346:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-347-\tstruct ieee80211_vif *vif = tx_info-\u003econtrol.vif;\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c=445=static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,\n--\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-465-\ttxok = tx_ctl-\u003etxok;\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c:466:\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/htc_drv_txrx.c-467-\tvif = tx_info-\u003econtrol.vif;\n--\ndrivers/net/wireless/ath/ath9k/link.c=201=static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)\n--\ndrivers/net/wireless/ath/ath9k/link.c-203-\tstruct ieee80211_hw *hw = sc-\u003ehw;\ndrivers/net/wireless/ath/ath9k/link.c:204:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/link.c-205-\tstruct ath_hw *ah = sc-\u003esc_ah;\n--\ndrivers/net/wireless/ath/ath9k/main.c=830=static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix)\n--\ndrivers/net/wireless/ath/ath9k/main.c-839-\ndrivers/net/wireless/ath/ath9k/main.c:840:\t\ttxinfo = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/main.c-841-\t\tfi = (struct ath_frame_info *)\u0026txinfo-\u003estatus.status_driver_data[0];\n--\ndrivers/net/wireless/ath/ath9k/tx99.c=40=static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)\n--\ndrivers/net/wireless/ath/ath9k/tx99.c-79-\ndrivers/net/wireless/ath/ath9k/tx99.c:80:\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/tx99.c-81-\tmemset(tx_info, 0, sizeof(*tx_info));\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=89=static void ath_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)\ndrivers/net/wireless/ath/ath9k/xmit.c-90-{\ndrivers/net/wireless/ath/ath9k/xmit.c:91:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-92-\tstruct ieee80211_sta *sta = info-\u003estatus.status_driver_data[0];\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=145=static struct ath_frame_info *get_frame_info(struct sk_buff *skb)\ndrivers/net/wireless/ath/ath9k/xmit.c-146-{\ndrivers/net/wireless/ath/ath9k/xmit.c:147:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-148-\tBUILD_BUG_ON(sizeof(struct ath_frame_info) \u003e\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=198=static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-202-\ndrivers/net/wireless/ath/ath9k/xmit.c:203:\ttx_info = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-204-\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=483=static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-506-\tskb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:507:\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-508-\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-574-\t\tskb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:575:\t\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-576-\t\tfi = get_frame_info(skb);\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=701=static bool bf_is_ampdu_not_probing(struct ath_buf *bf)\ndrivers/net/wireless/ath/ath9k/xmit.c-702-{\ndrivers/net/wireless/ath/ath9k/xmit.c:703:    struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-704-    return bf_isampdu(bf) \u0026\u0026 !(info-\u003eflags \u0026 IEEE80211_TX_CTL_RATE_CTRL_PROBE);\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=725=static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-758-\t\tif (!flush) {\ndrivers/net/wireless/ath/ath9k/xmit.c:759:\t\t\tinfo = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-760-\t\t\tmemcpy(info-\u003econtrol.rates, bf-\u003erates,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=774=static bool ath_lookup_legacy(struct ath_buf *bf)\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-781-\tskb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:782:\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-783-\trates = tx_info-\u003econtrol.rates;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=796=static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-807-\tskb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:808:\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-809-\trates = bf-\u003erates;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=938=ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-968-\ndrivers/net/wireless/ath/ath9k/xmit.c:969:\t\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-970-\t\ttx_info-\u003eflags \u0026= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1027=ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1055-\ndrivers/net/wireless/ath/ath9k/xmit.c:1056:\t\t\ttx_info = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-1057-\t\t\tif ((tx_info-\u003eflags \u0026 IEEE80211_TX_CTL_RATE_CTRL_PROBE) ||\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1174=static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1188-\tfi = get_frame_info(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c:1189:\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-1190-\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1260=static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1275-\tskb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:1276:\ttx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-1277-\trates = bf-\u003erates;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1403=static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1418-\t\tstruct sk_buff *skb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:1419:\t\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-1420-\t\tstruct ath_frame_info *fi = get_frame_info(skb);\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1496=ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1518-\ndrivers/net/wireless/ath/ath9k/xmit.c:1519:\t\ttx_info = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-1520-\t\tif (tx_info-\u003eflags \u0026 IEEE80211_TX_CTL_AMPDU) {\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1529=static int ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1543-\ndrivers/net/wireless/ath/ath9k/xmit.c:1544:\ttx_info = IEEE80211_SKB_CB(bf-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-1545-\taggr = !!(tx_info-\u003eflags \u0026 IEEE80211_TX_CTL_AMPDU);\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=1690=void ath9k_release_buffered_frames(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-1743-\ndrivers/net/wireless/ath/ath9k/xmit.c:1744:\tinfo = IEEE80211_SKB_CB(bf_tail-\u003ebf_mpdu);\ndrivers/net/wireless/ath/ath9k/xmit.c-1745-\tinfo-\u003eflags |= IEEE80211_TX_STATUS_EOSP;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2106=static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2108-{\ndrivers/net/wireless/ath/ath9k/xmit.c:2109:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2110-\tstruct ath_frame_info *fi = get_frame_info(skb);\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2129=static void setup_frame_info(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2133-{\ndrivers/net/wireless/ath/ath9k/xmit.c:2134:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2135-\tstruct ieee80211_key_conf *hw_key = tx_info-\u003econtrol.hw_key;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2263=void ath_assign_seq(struct ath_common *common, struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2265-\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb-\u003edata;\ndrivers/net/wireless/ath/ath9k/xmit.c:2266:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2267-\tstruct ieee80211_vif *vif = info-\u003econtrol.vif;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2285=static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2288-\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb-\u003edata;\ndrivers/net/wireless/ath/ath9k/xmit.c:2289:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2290-\tstruct ieee80211_sta *sta = txctl-\u003esta;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2323=int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2325-{\ndrivers/net/wireless/ath/ath9k/xmit.c:2326:\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2327-\tstruct ieee80211_sta *sta = txctl-\u003esta;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2455=static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2458-{\ndrivers/net/wireless/ath/ath9k/xmit.c:2459:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2460-\tstruct ath_common *common = ath9k_hw_common(sc-\u003esc_ah);\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2507=static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2512-\tstruct sk_buff *skb = bf-\u003ebf_mpdu;\ndrivers/net/wireless/ath/ath9k/xmit.c:2513:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2514-\tunsigned long flags;\n--\ndrivers/net/wireless/ath/ath9k/xmit.c=2563=static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,\n--\ndrivers/net/wireless/ath/ath9k/xmit.c-2568-\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\ndrivers/net/wireless/ath/ath9k/xmit.c:2569:\tstruct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/ath9k/xmit.c-2570-\tstruct ieee80211_hw *hw = sc-\u003ehw;\n--\ndrivers/net/wireless/ath/carl9170/debug.c=279=static void carl9170_debugfs_format_frame(struct ar9170 *ar,\n--\ndrivers/net/wireless/ath/carl9170/debug.c-283-\tstruct _carl9170_tx_superframe *txc = (void *) skb-\u003edata;\ndrivers/net/wireless/ath/carl9170/debug.c:284:\tstruct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/carl9170/debug.c-285-\tstruct carl9170_tx_info *arinfo = (void *) txinfo-\u003erate_driver_data;\n--\ndrivers/net/wireless/ath/carl9170/main.c=219=static void carl9170_flush(struct ar9170 *ar, bool drop_queued)\n--\ndrivers/net/wireless/ath/carl9170/main.c-234-\ndrivers/net/wireless/ath/carl9170/main.c:235:\t\t\t\tinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/carl9170/main.c-236-\t\t\t\tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_AMPDU)\n--\ndrivers/net/wireless/ath/carl9170/rx.c=576=static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)\n--\ndrivers/net/wireless/ath/carl9170/rx.c-607-\ndrivers/net/wireless/ath/carl9170/rx.c:608:\t\t\ttx_info = IEEE80211_SKB_CB(entry_skb);\ndrivers/net/wireless/ath/carl9170/rx.c-609-\t\t\ttx_info-\u003eflags |= IEEE80211_TX_STAT_ACK;\n--\ndrivers/net/wireless/ath/carl9170/tx.c=331=void carl9170_tx_get_skb(struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/carl9170/tx.c-333-\tstruct carl9170_tx_info *arinfo = (void *)\ndrivers/net/wireless/ath/carl9170/tx.c:334:\t\t(IEEE80211_SKB_CB(skb))-\u003erate_driver_data;\ndrivers/net/wireless/ath/carl9170/tx.c-335-\tkref_get(\u0026arinfo-\u003eref);\n--\ndrivers/net/wireless/ath/carl9170/tx.c=338=int carl9170_tx_put_skb(struct sk_buff *skb)\n--\ndrivers/net/wireless/ath/carl9170/tx.c-340-\tstruct carl9170_tx_info *arinfo = (void *)\ndrivers/net/wireless/ath/carl9170/tx.c:341:\t\t(IEEE80211_SKB_CB(skb))-\u003erate_driver_data;\ndrivers/net/wireless/ath/carl9170/tx.c-342-\n--\ndrivers/net/wireless/ath/carl9170/tx.c=476=void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,\n--\ndrivers/net/wireless/ath/carl9170/tx.c-482-\ndrivers/net/wireless/ath/carl9170/tx.c:483:\ttxinfo = IEEE80211_SKB_CB(skb);\ndrivers/net/wireless/ath/carl9170/tx.c-484-\n--\ndrivers/net/wireless/ath/carl9170/tx.c=500=void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)\ndrivers/net/wireless/ath/carl9170/tx.c-501-{\n\n"
}

43/3 2026/08/27 06:43 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 41409
							output: 27
							thoughts: 57
						

Thoughts:
Here's my take on the situation:

**Investigating a Suspected IEEE 802.11 TX Initialization Issue**

Okay, hold on a second. Something's not quite right. I was under the impression that there was a function called `ieee80211_tx_info_init`, but my intuition (and memory) is telling me that's not actually the correct name. That rings a bell, but it's not the right bell. I need to double-check my assumptions here. Time to dig into the code. Specifically, the `net/mac80211/tx.c` file should hold the key, or at least the relevant functions. I'll need to confirm how the `IEEE80211_SKB_CB` structure is actually initialized. I'm looking for the canonical way this happens. I need to make sure I'm following the correct path for my analysis.



44/3 2026/08/27 06:43 tool grepper
0m Args:
{
  "Expression": "memset.*IEEE80211_SKB_CB"
}

Results:
{
  "Output": "drivers/net/wireless/ti/wlcore/main.c=1390=static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)\n--\ndrivers/net/wireless/ti/wlcore/main.c-1418-\tskb_set_queue_mapping(skb, 0);\ndrivers/net/wireless/ti/wlcore/main.c:1419:\tmemset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));\ndrivers/net/wireless/ti/wlcore/main.c-1420-\n"
}

45/3 2026/08/27 06:43 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 41872
							output: 17
							thoughts: 27
						

Thoughts:
Okay, here's my interpretation of that thought process, written as a first-person summary, keeping in mind I'm dealing with an expert audience:

**Quick Scan and Diagnostic Check**

Right, I see a `memset` call right off the bat, specifically targeting `info`. My internal alarm bells are already going off, as `memset` is a classic tool, but its application can sometimes be a code smell, especially when dealing with complex data structures. I need to understand *why* this is happening. So, I need to quickly determine whether the clearing is a necessary precaution or an indicator of potential issues with memory management or initialization. Let's dig deeper; I'm going to scan the code for every instance where `memset` is used on the `info` structure or its members. A quick search for `memset.*info` should give me a good overview of how and where the structure is being treated. This should help to give me a better understanding of the code's intent.



46/3 2026/08/27 06:43 tool grepper
0m Args:
{
  "Expression": "memset.*info"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 7074 lines.\nUse more precise expression if possible.\n\nDocumentation/bpf/bpf_iterators.rst=407=First,  fill the ``bpf_iter_attach_opts`` struct as shown below:\n--\nDocumentation/bpf/bpf_iterators.rst-412-  union bpf_iter_link_info linfo;\nDocumentation/bpf/bpf_iterators.rst:413:  memset(\u0026linfo, 0, sizeof(linfo));\nDocumentation/bpf/bpf_iterators.rst-414-  linfo.task.pid = getpid();\n--\nDocumentation/bpf/bpf_iterators.rst=441=The whole program looks like the following code:\n--\nDocumentation/bpf/bpf_iterators.rst-489-                return;\nDocumentation/bpf/bpf_iterators.rst:490:        memset(\u0026linfo, 0, sizeof(linfo));\nDocumentation/bpf/bpf_iterators.rst-491-        linfo.task.pid = getpid();\n--\nDocumentation/bpf/bpf_iterators.rst=549=The user space program would look like the following block:\n--\nDocumentation/bpf/bpf_iterators.rst-560-          skel-\u003ebss-\u003etarget_pid = getpid(); /* process ID.  For thread id, use gettid() */\nDocumentation/bpf/bpf_iterators.rst:561:          memset(\u0026linfo, 0, sizeof(linfo));\nDocumentation/bpf/bpf_iterators.rst-562-          linfo.task.pid = getpid();\n--\nDocumentation/driver-api/gpio/legacy-boards.rst=249=software nodes using the ``fwnode`` field in struct platform_device_info.\n--\nDocumentation/driver-api/gpio/legacy-boards.rst-264-\nDocumentation/driver-api/gpio/legacy-boards.rst:265:  \tmemset(\u0026pdev_info, 0, sizeof(pdev_info));\nDocumentation/driver-api/gpio/legacy-boards.rst-266-  \tpdev_info.name = MYBOARD_GPIO_CONTROLLER;\n--\nDocumentation/driver-api/gpio/legacy-boards.rst-274-\nDocumentation/driver-api/gpio/legacy-boards.rst:275:  \tmemset(\u0026pdev_info, 0, sizeof(pdev_info));\nDocumentation/driver-api/gpio/legacy-boards.rst-276-  \tpdev_info.name = \"leds-gpio\";\n--\nDocumentation/driver-api/gpio/legacy-boards.rst-285-\nDocumentation/driver-api/gpio/legacy-boards.rst:286:  \tmemset(\u0026pdev_info, 0, sizeof(pdev_info));\nDocumentation/driver-api/gpio/legacy-boards.rst-287-  \tpdev_info.name = \"gpio-keys\";\n--\nDocumentation/i2c/instantiating-devices.rst=145=Example (from the nxp OHCI driver):\n--\nDocumentation/i2c/instantiating-devices.rst-158-\ti2c_adap = i2c_get_adapter(2);\nDocumentation/i2c/instantiating-devices.rst:159:\tmemset(\u0026i2c_info, 0, sizeof(struct i2c_board_info));\nDocumentation/i2c/instantiating-devices.rst-160-\tstrscpy(i2c_info.type, \"isp1301_nxp\", sizeof(i2c_info.type));\n--\nDocumentation/networking/kcm.rst=128=a KCM socket. This is accomplished by an ioctl on a KCM socket::\n--\nDocumentation/networking/kcm.rst-136-\nDocumentation/networking/kcm.rst:137:  memset(\u0026info, 0, sizeof(info));\nDocumentation/networking/kcm.rst-138-\n--\nDocumentation/networking/kcm.rst=148=ioctl on a KCM socket for the multiplexor. e.g.::\n--\nDocumentation/networking/kcm.rst-157-\nDocumentation/networking/kcm.rst:158:  memset(\u0026info, 0, sizeof(info));\nDocumentation/networking/kcm.rst-159-\n--\nDocumentation/networking/kcm.rst=173=Unattaching a transport socket from a multiplexor is straightforward. An\n--\nDocumentation/networking/kcm.rst-182-\nDocumentation/networking/kcm.rst:183:  memset(\u0026info, 0, sizeof(info));\nDocumentation/networking/kcm.rst-184-\n--\narch/arc/kernel/setup.c=289=static char *arc_cpu_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len)\n--\narch/arc/kernel/setup.c-298-\narch/arc/kernel/setup.c:299:\tmemset(info, 0, sizeof(struct cpuinfo_arc));\narch/arc/kernel/setup.c-300-\n--\narch/arm/kernel/process.c=218=void flush_thread(void)\n--\narch/arm/kernel/process.c-224-\narch/arm/kernel/process.c:225:\tmemset(\u0026tsk-\u003ethread.debug, 0, sizeof(struct debug_info));\narch/arm/kernel/process.c-226-\tmemset(\u0026thread-\u003efpstate, 0, sizeof(union fp_state));\n--\narch/arm/mach-imx/pm-imx6.c=464=static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)\n--\narch/arm/mach-imx/pm-imx6.c-513-\narch/arm/mach-imx/pm-imx6.c:514:\tmemset(suspend_ocram_base, 0, sizeof(*pm_info));\narch/arm/mach-imx/pm-imx6.c-515-\tpm_info = suspend_ocram_base;\n--\narch/arm/mach-omap2/pm33xx-core.c=361=int __init amx3_common_pm_init(void)\n--\narch/arm/mach-omap2/pm33xx-core.c-367-\narch/arm/mach-omap2/pm33xx-core.c:368:\tmemset(\u0026devinfo, 0, sizeof(devinfo));\narch/arm/mach-omap2/pm33xx-core.c-369-\tdevinfo.name = \"pm33xx\";\n--\narch/arm64/kernel/ptrace.c=227=void ptrace_hw_copy_thread(struct task_struct *tsk)\narch/arm64/kernel/ptrace.c-228-{\narch/arm64/kernel/ptrace.c:229:\tmemset(\u0026tsk-\u003ethread.debug, 0, sizeof(struct debug_info));\narch/arm64/kernel/ptrace.c-230-}\n--\narch/mips/cavium-octeon/setup.c=659=void __init prom_init(void)\n--\narch/mips/cavium-octeon/setup.c-676-\tsysinfo = cvmx_sysinfo_get();\narch/mips/cavium-octeon/setup.c:677:\tmemset(sysinfo, 0, sizeof(*sysinfo));\narch/mips/cavium-octeon/setup.c-678-\tsysinfo-\u003esystem_dram_size = octeon_bootinfo-\u003edram_size \u003c\u003c 20;\n--\narch/parisc/kernel/drivers.c=989=static __init int qemu_print_iodc_data(struct device *lin_dev, void *data)\n--\narch/parisc/kernel/drivers.c-1022-\t\tmod_path.path.mod = dev-\u003ehw_path;\narch/parisc/kernel/drivers.c:1023:\t\tmemset(\u0026pdc_mod_info, 0, sizeof(pdc_mod_info));\narch/parisc/kernel/drivers.c-1024-\t\tstatus = pdc_system_map_find_mods(\u0026pdc_mod_info,\n--\narch/parisc/kernel/processor.c=81=static int __init processor_probe(struct parisc_device *dev)\n--\narch/parisc/kernel/processor.c-165-\tif (cpuid)\narch/parisc/kernel/processor.c:166:\t\tmemset(p, 0, sizeof(struct cpuinfo_parisc));\narch/parisc/kernel/processor.c-167-\n--\narch/parisc/kernel/unwind.c=392=void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, \n--\narch/parisc/kernel/unwind.c-394-{\narch/parisc/kernel/unwind.c:395:\tmemset(info, 0, sizeof(struct unwind_frame_info));\narch/parisc/kernel/unwind.c-396-\tinfo-\u003et = t;\n--\narch/parisc/mm/init.c=743=void btlb_init_per_cpu(void)\n--\narch/parisc/mm/init.c-751-\telse if (pdc_btlb_info(\u0026btlb_info) \u003c 0) {\narch/parisc/mm/init.c:752:\t\tmemset(\u0026btlb_info, 0, sizeof btlb_info);\narch/parisc/mm/init.c-753-\t}\n--\narch/powerpc/kernel/fadump.c=816=static void fadump_free_mem_ranges(struct fadump_mrange_info *mrange_info)\n--\narch/powerpc/kernel/fadump.c-823-\tkfree(mrange_info-\u003emem_ranges);\narch/powerpc/kernel/fadump.c:824:\tmemset((void *)((u64)mrange_info + RNG_NAME_SZ), 0,\narch/powerpc/kernel/fadump.c-825-\t       (sizeof(struct fadump_mrange_info) - RNG_NAME_SZ));\n--\narch/powerpc/kernel/fadump.c=1093=static unsigned long init_fadump_header(unsigned long addr)\n--\narch/powerpc/kernel/fadump.c-1102-\narch/powerpc/kernel/fadump.c:1103:\tmemset(fdh, 0, sizeof(struct fadump_crash_info_header));\narch/powerpc/kernel/fadump.c-1104-\tfdh-\u003emagic_number = FADUMP_CRASH_INFO_MAGIC;\n--\narch/powerpc/kvm/book3s_64_mmu_radix.c=1198=int kvmhv_get_rmmu_info(struct kvm *kvm, struct kvm_ppc_rmmu_info *info)\n--\narch/powerpc/kvm/book3s_64_mmu_radix.c-1203-\t\treturn -EINVAL;\narch/powerpc/kvm/book3s_64_mmu_radix.c:1204:\tmemset(info, 0, sizeof(*info));\narch/powerpc/kvm/book3s_64_mmu_radix.c-1205-\n--\narch/powerpc/kvm/book3s_hv.c=3794=static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)\n--\narch/powerpc/kvm/book3s_hv.c-3901-\t\tsip = \u0026split_info;\narch/powerpc/kvm/book3s_hv.c:3902:\t\tmemset(\u0026split_info, 0, sizeof(split_info));\narch/powerpc/kvm/book3s_hv.c-3903-\t\tfor (sub = 0; sub \u003c core_info.n_subcores; ++sub)\n--\narch/powerpc/kvm/powerpc.c=2388=int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)\n--\narch/powerpc/kvm/powerpc.c-2396-\t\tstruct kvm_ppc_pvinfo pvinfo;\narch/powerpc/kvm/powerpc.c:2397:\t\tmemset(\u0026pvinfo, 0, sizeof(pvinfo));\narch/powerpc/kvm/powerpc.c-2398-\t\tr = kvm_vm_ioctl_get_pvinfo(\u0026pvinfo);\n--\narch/powerpc/kvm/powerpc.c-2442-\narch/powerpc/kvm/powerpc.c:2443:\t\tmemset(\u0026info, 0, sizeof(info));\narch/powerpc/kvm/powerpc.c-2444-\t\tr = kvm-\u003earch.kvm_ops-\u003eget_smmu_info(kvm, \u0026info);\n--\narch/powerpc/platforms/powernv/opal-prd.c=271=static long opal_prd_ioctl(struct file *file, unsigned int cmd,\n--\narch/powerpc/platforms/powernv/opal-prd.c-279-\tcase OPAL_PRD_GET_INFO:\narch/powerpc/platforms/powernv/opal-prd.c:280:\t\tmemset(\u0026info, 0, sizeof(info));\narch/powerpc/platforms/powernv/opal-prd.c-281-\t\tinfo.version = OPAL_PRD_KERNEL_VERSION;\n--\narch/s390/kernel/crash_dump.c=352=static void *nt_prpsinfo(void *ptr)\n--\narch/s390/kernel/crash_dump.c-355-\narch/s390/kernel/crash_dump.c:356:\tmemset(\u0026prpsinfo, 0, sizeof(prpsinfo));\narch/s390/kernel/crash_dump.c-357-\tprpsinfo.pr_sname = 'R';\n--\narch/s390/kernel/lgr.c=116=static void lgr_info_get(struct lgr_info *lgr_info)\n--\narch/s390/kernel/lgr.c-119-\narch/s390/kernel/lgr.c:120:\tmemset(lgr_info, 0, sizeof(*lgr_info));\narch/s390/kernel/lgr.c-121-\tstfle(lgr_info-\u003estfle_fac_list, ARRAY_SIZE(lgr_info-\u003estfle_fac_list));\n--\narch/s390/kernel/perf_event.c=101=static void print_debug_cf(void)\n--\narch/s390/kernel/perf_event.c-105-\narch/s390/kernel/perf_event.c:106:\tmemset(\u0026cf_info, 0, sizeof(cf_info));\narch/s390/kernel/perf_event.c-107-\tif (!qctri(\u0026cf_info))\n--\narch/s390/kvm/s390/interrupt.c=811=static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)\n--\narch/s390/kvm/s390/interrupt.c-820-\tclear_bit(IRQ_PEND_PROG, \u0026li-\u003epending_irqs);\narch/s390/kvm/s390/interrupt.c:821:\tmemset(\u0026li-\u003eirq.pgm, 0, sizeof(pgm_info));\narch/s390/kvm/s390/interrupt.c-822-\tspin_unlock(\u0026li-\u003elock);\n--\narch/sparc/kernel/leon_pci_grpci2.c=686=static int grpci2_of_probe(struct platform_device *ofdev)\n--\narch/sparc/kernel/leon_pci_grpci2.c-783-\t */\narch/sparc/kernel/leon_pci_grpci2.c:784:\tmemset(\u0026priv-\u003einfo.io_space, 0, sizeof(struct resource));\narch/sparc/kernel/leon_pci_grpci2.c-785-\tpriv-\u003einfo.io_space.name = \"GRPCI2 PCI I/O Space\";\n--\narch/sparc/kernel/leon_pci_grpci2.c-793-\t */\narch/sparc/kernel/leon_pci_grpci2.c:794:\tmemset(\u0026priv-\u003einfo.mem_space, 0, sizeof(struct resource));\narch/sparc/kernel/leon_pci_grpci2.c-795-\tpriv-\u003einfo.mem_space.name = \"GRPCI2 PCI MEM Space\";\n--\narch/x86/boot/video-vesa.c=31=static int vesa_probe(void)\n--\narch/x86/boot/video-vesa.c-62-\narch/x86/boot/video-vesa.c:63:\t\tmemset(\u0026vminfo, 0, sizeof(vminfo)); /* Just in case... */\narch/x86/boot/video-vesa.c-64-\n--\narch/x86/boot/video-vesa.c=104=static int vesa_set_mode(struct mode_info *mode)\n--\narch/x86/boot/video-vesa.c-109-\narch/x86/boot/video-vesa.c:110:\tmemset(\u0026vminfo, 0, sizeof(vminfo)); /* Just in case... */\narch/x86/boot/video-vesa.c-111-\n--\narch/x86/boot/video-vesa.c=236=void vesa_store_edid(void)\n--\narch/x86/boot/video-vesa.c-241-\t/* Apparently used as a nonsense token... */\narch/x86/boot/video-vesa.c:242:\tmemset(\u0026boot_params.edid_info, 0x13, sizeof(boot_params.edid_info));\narch/x86/boot/video-vesa.c-243-\n--\narch/x86/kernel/apic/vector.c=74=void init_irq_alloc_info(struct irq_alloc_info *info,\n--\narch/x86/kernel/apic/vector.c-76-{\narch/x86/kernel/apic/vector.c:77:\tmemset(info, 0, sizeof(*info));\narch/x86/kernel/apic/vector.c-78-\tinfo-\u003emask = mask;\n--\narch/x86/kernel/cpu/cpuid_parser.c=14=static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_output *out)\n--\narch/x86/kernel/cpu/cpuid_parser.c-20-\narch/x86/kernel/cpu/cpuid_parser.c:21:\tmemset(out-\u003einfo, 0, sizeof(*out-\u003einfo));\narch/x86/kernel/cpu/cpuid_parser.c-22-}\n--\narch/x86/kernel/cpu/sgx/ioctl.c=58=static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs)\n--\narch/x86/kernel/cpu/sgx/ioctl.c-105-\tpginfo.secs = 0;\narch/x86/kernel/cpu/sgx/ioctl.c:106:\tmemset(\u0026secinfo, 0, sizeof(secinfo));\narch/x86/kernel/cpu/sgx/ioctl.c-107-\n--\narch/x86/kernel/cpu/sgx/ioctl.c=716=sgx_enclave_restrict_permissions(struct sgx_encl *encl,\n--\narch/x86/kernel/cpu/sgx/ioctl.c-725-\narch/x86/kernel/cpu/sgx/ioctl.c:726:\tmemset(\u0026secinfo, 0, sizeof(secinfo));\narch/x86/kernel/cpu/sgx/ioctl.c-727-\tsecinfo.flags = modp-\u003epermissions \u0026 SGX_SECINFO_PERMISSION_MASK;\n--\narch/x86/kernel/cpu/sgx/ioctl.c=871=static long sgx_enclave_modify_types(struct sgx_encl *encl,\n--\narch/x86/kernel/cpu/sgx/ioctl.c-891-\narch/x86/kernel/cpu/sgx/ioctl.c:892:\tmemset(\u0026secinfo, 0, sizeof(secinfo));\narch/x86/kernel/cpu/sgx/ioctl.c-893-\n--\narch/x86/kernel/cpu/sgx/ioctl.c=1071=static long sgx_encl_remove_pages(struct sgx_encl *encl,\n--\narch/x86/kernel/cpu/sgx/ioctl.c-1080-\narch/x86/kernel/cpu/sgx/ioctl.c:1081:\tmemset(\u0026secinfo, 0, sizeof(secinfo));\narch/x86/kernel/cpu/sgx/ioctl.c-1082-\tsecinfo.flags = SGX_SECINFO_R | SGX_SECINFO_W | SGX_SECINFO_X;\n--\narch/x86/kernel/kexec-bzimage64.c=301=setup_boot_parameters(struct kimage *image, struct boot_params *params,\n--\narch/x86/kernel/kexec-bzimage64.c-324-\t/* Default APM info */\narch/x86/kernel/kexec-bzimage64.c:325:\tmemset(\u0026params-\u003eapm_bios_info, 0, sizeof(params-\u003eapm_bios_info));\narch/x86/kernel/kexec-bzimage64.c-326-\narch/x86/kernel/kexec-bzimage64.c-327-\t/* Default drive info */\narch/x86/kernel/kexec-bzimage64.c:328:\tmemset(\u0026params-\u003ehd0_info, 0, sizeof(params-\u003ehd0_info));\narch/x86/kernel/kexec-bzimage64.c:329:\tmemset(\u0026params-\u003ehd1_info, 0, sizeof(params-\u003ehd1_info));\narch/x86/kernel/kexec-bzimage64.c-330-\n--\narch/x86/kernel/tls.c=198=static void fill_user_desc(struct user_desc *info, int idx,\n--\narch/x86/kernel/tls.c-201-{\narch/x86/kernel/tls.c:202:\tmemset(info, 0, sizeof(*info));\narch/x86/kernel/tls.c-203-\tinfo-\u003eentry_number = idx;\n--\narch/x86/kvm/x86.c=5983=static void prepare_emulation_failure_exit(struct kvm_vcpu *vcpu, u64 *data,\n--\narch/x86/kvm/x86.c-5993-\t */\narch/x86/kvm/x86.c:5994:\tmemset(\u0026info, 0, sizeof(info));\narch/x86/kvm/x86.c-5995-\n--\narch/x86/kvm/xen.c=320=static void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, bool atomic)\n--\narch/x86/kvm/xen.c-533-\t\t */\narch/x86/kvm/xen.c:534:\t\tmemset(\u0026rs, 0, offsetof(struct vcpu_runstate_info, state_entry_time));\narch/x86/kvm/xen.c-535-#endif\n--\narch/x86/um/tls_32.c=71=static inline void clear_user_desc(struct user_desc* info)\n--\narch/x86/um/tls_32.c-73-\t/* Postcondition: LDT_empty(info) returns true. */\narch/x86/um/tls_32.c:74:\tmemset(info, 0, sizeof(*info));\narch/x86/um/tls_32.c-75-\n--\narch/x86/xen/mmu_pv.c=1205=static void __init xen_pagetable_p2m_free(void)\n--\narch/x86/xen/mmu_pv.c-1216-\t/* using __ka address and sticking INVALID_P2M_ENTRY! */\narch/x86/xen/mmu_pv.c:1217:\tmemset((void *)xen_start_info-\u003emfn_list, 0xff, size);\narch/x86/xen/mmu_pv.c-1218-\n--\ncrypto/asymmetric_keys/public_key.c=173=static int software_key_query(const struct kernel_pkey_params *params,\n--\ncrypto/asymmetric_keys/public_key.c-198-\ncrypto/asymmetric_keys/public_key.c:199:\tmemset(info, 0, sizeof(*info));\ncrypto/asymmetric_keys/public_key.c-200-\n--\ncrypto/echainiv.c=26=static int echainiv_encrypt(struct aead_request *req)\n--\ncrypto/echainiv.c-54-\tseqno = be64_to_cpu(nseqno);\ncrypto/echainiv.c:55:\tmemset(info, 0, ivsize);\ncrypto/echainiv.c-56-\n--\ndrivers/accel/ethosu/ethosu_drv.c=219=static int ethosu_reset(struct ethosu_device *ethosudev)\n--\ndrivers/accel/ethosu/ethosu_drv.c-251-\tif (ethosudev-\u003esram)\ndrivers/accel/ethosu/ethosu_drv.c:252:\t\tmemset_io(ethosudev-\u003esram, 0, ethosudev-\u003enpu_info.sram_size);\ndrivers/accel/ethosu/ethosu_drv.c-253-\n--\ndrivers/accel/habanalabs/common/device.c=2864=void hl_enable_err_info_capture(struct hl_error_info *captured_err_info)\n--\ndrivers/accel/habanalabs/common/device.c-2866-\tvfree(captured_err_info-\u003epage_fault_info.user_mappings);\ndrivers/accel/habanalabs/common/device.c:2867:\tmemset(captured_err_info, 0, sizeof(struct hl_error_info));\ndrivers/accel/habanalabs/common/device.c-2868-\tatomic_set(\u0026captured_err_info-\u003ecs_timeout.write_enable, 1);\n--\ndrivers/accel/habanalabs/common/firmware_if.c=858=int hl_fw_cpucp_info_get(struct hl_device *hdev,\n--\ndrivers/accel/habanalabs/common/firmware_if.c-878-\ndrivers/accel/habanalabs/common/firmware_if.c:879:\tmemset(cpucp_info_cpu_addr, 0, sizeof(struct cpucp_info));\ndrivers/accel/habanalabs/common/firmware_if.c-880-\n--\ndrivers/accel/habanalabs/common/firmware_if.c=1008=int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size)\n--\ndrivers/accel/habanalabs/common/firmware_if.c-1023-\ndrivers/accel/habanalabs/common/firmware_if.c:1024:\tmemset(eeprom_info_cpu_addr, 0, max_size);\ndrivers/accel/habanalabs/common/firmware_if.c-1025-\n--\ndrivers/accel/habanalabs/common/firmware_if.c=1282=int hl_fw_dram_replaced_row_get(struct hl_device *hdev,\n--\ndrivers/accel/habanalabs/common/firmware_if.c-1299-\ndrivers/accel/habanalabs/common/firmware_if.c:1300:\tmemset(cpucp_repl_rows_info_cpu_addr, 0, sizeof(struct cpucp_hbm_row_info));\ndrivers/accel/habanalabs/common/firmware_if.c-1301-\n--\ndrivers/accel/habanalabs/gaudi/gaudi.c=6948=static void gaudi_handle_qman_err_generic(struct hl_device *hdev,\n--\ndrivers/accel/habanalabs/gaudi/gaudi.c-6985-\t\t\t\thdev-\u003ecaptured_err_info.undef_opcode.write_enable) {\ndrivers/accel/habanalabs/gaudi/gaudi.c:6986:\t\t\tmemset(\u0026hdev-\u003ecaptured_err_info.undef_opcode, 0,\ndrivers/accel/habanalabs/gaudi/gaudi.c-6987-\t\t\t\t\t\tsizeof(hdev-\u003ecaptured_err_info.undef_opcode));\n--\ndrivers/acpi/acpi_platform.c=141=struct platform_device *acpi_create_platform_device(struct acpi_device *adev,\n--\ndrivers/acpi/acpi_platform.c-196-\ndrivers/acpi/acpi_platform.c:197:\tmemset(\u0026pdevinfo, 0, sizeof(pdevinfo));\ndrivers/acpi/acpi_platform.c-198-\t/*\n--\ndrivers/acpi/acpica/dbexec.c=345=acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)\n--\ndrivers/acpi/acpica/dbexec.c-388-\ndrivers/acpi/acpica/dbexec.c:389:\tmemset(\u0026acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));\ndrivers/acpi/acpica/dbexec.c-390-\tstrcpy(name_string, name);\n--\ndrivers/acpi/acpica/dbexec.c=657=acpi_db_create_execution_thread(char *method_name_arg,\n--\ndrivers/acpi/acpica/dbexec.c-662-\ndrivers/acpi/acpica/dbexec.c:663:\tmemset(\u0026acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));\ndrivers/acpi/acpica/dbexec.c-664-\tacpi_gbl_db_method_info.name = method_name_arg;\n--\ndrivers/acpi/acpica/dbexec.c=720=acpi_db_create_execution_threads(char *num_threads_arg,\n--\ndrivers/acpi/acpica/dbexec.c-779-\ndrivers/acpi/acpica/dbexec.c:780:\tmemset(\u0026acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));\ndrivers/acpi/acpica/dbexec.c-781-\n--\ndrivers/acpi/acpica/dbexec.c-794-\t}\ndrivers/acpi/acpica/dbexec.c:795:\tmemset(acpi_gbl_db_method_info.threads, 0, size);\ndrivers/acpi/acpica/dbexec.c-796-\n--\ndrivers/acpi/acpica/dsfield.c=473=acpi_ds_create_field(union acpi_parse_object *op,\n--\ndrivers/acpi/acpica/dsfield.c-505-\ndrivers/acpi/acpica/dsfield.c:506:\tmemset(\u0026info, 0, sizeof(struct acpi_create_field_info));\ndrivers/acpi/acpica/dsfield.c-507-\n--\ndrivers/acpi/acpica/dsinit.c=157=acpi_ds_initialize_objects(u32 table_index,\n--\ndrivers/acpi/acpica/dsinit.c-176-\ndrivers/acpi/acpica/dsinit.c:177:\tmemset(\u0026info, 0, sizeof(struct acpi_init_walk_info));\ndrivers/acpi/acpica/dsinit.c-178-\n--\ndrivers/acpi/acpica/nsinit.c=46=acpi_status acpi_ns_initialize_objects(void)\n--\ndrivers/acpi/acpica/nsinit.c-61-\ndrivers/acpi/acpica/nsinit.c:62:\tmemset(\u0026info, 0, sizeof(struct acpi_init_walk_info));\ndrivers/acpi/acpica/nsinit.c-63-\n--\ndrivers/acpi/acpica/nsinit.c=105=acpi_status acpi_ns_initialize_devices(u32 flags)\n--\ndrivers/acpi/acpica/nsinit.c-167-\t\tif (ACPI_SUCCESS(status)) {\ndrivers/acpi/acpica/nsinit.c:168:\t\t\tmemset(info.evaluate_info, 0,\ndrivers/acpi/acpica/nsinit.c-169-\t\t\t       sizeof(struct acpi_evaluate_info));\n--\ndrivers/acpi/acpica/nsinit.c=515=acpi_ns_init_one_device(acpi_handle obj_handle,\n--\ndrivers/acpi/acpica/nsinit.c-638-\ndrivers/acpi/acpica/nsinit.c:639:\t\tmemset(info, 0, sizeof(struct acpi_evaluate_info));\ndrivers/acpi/acpica/nsinit.c-640-\t\tinfo-\u003eprefix_node = device_node;\n--\ndrivers/acpi/acpica/rsmisc.c=35=acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,\n--\ndrivers/acpi/acpica/rsmisc.c-87-\t\t\t */\ndrivers/acpi/acpica/rsmisc.c:88:\t\t\tmemset(resource, 0, INIT_RESOURCE_LENGTH(info));\ndrivers/acpi/acpica/rsmisc.c-89-\t\t\tresource-\u003etype = INIT_RESOURCE_TYPE(info);\n--\ndrivers/acpi/acpica/rsmisc.c-302-\ndrivers/acpi/acpica/rsmisc.c:303:\t\t\tmemset(destination, info-\u003eaml_offset, info-\u003evalue);\ndrivers/acpi/acpica/rsmisc.c-304-\t\t\tbreak;\n--\ndrivers/acpi/acpica/rsmisc.c=446=acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,\n--\ndrivers/acpi/acpica/rsmisc.c-480-\ndrivers/acpi/acpica/rsmisc.c:481:\t\t\tmemset(aml, 0, INIT_RESOURCE_LENGTH(info));\ndrivers/acpi/acpica/rsmisc.c-482-\t\t\taml_length = INIT_RESOURCE_LENGTH(info);\n--\ndrivers/acpi/dock.c=575=void acpi_dock_add(struct acpi_device *adev)\n--\ndrivers/acpi/dock.c-582-\ndrivers/acpi/dock.c:583:\tmemset(\u0026pdevinfo, 0, sizeof(pdevinfo));\ndrivers/acpi/dock.c-584-\tpdevinfo.name = \"dock\";\n--\ndrivers/acpi/pfr_telemetry.c=79=static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info,\n--\ndrivers/acpi/pfr_telemetry.c-85-\ndrivers/acpi/pfr_telemetry.c:86:\tmemset(data_info, 0, sizeof(*data_info));\ndrivers/acpi/pfr_telemetry.c-87-\tmemset(\u0026in_obj, 0, sizeof(in_obj));\n--\ndrivers/android/binder.c=4744=static int binder_thread_read(struct binder_proc *proc,\n--\ndrivers/android/binder.c-5001-\ndrivers/android/binder.c:5002:\t\t\tmemset(\u0026info, 0, sizeof(info));\ndrivers/android/binder.c-5003-\t\t\tfreeze = container_of(w, struct binder_ref_freeze, work);\n--\ndrivers/android/binder.c=5599=static int binder_ioctl_get_node_debug_info(struct binder_proc *proc,\n--\ndrivers/android/binder.c-5604-\ndrivers/android/binder.c:5605:\tmemset(info, 0, sizeof(*info));\ndrivers/android/binder.c-5606-\n--\ndrivers/ata/libata-eh.c=712=void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)\n--\ndrivers/ata/libata-eh.c-734-\t\tlink-\u003eeh_context.i = link-\u003eeh_info;\ndrivers/ata/libata-eh.c:735:\t\tmemset(\u0026link-\u003eeh_info, 0, sizeof(link-\u003eeh_info));\ndrivers/ata/libata-eh.c-736-\n--\ndrivers/ata/libata-eh.c-791-\tata_for_each_link(link, ap, HOST_FIRST)\ndrivers/ata/libata-eh.c:792:\t\tmemset(\u0026link-\u003eeh_info, 0, sizeof(link-\u003eeh_info));\ndrivers/ata/libata-eh.c-793-\n--\ndrivers/ata/pata_icside.c=480=static int pata_icside_probe(struct expansion_card *ec,\n--\ndrivers/ata/pata_icside.c-513-\ndrivers/ata/pata_icside.c:514:\tmemset(\u0026info, 0, sizeof(info));\ndrivers/ata/pata_icside.c-515-\tinfo.state = state;\n--\ndrivers/ata/pata_macio.c=1049=static int pata_macio_common_init(struct pata_macio_priv *priv,\n--\ndrivers/ata/pata_macio.c-1067-\t/* Allocate libata host for 1 port */\ndrivers/ata/pata_macio.c:1068:\tmemset(\u0026pinfo, 0, sizeof(struct ata_port_info));\ndrivers/ata/pata_macio.c-1069-\tpmac_macio_calc_timing_masks(priv, \u0026pinfo);\n--\ndrivers/ata/sata_highbank.c=326=static int highbank_initialize_phys(struct device *dev, void __iomem *addr)\n--\ndrivers/ata/sata_highbank.c-333-\ndrivers/ata/sata_highbank.c:334:\tmemset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);\ndrivers/ata/sata_highbank.c-335-\n--\ndrivers/base/core.c=4950=set_dev_info(const struct device *dev, struct dev_printk_info *dev_info)\n--\ndrivers/base/core.c-4953-\ndrivers/base/core.c:4954:\tmemset(dev_info, 0, sizeof(*dev_info));\ndrivers/base/core.c-4955-\n--\ndrivers/block/loop.c=1300=loop_get_status(struct loop_device *lo, struct loop_info64 *info)\n--\ndrivers/block/loop.c-1313-\ndrivers/block/loop.c:1314:\tmemset(info, 0, sizeof(*info));\ndrivers/block/loop.c-1315-\tinfo-\u003elo_number = lo-\u003elo_number;\n--\ndrivers/block/loop.c=1336=loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64)\ndrivers/block/loop.c-1337-{\ndrivers/block/loop.c:1338:\tmemset(info64, 0, sizeof(*info64));\ndrivers/block/loop.c-1339-\tinfo64-\u003elo_number = info-\u003elo_number;\n--\ndrivers/block/loop.c=1350=loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)\ndrivers/block/loop.c-1351-{\ndrivers/block/loop.c:1352:\tmemset(info, 0, sizeof(*info));\ndrivers/block/loop.c-1353-\tinfo-\u003elo_number = info64-\u003elo_number;\n--\ndrivers/block/loop.c=1622=loop_info64_from_compat(const struct compat_loop_info __user *arg,\n--\ndrivers/block/loop.c-1629-\ndrivers/block/loop.c:1630:\tmemset(info64, 0, sizeof(*info64));\ndrivers/block/loop.c-1631-\tinfo64-\u003elo_number = info.lo_number;\n--\ndrivers/block/loop.c=1647=loop_info64_to_compat(const struct loop_info64 *info64,\n--\ndrivers/block/loop.c-1651-\ndrivers/block/loop.c:1652:\tmemset(\u0026info, 0, sizeof(info));\ndrivers/block/loop.c-1653-\tinfo.lo_number = info64-\u003elo_number;\n--\ndrivers/block/xen-blkfront.c=1072=static int xlvbd_alloc_gendisk(blkif_sector_t capacity,\n--\ndrivers/block/xen-blkfront.c-1119-\ndrivers/block/xen-blkfront.c:1120:\tmemset(\u0026info-\u003etag_set, 0, sizeof(info-\u003etag_set));\ndrivers/block/xen-blkfront.c-1121-\tinfo-\u003etag_set.ops = \u0026blkfront_mq_ops;\n--\ndrivers/char/agp/generic.c=364=int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)\ndrivers/char/agp/generic.c-365-{\ndrivers/char/agp/generic.c:366:\tmemset(info, 0, sizeof(struct agp_kern_info));\n\n"
}

47/3 2026/08/27 06:43 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 53148
							output: 45
							thoughts: 84
						

Thoughts:
**Investigating `memset` Calls in mac80211 tx.c**

Okay, so I was looking into the `net/mac80211/tx.c` file and trying to track down any instances of `memset` calls operating on `IEEE80211_SKB_CB`. My initial search, however, was clearly misguided – I realized I had accidentally searched for `memset` followed by `.info`, rather than targeting the specific `IEEE80211_SKB_CB` struct. This is a crucial distinction. Now, let's refine the search and look for `memset` directly followed by instances referencing `IEEE80211_SKB_CB` within that file. That should give me the information I actually need.



48/3 2026/08/27 06:43 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "memset.*IEEE80211_SKB_CB",
  "PathPrefix": "net/mac80211/tx.c"
}

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

49/3 2026/08/27 06:43 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 53458
							output: 33
							thoughts: 23
						

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

**Investigating Memory Initialization in the 802.11 Transmit Path**

Okay, so I need to track down how memory is being initialized within the mac80211 transmit path. Specifically, I'm thinking about the use of `memset` – it's often a performance bottleneck, or even a source of subtle bugs if used incorrectly, and I want to see where it's being employed in the context of `tx.c`. I expect to find it used in contexts such as frame descriptors, buffer initialization, or perhaps even in clearing control structures. The goal here is to identify potential areas for optimization, or maybe even to understand the rationale behind specific design choices related to memory management in this critical part of the wireless stack. Knowing what is being zeroed and why will help me understand the code and how to potentially improve it. Let's see what `find` turns up...



50/3 2026/08/27 06:43 tool grepper
0m Args:
{
  "Expression": "memset",
  "PathPrefix": "net/mac80211/tx.c"
}

Results:
{
  "Output": "net/mac80211/tx.c=675=ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)\n--\nnet/mac80211/tx.c-685-\nnet/mac80211/tx.c:686:\tmemset(\u0026txrc, 0, sizeof(txrc));\nnet/mac80211/tx.c-687-\n--\nnet/mac80211/tx.c=1208=ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/tx.c-1217-\nnet/mac80211/tx.c:1218:\tmemset(tx, 0, sizeof(*tx));\nnet/mac80211/tx.c-1219-\ttx-\u003eskb = skb;\n--\nnet/mac80211/tx.c=2324=netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,\n--\nnet/mac80211/tx.c-2339-\nnet/mac80211/tx.c:2340:\tmemset(info, 0, sizeof(*info));\nnet/mac80211/tx.c-2341-\tinfo-\u003eflags = IEEE80211_TX_CTL_REQ_TX_STATUS |\n--\nnet/mac80211/tx.c=2648=static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/tx.c-3030-\tinfo = IEEE80211_SKB_CB(skb);\nnet/mac80211/tx.c:3031:\tmemset(info, 0, sizeof(*info));\nnet/mac80211/tx.c-3032-\n--\nnet/mac80211/tx.c=3470=static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/tx.c-3597-\nnet/mac80211/tx.c:3598:\tmemset(skb_push(skb, pad), 0, pad);\nnet/mac80211/tx.c-3599-\n--\nnet/mac80211/tx.c=3739=void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/tx.c-3776-\tinfo = IEEE80211_SKB_CB(skb);\nnet/mac80211/tx.c:3777:\tmemset(info, 0, sizeof(*info));\nnet/mac80211/tx.c-3778-\tinfo-\u003eband = fast_tx-\u003eband;\n--\nnet/mac80211/tx.c=3880=struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-3937-\nnet/mac80211/tx.c:3938:\tmemset(\u0026tx, 0, sizeof(tx));\nnet/mac80211/tx.c-3939-\t__skb_queue_head_init(\u0026tx.skbs);\n--\nnet/mac80211/tx.c=4700=static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/tx.c-4746-\tinfo = IEEE80211_SKB_CB(skb);\nnet/mac80211/tx.c:4747:\tmemset(info, 0, sizeof(*info));\nnet/mac80211/tx.c-4748-\n--\nnet/mac80211/tx.c=5433=static int ieee80211_beacon_protect(struct sk_buff *skb,\n--\nnet/mac80211/tx.c-5441-\nnet/mac80211/tx.c:5442:\tmemset(\u0026tx, 0, sizeof(tx));\nnet/mac80211/tx.c-5443-\ttx.key = rcu_dereference(link-\u003edefault_beacon_key);\n--\nnet/mac80211/tx.c=5470=int ieee80211_encrypt_tx_skb(struct sk_buff *skb)\n--\nnet/mac80211/tx.c-5480-\nnet/mac80211/tx.c:5481:\tmemset(\u0026tx, 0, sizeof(tx));\nnet/mac80211/tx.c-5482-\ttx.key = container_of(info-\u003econtrol.hw_key, struct ieee80211_key, conf);\n--\nnet/mac80211/tx.c=5510=ieee80211_beacon_get_finish(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-5544-\nnet/mac80211/tx.c:5545:\tmemset(\u0026txrc, 0, sizeof(txrc));\nnet/mac80211/tx.c-5546-\ttxrc.hw = hw;\n--\nnet/mac80211/tx.c=5766=__ieee80211_beacon_get(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-5794-\tif (offs)\nnet/mac80211/tx.c:5795:\t\tmemset(offs, 0, sizeof(*offs));\nnet/mac80211/tx.c-5796-\n--\nnet/mac80211/tx.c=5999=struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-6021-\thdr = (struct ieee80211_hdr *) skb-\u003edata;\nnet/mac80211/tx.c:6022:\tmemset(hdr-\u003eaddr1, 0, sizeof(hdr-\u003eaddr1));\nnet/mac80211/tx.c-6023-\n"
}

51/3 2026/08/27 06:43 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 55521
							output: 28
							thoughts: 1367
						

Thoughts:
**Analyzing IEEE80211 SKB Control Structure Initialization**

Okay, let's break this down. I'm seeing that `memset` is used to zero out the `IEEE80211_SKB_CB` structure in several places: when new frames are constructed, during transmission, and when monitor mode starts transmitting. This confirms my initial understanding that the control information is initialized to zero when the frame is created. Broadcast frames that are buffered will have been zeroed when created, and are just dequeued. Therefore, I can confidently say the `info->control` part of the structure is fully initialized when a new frame is generated or received.

Now, let's revisit `mm81x_tx_h_get_bw`. My primary concern is the initialization of `info->control.vif`. I need to ensure this is set correctly. I noticed that the code checks several conditions: if it's a probe response, whether the frame is management or has a specific flag, and if it's an AP and the destination is a multicast address. If none of these conditions are met and there is an associated station, the bandwidth calculation depends on the station's capabilities. However, before those conditions are evaluated, it is critical to confirm the `vif` is set.

Looking at `mm81x_mac_send_buffered_bc`, I see that the `vif` is explicitly set within the loop: `IEEE80211_SKB_CB(bc_frame)->control.vif = vif;`. Thus, I can definitively confirm that `info->control.vif` is initialized, and my concerns about that specific element are alleviated.

I need to circle back to `mm81x_tx_h_fill_info` now.  The code accesses `info->control.rates[i].flags`. Since the entire `info` structure is zeroed out, it is safe to read `info->control.rates[i].flags`. My concern is whether rate control populates those values for broadcast frames. It's likely that the MAC80211 rate control isn't heavily involved with broadcast frames, so that zeroed-out value is most likely safe to read. A zero is what I'd expect if nothing else had modified it. I'll need to keep this in mind for a more comprehensive analysis, especially in the context of the rate control algorithm itself.

I'm ready to move on.  I have addressed the concerns I had. Now, let's dig into `mm81x_rc_sta_fill_tx_rates`.



52/3 2026/08/27 06:43 tool grepper
0m Args:
{
  "Expression": "mm81x_rc_sta_fill_tx_rates"
}

Results:
{
  "Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=1170=static void mm81x_tx_h_fill_info(struct mm81x *mors,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1188-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:1189:\tmm81x_rc_sta_fill_tx_rates(mors, tx_info, skb, sta, tx_bw_mhz,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-1190-\t\t\t\t   rts_allowed);\n--\ndrivers/net/wireless/morsemicro/mm81x/rc.c=239=static bool mm81x_rc_use_basic_rates(struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/morsemicro/mm81x/rc.c-262-\ndrivers/net/wireless/morsemicro/mm81x/rc.c:263:void mm81x_rc_sta_fill_tx_rates(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/rc.c-264-\t\t\t\tstruct mm81x_skb_tx_info *tx_info,\n--\ndrivers/net/wireless/morsemicro/mm81x/rc.h=37=void mm81x_rc_sta_remove(struct mm81x *mors, struct ieee80211_sta *sta);\ndrivers/net/wireless/morsemicro/mm81x/rc.h:38:void mm81x_rc_sta_fill_tx_rates(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/rc.h-39-\t\t\t\tstruct mm81x_skb_tx_info *tx_info,\n"
}

53/3 2026/08/27 06:43 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 57972
							output: 46
							thoughts: 20
						

Thoughts:
Okay, here's my interpretation of what's going on, framed as a first-person expert perspective:

**Diving into `mm81x_rc_sta_fill_tx_rates`**

Alright, let's pull up `mm81x_rc_sta_fill_tx_rates`. This function name immediately clues me in – we're looking at something related to rate control, and specifically, populating transmit rate information for a station. "mm81x" likely indicates a specific hardware platform or chipset, which narrows down the scope quite a bit. My guess is this is where the lower layers of the rate control algorithm interacts with the radio hardware to set the actual TX rate. We should be able to dig into the function and identify the data structures that it's working with. The key here is to determine how the current rate is identified and what sort of factors are considered when this function is called. We'll look for input parameters, what's being calculated, and if there are any external dependencies on the firmware. We should also look for anything that sets the retry rates, since that is critically important for stable operation. This is likely an important piece of the rate control puzzle, so let's get into it and see how it works.



54/3 2026/08/27 06:44 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/morsemicro/mm81x/rc.c",
  "FirstLine": 263,
  "LineCount": 50
}

Results:
{
  "Contents": " 263:\tvoid mm81x_rc_sta_fill_tx_rates(struct mm81x *mors,\n 264:\t\t\t\t\tstruct mm81x_skb_tx_info *tx_info,\n 265:\t\t\t\t\tstruct sk_buff *skb, struct ieee80211_sta *sta,\n 266:\t\t\t\t\tint tx_bw, bool rts_allowed)\n 267:\t{\n 268:\t\tint ret, i;\n 269:\t\tstruct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-\u003edata;\n 270:\t\tstruct mm81x_sta *msta;\n 271:\t\tstruct mmrc_rate_table rates;\n 272:\t\tstruct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);\n 273:\t\n 274:\t\tBUILD_BUG_ON((MMRC_BW_1MHZ != (enum mmrc_bw)DOT11_BANDWIDTH_1MHZ ||\n 275:\t\t\t      MMRC_BW_2MHZ != (enum mmrc_bw)DOT11_BANDWIDTH_2MHZ ||\n 276:\t\t\t      MMRC_BW_4MHZ != (enum mmrc_bw)DOT11_BANDWIDTH_4MHZ ||\n 277:\t\t\t      MMRC_BW_16MHZ != (enum mmrc_bw)DOT11_BANDWIDTH_16MHZ));\n 278:\t\n 279:\t\tmemset(\u0026info-\u003econtrol.rates, 0, sizeof(info-\u003econtrol.rates));\n 280:\t\tmemset(\u0026info-\u003estatus.rates, 0, sizeof(info-\u003estatus.rates));\n 281:\t\tmm81x_rc_sta_fill_basic_rates(tx_info, info, tx_bw);\n 282:\t\n 283:\t\t/* Use basic rates for non data packets */\n 284:\t\tif (mm81x_rc_use_basic_rates(sta, skb, hdr))\n 285:\t\t\treturn;\n 286:\t\n 287:\t\tmsta = (struct mm81x_sta *)sta-\u003edrv_priv;\n 288:\t\tif (!msta)\n 289:\t\t\treturn;\n 290:\t\n 291:\t\tret = mm81x_rc_sta_get_rates(mors, msta, \u0026rates, skb-\u003elen);\n 292:\t\tif (ret != 0)\n 293:\t\t\treturn;\n 294:\t\n 295:\t\tfor (i = 0; i \u003c IEEE80211_TX_MAX_RATES; i++) {\n 296:\t\t\tinfo-\u003econtrol.rates[i].flags = 0;\n 297:\t\t\tif (rates.rates[i].rate != MMRC_MCS_UNUSED) {\n 298:\t\t\t\tu8 mcs = rates.rates[i].rate;\n 299:\t\t\t\tu8 nss_index = rates.rates[i].ss;\n 300:\t\t\t\tenum dot11_bandwidth bw_idx =\n 301:\t\t\t\t\t(enum dot11_bandwidth)rates.rates[i].bw;\n 302:\t\t\t\tenum mm81x_rate_preamble pream =\n 303:\t\t\t\t\tMM81X_RATE_PREAMBLE_S1G_SHORT;\n 304:\t\n 305:\t\t\t\tmm81x_ratecode_bw_index_set(\n 306:\t\t\t\t\t\u0026tx_info-\u003erates[i].mm81x_ratecode, bw_idx);\n 307:\t\t\t\tmm81x_ratecode_mcs_index_set(\n 308:\t\t\t\t\t\u0026tx_info-\u003erates[i].mm81x_ratecode, mcs);\n 309:\t\t\t\tmm81x_ratecode_nss_index_set(\n 310:\t\t\t\t\t\u0026tx_info-\u003erates[i].mm81x_ratecode, nss_index);\n 311:\t\t\t\tif (bw_idx == DOT11_BANDWIDTH_1MHZ)\n 312:\t\t\t\t\tpream = MM81X_RATE_PREAMBLE_S1G_1M;\n"
}

55/3 2026/08/27 06:44 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 59392
							output: 233
							thoughts: 2485
						

Thoughts:
**Unraveling Potential Initialization Issues in the WiFi Driver**

Okay, let's break this down systematically. My primary concern is always uninitialized memory, potential information leaks, and generally, any areas where data might be used before it's properly set.

First, `mm81x_rc_sta_fill_tx_rates` explicitly zeroes `info->control.rates` and `info->status.rates`. That's good; it establishes a known state.  I'll file that away.

Then, checking `mm81x_mac_ops_tx_frames_pending` is trivial, it's just a wrapper. Doesn't seem risky at all.

`mm81x_tx_h_is_ps_filtered` only conditionally modifies its behavior based on the interface type (AP or STA).  It uses the `vif` from `info->control`. That suggests that `info->control.vif` is set when skb is created.

The `mm81x_mac_ops_sta_state` function is interesting because it introduces `mors_sta->max_rx_bw_mhz`. This is initialized based on the `sta->deflink.s1g_cap.cap`, which is initialized by mac80211 on association.  Therefore, it's initialized *when the station associates.* Good to know.

Next, `mm81x_mac_beacon_work` uses a zero-initialized `tx_info` and then fills it via `mm81x_beacon_h_fill_tx_info`.  `mm81x_mac_send_buffered_bc` uses `control`. `control` is explicitly zero-initialized in the code. This is very good. This function appears safe.

Alright, so the key questions:

*   Is `tx_info` always initialized? Yes.
*   Is `control` always initialized? Yes.
*   Is `info->control.rates` always initialized? Yes.
*   Is `info` always initialized? Yes.
*   Is `mors_sta->max_rx_bw_mhz` reliably initialized? Yes, on association.
*   Is the calculation of `tx_bw_mhz` safe? Yes, it uses initialized values and `min`.

Now, digging deeper. What about `mm81x_tx_h_get_bw`?  We are reading `hdr->frame_control`, `info->control.flags`, `info->control.vif->type`, and `ieee80211_get_DA(hdr)`. So, is the data pointed to by `hdr` always valid? Yes, the MAC header is always present in a valid skb.  We need to verify that `skb->data` does point to a valid header.

Finally, `mm81x_tx_h_get_max_tx_bw` is just a series of safe macro checks and ternary operators.

My conclusion is the code carefully initializes everything. The patch looks safe. It's adding features for bandwidth control and broadcast handling, so that's all good.

Therefore, this patch seems to avoid uninitialized memory issues and should be safe from potential KSMAN issues. I'd be confident that KASAN and standard tools will be sufficient to catch any remaining issues here. The patch has purely logical changes: introducing new variables/structs which are always initialized. No complex data structures are allocated without initialization. I can't see any obvious information leaks. No uninitialized variables used in branching.



56/3 2026/08/27 06:44 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch modifies the mm81x wireless driver to limit TX bandwidth based on the station's maximum RX bandwidth, send buffered broadcast frames after a DTIM beacon, and implement the tx_frames_pending callback. All newly introduced local structures (e.g., `struct ieee80211_tx_control control` and `struct mm81x_skb_tx_info tx_info`) are explicitly zero-initialized using `{ 0 }`. The `max_rx_bw_mhz` field added to `struct mm81x_sta` is initialized from the mac80211 station capabilities during association. The patch does not introduce any new kernel-to-user copies, nor does it add complex data structures that could be partially uninitialized. There is no risk of uninitialized memory being used in control flow or leaked to userspace. Standard KASAN and other bug detectors are sufficient to catch any potential memory corruption or out-of-bounds access.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch modifies the mm81x wireless driver to limit TX bandwidth based on the station's maximum RX bandwidth, send buffered broadcast frames after a DTIM beacon, and implement the tx_frames_pending callback. All newly introduced local structures (e.g., `struct ieee80211_tx_control control` and `struct mm81x_skb_tx_info tx_info`) are explicitly zero-initialized using `{ 0 }`. The `max_rx_bw_mhz` field added to `struct mm81x_sta` is initialized from the mac80211 station capabilities during association. The patch does not introduce any new kernel-to-user copies, nor does it add complex data structures that could be partially uninitialized. There is no risk of uninitialized memory being used in control flow or leaked to userspace. Standard KASAN and other bug detectors are sufficient to catch any potential memory corruption or out-of-bounds access.",
  "NeedsKMSAN": 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)