AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/09/25 19:23 flow patch-triage
1m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "The patch introduces a TX hold mechanism to limit the number of frames queued in hardware for the MediaTek MT7603 wireless driver. The changes are located in drivers/net/wireless/mediatek/mt76/mt7603/ and the shared mt76 core (where MT_WCID_FLAG_TX_HOLD is checked in tx.c, but only ever set by mt7603). The MT7603E driver requires physical MediaTek MT7603E PCIe hardware or an MT7628 SoC, neither of which is emulated in standard virtualized environments (QEMU/GCE). The code is therefore structurally unreachable for fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/09/25 19:23 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit e44898c51bc43c16d317501c15df05b996065da2\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Fri Sep 25 19:23:56 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h\nindex 62b41c8bb7c0d..d03e66c2af746 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt76.h\n+++ b/drivers/net/wireless/mediatek/mt76/mt76.h\n@@ -362,6 +362,7 @@ enum mt76_wcid_flags {\n \tMT_WCID_FLAG_4ADDR,\n \tMT_WCID_FLAG_HDR_TRANS,\n \tMT_WCID_FLAG_TDLS_PEER,\n+\tMT_WCID_FLAG_TX_HOLD,\n };\n \n #define MT76_N_WCIDS 1088\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c\nindex c891ad5498e61..7e61a2b533ce3 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c\n@@ -93,6 +93,34 @@ mt7603_ampdu_stat_show(struct seq_file *file, void *data)\n \n DEFINE_SHOW_ATTRIBUTE(mt7603_ampdu_stat);\n \n+static int\n+mt7603_hw_cap_read(struct seq_file *s, void *data)\n+{\n+\tstruct mt7603_dev *dev = dev_get_drvdata(s-\u003eprivate);\n+\tint i;\n+\n+\tseq_printf(s, \"high %u low %u resync %u\\n\",\n+\t\t   READ_ONCE(dev-\u003ehw_cap_high), READ_ONCE(dev-\u003ehw_cap_low),\n+\t\t   READ_ONCE(dev-\u003ehw_cap_resync));\n+\n+\trcu_read_lock();\n+\tfor (i = 0; i \u003c MT7603_WTBL_STA; i++) {\n+\t\tstruct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);\n+\t\tstruct mt7603_sta *msta;\n+\n+\t\tif (!wcid || !wcid-\u003esta)\n+\t\t\tcontinue;\n+\n+\t\tmsta = container_of(wcid, struct mt7603_sta, wcid);\n+\t\tseq_printf(s, \"wcid %d pending %d hold %d\\n\", i,\n+\t\t\t   atomic_read(\u0026msta-\u003ehw_pending),\n+\t\t\t   test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags));\n+\t}\n+\trcu_read_unlock();\n+\n+\treturn 0;\n+}\n+\n void mt7603_init_debugfs(struct mt7603_dev *dev)\n {\n \tstruct dentry *dir;\n@@ -115,4 +143,8 @@ void mt7603_init_debugfs(struct mt7603_dev *dev)\n \t\t\t    \u0026dev-\u003esensitivity_limit);\n \tdebugfs_create_bool(\"dynamic_sensitivity\", 0600, dir,\n \t\t\t    \u0026dev-\u003edynamic_sensitivity);\n+\tdebugfs_create_u32(\"hw_cap_high\", 0600, dir, \u0026dev-\u003ehw_cap_high);\n+\tdebugfs_create_u32(\"hw_cap_low\", 0600, dir, \u0026dev-\u003ehw_cap_low);\n+\tdebugfs_create_devm_seqfile(dev-\u003emt76.dev, \"hw_cap\", dir,\n+\t\t\t\t    mt7603_hw_cap_read);\n }\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c\nindex 477a9b7a8cf7d..7db136a5997ce 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c\n@@ -49,6 +49,11 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)\n \n \tpriv = msta = container_of(wcid, struct mt7603_sta, wcid);\n \n+\t/* The frame left the hardware: its TX status will not arrive. */\n+\tif (wcid-\u003esta \u0026\u0026\n+\t    FIELD_GET(MT_TXD5_PID, le32_to_cpu(txd[5])) != MT_PACKET_ID_NO_ACK)\n+\t\tmt7603_hw_pending_dec(dev, msta);\n+\n \tsta = container_of(priv, struct ieee80211_sta, drv_priv);\n \thdr = (struct ieee80211_hdr *)\u0026skb-\u003edata[MT_TXD_SIZE];\n \n@@ -81,7 +86,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)\n \n \tspin_lock_bh(\u0026dev-\u003eps_lock);\n \t__skb_queue_tail(\u0026msta-\u003epsq, skb);\n-\tif (skb_queue_len(\u0026msta-\u003epsq) \u003e= 64) {\n+\tif (skb_queue_len(\u0026msta-\u003epsq) \u003e= MT7603_PSQ_MAX) {\n \t\tskb = __skb_dequeue(\u0026msta-\u003epsq);\n \t\tdev_kfree_skb(skb);\n \t}\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c\nindex 10f2ec70c792b..900dda2eaca2a 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c\n@@ -518,6 +518,8 @@ int mt7603_register_device(struct mt7603_dev *dev)\n \tdev-\u003eslottime = 9;\n \tdev-\u003esensitivity_limit = 28;\n \tdev-\u003edynamic_sensitivity = true;\n+\tdev-\u003ehw_cap_high = MT7603_HW_CAP_HIGH;\n+\tdev-\u003ehw_cap_low = MT7603_HW_CAP_LOW;\n \n \tret = mt7603_init_hardware(dev);\n \tif (ret)\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c\nindex fa0bf9a201ce2..6d8026abcb571 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c\n@@ -1095,6 +1095,10 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,\n \n \tpid = mt76_tx_status_skb_add(mdev, wcid, tx_info-\u003eskb);\n \n+\t/* Owed until its TX status arrives or a loop-back returns it. */\n+\tif (sta \u0026\u0026 pid != MT_PACKET_ID_NO_ACK)\n+\t\tmt7603_hw_pending_inc(dev, msta);\n+\n \tif (info-\u003eflags \u0026 IEEE80211_TX_CTL_RATE_CTRL_PROBE) {\n \t\tspin_lock_bh(\u0026dev-\u003emt76.lock);\n \t\tmt7603_wtbl_set_rates(dev, msta, \u0026info-\u003econtrol.rates[0],\n@@ -1300,6 +1304,9 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)\n \tsta = wcid_to_sta(wcid);\n \tmt76_wcid_add_poll(\u0026dev-\u003emt76, \u0026msta-\u003ewcid);\n \n+\tif (wcid-\u003esta)\n+\t\tmt7603_hw_pending_dec(dev, msta);\n+\n \tif (mt7603_mac_add_txs_skb(dev, msta, pid, txs_data))\n \t\tgoto out;\n \n@@ -1876,6 +1883,56 @@ mt7603_mac_ps_check(struct mt7603_dev *dev)\n \trcu_read_unlock();\n }\n \n+/* Lift the hold on a station's tx queues and get the scheduler going. */\n+void mt7603_hw_release(struct mt7603_dev *dev, struct mt7603_sta *msta)\n+{\n+\tstruct ieee80211_sta *sta;\n+\tint i;\n+\n+\tif (!test_and_clear_bit(MT_WCID_FLAG_TX_HOLD, \u0026msta-\u003ewcid.flags))\n+\t\treturn;\n+\n+\tsta = container_of((void *)msta, struct ieee80211_sta, drv_priv);\n+\tfor (i = 0; i \u003c ARRAY_SIZE(sta-\u003etxq); i++)\n+\t\tif (sta-\u003etxq[i])\n+\t\t\tieee80211_schedule_txq(mt76_hw(dev), sta-\u003etxq[i]);\n+\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\n+}\n+\n+/*\n+ * Every frame counted ends in a TX status or a loop-back return. If a held\n+ * station saw neither for a second, its count is off: start over instead\n+ * of keeping it on hold. Turning the cap off releases every hold.\n+ */\n+static void\n+mt7603_hw_cap_check(struct mt7603_dev *dev)\n+{\n+\tbool enabled = READ_ONCE(dev-\u003ehw_cap_high);\n+\tint i;\n+\n+\trcu_read_lock();\n+\tfor (i = 0; i \u003c MT7603_WTBL_STA; i++) {\n+\t\tstruct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);\n+\t\tstruct mt7603_sta *msta;\n+\n+\t\tif (!wcid || !wcid-\u003esta ||\n+\t\t    !test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags))\n+\t\t\tcontinue;\n+\n+\t\tmsta = container_of(wcid, struct mt7603_sta, wcid);\n+\t\tif (enabled \u0026\u0026\n+\t\t    time_before(jiffies, READ_ONCE(msta-\u003ehw_settled) + HZ))\n+\t\t\tcontinue;\n+\n+\t\tif (enabled) {\n+\t\t\tatomic_set(\u0026msta-\u003ehw_pending, 0);\n+\t\t\tdev-\u003ehw_cap_resync++;\n+\t\t}\n+\t\tmt7603_hw_release(dev, msta);\n+\t}\n+\trcu_read_unlock();\n+}\n+\n void mt7603_mac_work(struct work_struct *work)\n {\n \tstruct mt7603_dev *dev = container_of(work, struct mt7603_dev,\n@@ -1891,6 +1948,7 @@ void mt7603_mac_work(struct work_struct *work)\n \tmt76_update_survey(\u0026dev-\u003emphy);\n \tmt7603_edcca_check(dev);\n \tmt7603_mac_ps_check(dev);\n+\tmt7603_hw_cap_check(dev);\n \n \tfor (i = 0, idx = 0; i \u003c 2; i++) {\n \t\tu32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c\nindex 757664e9e1f20..6a18f4013e69a 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c\n@@ -339,6 +339,8 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n \n \tINIT_LIST_HEAD(\u0026msta-\u003ewcid.poll_list);\n \t__skb_queue_head_init(\u0026msta-\u003epsq);\n+\tatomic_set(\u0026msta-\u003ehw_pending, 0);\n+\tmsta-\u003ehw_settled = jiffies;\n \tmsta-\u003eps = ~0;\n \tmsta-\u003esmps = ~0;\n \tmsta-\u003ewcid.sta = 1;\n@@ -391,14 +393,22 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n }\n \n static void\n-mt7603_ps_tx_list(struct mt7603_dev *dev, struct sk_buff_head *list)\n+mt7603_ps_tx_list(struct mt7603_dev *dev, struct mt7603_sta *msta,\n+\t\t  struct sk_buff_head *list)\n {\n \tstruct sk_buff *skb;\n \n \twhile ((skb = __skb_dequeue(list)) != NULL) {\n \t\tint qid = skb_get_queue_mapping(skb);\n-\n-\t\tmt76_tx_queue_skb_raw(dev, dev-\u003emphy.q_tx[qid], skb, 0);\n+\t\tbool txs = le32_get_bits(((__le32 *)skb-\u003edata)[5],\n+\t\t\t\t\t MT_TXD5_PID) != MT_PACKET_ID_NO_ACK;\n+\n+\t\t/* Count it before the TX status can arrive. */\n+\t\tif (txs)\n+\t\t\tmt7603_hw_pending_inc(dev, msta);\n+\t\tif (mt76_tx_queue_skb_raw(dev, dev-\u003emphy.q_tx[qid], skb, 0) \u0026\u0026\n+\t\t    txs)\n+\t\t\tmt7603_hw_pending_dec(dev, msta);\n \t}\n }\n \n@@ -420,7 +430,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)\n \tskb_queue_splice_tail_init(\u0026msta-\u003epsq, \u0026list);\n \tspin_unlock_bh(\u0026dev-\u003eps_lock);\n \n-\tmt7603_ps_tx_list(dev, \u0026list);\n+\tmt7603_ps_tx_list(dev, msta, \u0026list);\n }\n \n static struct ieee80211_hdr *\n@@ -529,7 +539,7 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,\n \t\t    !ieee80211_is_data_qos(mt7603_ps_skb_hdr(last)-\u003eframe_control);\n \tlast_tid = __fls(tids);\n \n-\tmt7603_ps_tx_list(dev, \u0026list);\n+\tmt7603_ps_tx_list(dev, msta, \u0026list);\n \n \tif (eosp_null)\n \t\tieee80211_send_eosp_nullfunc(sta, last_tid);\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h\nindex 5b0ecd01aad95..b7b2225341451 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h\n+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h\n@@ -20,6 +20,19 @@\n #define MT7603_TX_RING_SIZE\t256\n #define MT7603_PSD_RING_SIZE\t128\n \n+/*\n+ * Frames a station may have in the hardware (tx ring and PSE) before its\n+ * tx queues are held, and the count at which they are released.\n+ */\n+#define MT7603_HW_CAP_HIGH\t96\n+#define MT7603_HW_CAP_LOW\t48\n+\n+/*\n+ * Frames looped back by the PSE for a sleeping station. They are sent again\n+ * on wake-up, so leave room in the tx ring for other traffic.\n+ */\n+#define MT7603_PSQ_MAX\t\t(MT7603_TX_RING_SIZE - 64)\n+\n #define MT7603_FIRMWARE_E1\t\"mt7603_e1.bin\"\n #define MT7603_FIRMWARE_E2\t\"mt7603_e2.bin\"\n #define MT7628_FIRMWARE_E1\t\"mt7628_e1.bin\"\n@@ -81,6 +94,14 @@ struct mt7603_sta {\n \n \tu8 ps;\n \tu8 ps_sleeping;\n+\n+\t/*\n+\t * Frames queued to the hardware that still owe a TX status. The\n+\t * hardware completes frames to mac80211 once DMA has copied them, so\n+\t * AQL cannot bound how many it holds for the station.\n+\t */\n+\tatomic_t hw_pending;\n+\tunsigned long hw_settled;\n };\n \n struct mt7603_vif {\n@@ -156,8 +177,38 @@ struct mt7603_dev {\n \tu32 reset_test;\n \n \tunsigned int reset_cause[__RESET_CAUSE_MAX];\n+\n+\t/* per-station cap on frames in the hardware, 0 = off (debugfs) */\n+\tu32 hw_cap_high;\n+\tu32 hw_cap_low;\n+\tu32 hw_cap_resync;\n };\n \n+void mt7603_hw_release(struct mt7603_dev *dev, struct mt7603_sta *msta);\n+\n+static inline void\n+mt7603_hw_pending_inc(struct mt7603_dev *dev, struct mt7603_sta *msta)\n+{\n+\tint pending = atomic_inc_return(\u0026msta-\u003ehw_pending);\n+\tu32 high = READ_ONCE(dev-\u003ehw_cap_high);\n+\n+\tif (high \u0026\u0026 pending \u003e= high \u0026\u0026\n+\t    !test_and_set_bit(MT_WCID_FLAG_TX_HOLD, \u0026msta-\u003ewcid.flags))\n+\t\tWRITE_ONCE(msta-\u003ehw_settled, jiffies);\n+}\n+\n+static inline void\n+mt7603_hw_pending_dec(struct mt7603_dev *dev, struct mt7603_sta *msta)\n+{\n+\tWRITE_ONCE(msta-\u003ehw_settled, jiffies);\n+\tif (!atomic_add_unless(\u0026msta-\u003ehw_pending, -1, 0))\n+\t\treturn;\n+\n+\tif (test_bit(MT_WCID_FLAG_TX_HOLD, \u0026msta-\u003ewcid.flags) \u0026\u0026\n+\t    atomic_read(\u0026msta-\u003ehw_pending) \u003c= READ_ONCE(dev-\u003ehw_cap_low))\n+\t\tmt7603_hw_release(dev, msta);\n+}\n+\n extern const struct mt76_driver_ops mt7603_drv_ops;\n extern const struct ieee80211_ops mt7603_ops;\n extern struct pci_driver mt7603_pci_driver;\ndiff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c\nindex 3707ee19e4ae7..e16a380c6daf8 100644\n--- a/drivers/net/wireless/mediatek/mt76/tx.c\n+++ b/drivers/net/wireless/mediatek/mt76/tx.c\n@@ -534,6 +534,10 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,\n \t\tif (stop || mt76_txq_stopped(q))\n \t\t\tbreak;\n \n+\t\t/* The previous frame may have filled the hardware. */\n+\t\tif (test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags))\n+\t\t\tbreak;\n+\n \t\tskb = mt76_txq_dequeue(phy, mtxq);\n \t\tif (!skb)\n \t\t\tbreak;\n@@ -605,6 +609,9 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)\n \n \t\tif (atomic_read(\u0026wcid-\u003enon_aql_packets) \u003e= MT_MAX_NON_AQL_PKT)\n \t\t\tcontinue;\n+\t\t/* The driver schedules the queues again when it lifts the hold. */\n+\t\tif (test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags))\n+\t\t\tcontinue;\n \t\tif (dev-\u003equeue_ops-\u003etx_cleanup \u0026\u0026\n \t\t    q-\u003equeued + 2 * MT_TXQ_FREE_THR \u003e= q-\u003endesc) {\n \t\t\tdev-\u003equeue_ops-\u003etx_cleanup(dev, q, false);\n"
}

2/1 2026/09/25 19:23 agent patch-evaluator
1m Model:
core

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a TX hold mechanism to limit the number of frames queued in hardware for the MediaTek MT7603 wireless driver. The changes are located in drivers/net/wireless/mediatek/mt76/mt7603/ and the shared mt76 core (where MT_WCID_FLAG_TX_HOLD is checked in tx.c, but only ever set by mt7603). The MT7603E driver requires physical MediaTek MT7603E PCIe hardware or an MT7628 SoC, neither of which is emulated in standard virtualized environments (QEMU/GCE). The code is therefore structurally unreachable for fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any '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:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit e44898c51bc43c16d317501c15df05b996065da2
Author: syz-cluster <triage@syzkaller.com>
Date:   Fri Sep 25 19:23:56 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 62b41c8bb7c0d..d03e66c2af746 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -362,6 +362,7 @@ enum mt76_wcid_flags {
 	MT_WCID_FLAG_4ADDR,
 	MT_WCID_FLAG_HDR_TRANS,
 	MT_WCID_FLAG_TDLS_PEER,
+	MT_WCID_FLAG_TX_HOLD,
 };
 
 #define MT76_N_WCIDS 1088
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c
index c891ad5498e61..7e61a2b533ce3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c
@@ -93,6 +93,34 @@ mt7603_ampdu_stat_show(struct seq_file *file, void *data)
 
 DEFINE_SHOW_ATTRIBUTE(mt7603_ampdu_stat);
 
+static int
+mt7603_hw_cap_read(struct seq_file *s, void *data)
+{
+	struct mt7603_dev *dev = dev_get_drvdata(s->private);
+	int i;
+
+	seq_printf(s, "high %u low %u resync %u\n",
+		   READ_ONCE(dev->hw_cap_high), READ_ONCE(dev->hw_cap_low),
+		   READ_ONCE(dev->hw_cap_resync));
+
+	rcu_read_lock();
+	for (i = 0; i < MT7603_WTBL_STA; i++) {
+		struct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);
+		struct mt7603_sta *msta;
+
+		if (!wcid || !wcid->sta)
+			continue;
+
+		msta = container_of(wcid, struct mt7603_sta, wcid);
+		seq_printf(s, "wcid %d pending %d hold %d\n", i,
+			   atomic_read(&msta->hw_pending),
+			   test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags));
+	}
+	rcu_read_unlock();
+
+	return 0;
+}
+
 void mt7603_init_debugfs(struct mt7603_dev *dev)
 {
 	struct dentry *dir;
@@ -115,4 +143,8 @@ void mt7603_init_debugfs(struct mt7603_dev *dev)
 			    &dev->sensitivity_limit);
 	debugfs_create_bool("dynamic_sensitivity", 0600, dir,
 			    &dev->dynamic_sensitivity);
+	debugfs_create_u32("hw_cap_high", 0600, dir, &dev->hw_cap_high);
+	debugfs_create_u32("hw_cap_low", 0600, dir, &dev->hw_cap_low);
+	debugfs_create_devm_seqfile(dev->mt76.dev, "hw_cap", dir,
+				    mt7603_hw_cap_read);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index 477a9b7a8cf7d..7db136a5997ce 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -49,6 +49,11 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 
 	priv = msta = container_of(wcid, struct mt7603_sta, wcid);
 
+	/* The frame left the hardware: its TX status will not arrive. */
+	if (wcid->sta &&
+	    FIELD_GET(MT_TXD5_PID, le32_to_cpu(txd[5])) != MT_PACKET_ID_NO_ACK)
+		mt7603_hw_pending_dec(dev, msta);
+
 	sta = container_of(priv, struct ieee80211_sta, drv_priv);
 	hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
 
@@ -81,7 +86,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 
 	spin_lock_bh(&dev->ps_lock);
 	__skb_queue_tail(&msta->psq, skb);
-	if (skb_queue_len(&msta->psq) >= 64) {
+	if (skb_queue_len(&msta->psq) >= MT7603_PSQ_MAX) {
 		skb = __skb_dequeue(&msta->psq);
 		dev_kfree_skb(skb);
 	}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
index 10f2ec70c792b..900dda2eaca2a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -518,6 +518,8 @@ int mt7603_register_device(struct mt7603_dev *dev)
 	dev->slottime = 9;
 	dev->sensitivity_limit = 28;
 	dev->dynamic_sensitivity = true;
+	dev->hw_cap_high = MT7603_HW_CAP_HIGH;
+	dev->hw_cap_low = MT7603_HW_CAP_LOW;
 
 	ret = mt7603_init_hardware(dev);
 	if (ret)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index fa0bf9a201ce2..6d8026abcb571 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -1095,6 +1095,10 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 
 	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
 
+	/* Owed until its TX status arrives or a loop-back returns it. */
+	if (sta && pid != MT_PACKET_ID_NO_ACK)
+		mt7603_hw_pending_inc(dev, msta);
+
 	if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
 		spin_lock_bh(&dev->mt76.lock);
 		mt7603_wtbl_set_rates(dev, msta, &info->control.rates[0],
@@ -1300,6 +1304,9 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
 	sta = wcid_to_sta(wcid);
 	mt76_wcid_add_poll(&dev->mt76, &msta->wcid);
 
+	if (wcid->sta)
+		mt7603_hw_pending_dec(dev, msta);
+
 	if (mt7603_mac_add_txs_skb(dev, msta, pid, txs_data))
 		goto out;
 
@@ -1876,6 +1883,56 @@ mt7603_mac_ps_check(struct mt7603_dev *dev)
 	rcu_read_unlock();
 }
 
+/* Lift the hold on a station's tx queues and get the scheduler going. */
+void mt7603_hw_release(struct mt7603_dev *dev, struct mt7603_sta *msta)
+{
+	struct ieee80211_sta *sta;
+	int i;
+
+	if (!test_and_clear_bit(MT_WCID_FLAG_TX_HOLD, &msta->wcid.flags))
+		return;
+
+	sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
+	for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+		if (sta->txq[i])
+			ieee80211_schedule_txq(mt76_hw(dev), sta->txq[i]);
+	mt76_worker_schedule(&dev->mt76.tx_worker);
+}
+
+/*
+ * Every frame counted ends in a TX status or a loop-back return. If a held
+ * station saw neither for a second, its count is off: start over instead
+ * of keeping it on hold. Turning the cap off releases every hold.
+ */
+static void
+mt7603_hw_cap_check(struct mt7603_dev *dev)
+{
+	bool enabled = READ_ONCE(dev->hw_cap_high);
+	int i;
+
+	rcu_read_lock();
+	for (i = 0; i < MT7603_WTBL_STA; i++) {
+		struct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);
+		struct mt7603_sta *msta;
+
+		if (!wcid || !wcid->sta ||
+		    !test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
+			continue;
+
+		msta = container_of(wcid, struct mt7603_sta, wcid);
+		if (enabled &&
+		    time_before(jiffies, READ_ONCE(msta->hw_settled) + HZ))
+			continue;
+
+		if (enabled) {
+			atomic_set(&msta->hw_pending, 0);
+			dev->hw_cap_resync++;
+		}
+		mt7603_hw_release(dev, msta);
+	}
+	rcu_read_unlock();
+}
+
 void mt7603_mac_work(struct work_struct *work)
 {
 	struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
@@ -1891,6 +1948,7 @@ void mt7603_mac_work(struct work_struct *work)
 	mt76_update_survey(&dev->mphy);
 	mt7603_edcca_check(dev);
 	mt7603_mac_ps_check(dev);
+	mt7603_hw_cap_check(dev);
 
 	for (i = 0, idx = 0; i < 2; i++) {
 		u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 757664e9e1f20..6a18f4013e69a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -339,6 +339,8 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 
 	INIT_LIST_HEAD(&msta->wcid.poll_list);
 	__skb_queue_head_init(&msta->psq);
+	atomic_set(&msta->hw_pending, 0);
+	msta->hw_settled = jiffies;
 	msta->ps = ~0;
 	msta->smps = ~0;
 	msta->wcid.sta = 1;
@@ -391,14 +393,22 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 }
 
 static void
-mt7603_ps_tx_list(struct mt7603_dev *dev, struct sk_buff_head *list)
+mt7603_ps_tx_list(struct mt7603_dev *dev, struct mt7603_sta *msta,
+		  struct sk_buff_head *list)
 {
 	struct sk_buff *skb;
 
 	while ((skb = __skb_dequeue(list)) != NULL) {
 		int qid = skb_get_queue_mapping(skb);
-
-		mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[qid], skb, 0);
+		bool txs = le32_get_bits(((__le32 *)skb->data)[5],
+					 MT_TXD5_PID) != MT_PACKET_ID_NO_ACK;
+
+		/* Count it before the TX status can arrive. */
+		if (txs)
+			mt7603_hw_pending_inc(dev, msta);
+		if (mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[qid], skb, 0) &&
+		    txs)
+			mt7603_hw_pending_dec(dev, msta);
 	}
 }
 
@@ -420,7 +430,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
 	skb_queue_splice_tail_init(&msta->psq, &list);
 	spin_unlock_bh(&dev->ps_lock);
 
-	mt7603_ps_tx_list(dev, &list);
+	mt7603_ps_tx_list(dev, msta, &list);
 }
 
 static struct ieee80211_hdr *
@@ -529,7 +539,7 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
 		    !ieee80211_is_data_qos(mt7603_ps_skb_hdr(last)->frame_control);
 	last_tid = __fls(tids);
 
-	mt7603_ps_tx_list(dev, &list);
+	mt7603_ps_tx_list(dev, msta, &list);
 
 	if (eosp_null)
 		ieee80211_send_eosp_nullfunc(sta, last_tid);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 5b0ecd01aad95..b7b2225341451 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -20,6 +20,19 @@
 #define MT7603_TX_RING_SIZE	256
 #define MT7603_PSD_RING_SIZE	128
 
+/*
+ * Frames a station may have in the hardware (tx ring and PSE) before its
+ * tx queues are held, and the count at which they are released.
+ */
+#define MT7603_HW_CAP_HIGH	96
+#define MT7603_HW_CAP_LOW	48
+
+/*
+ * Frames looped back by the PSE for a sleeping station. They are sent again
+ * on wake-up, so leave room in the tx ring for other traffic.
+ */
+#define MT7603_PSQ_MAX		(MT7603_TX_RING_SIZE - 64)
+
 #define MT7603_FIRMWARE_E1	"mt7603_e1.bin"
 #define MT7603_FIRMWARE_E2	"mt7603_e2.bin"
 #define MT7628_FIRMWARE_E1	"mt7628_e1.bin"
@@ -81,6 +94,14 @@ struct mt7603_sta {
 
 	u8 ps;
 	u8 ps_sleeping;
+
+	/*
+	 * Frames queued to the hardware that still owe a TX status. The
+	 * hardware completes frames to mac80211 once DMA has copied them, so
+	 * AQL cannot bound how many it holds for the station.
+	 */
+	atomic_t hw_pending;
+	unsigned long hw_settled;
 };
 
 struct mt7603_vif {
@@ -156,8 +177,38 @@ struct mt7603_dev {
 	u32 reset_test;
 
 	unsigned int reset_cause[__RESET_CAUSE_MAX];
+
+	/* per-station cap on frames in the hardware, 0 = off (debugfs) */
+	u32 hw_cap_high;
+	u32 hw_cap_low;
+	u32 hw_cap_resync;
 };
 
+void mt7603_hw_release(struct mt7603_dev *dev, struct mt7603_sta *msta);
+
+static inline void
+mt7603_hw_pending_inc(struct mt7603_dev *dev, struct mt7603_sta *msta)
+{
+	int pending = atomic_inc_return(&msta->hw_pending);
+	u32 high = READ_ONCE(dev->hw_cap_high);
+
+	if (high && pending >= high &&
+	    !test_and_set_bit(MT_WCID_FLAG_TX_HOLD, &msta->wcid.flags))
+		WRITE_ONCE(msta->hw_settled, jiffies);
+}
+
+static inline void
+mt7603_hw_pending_dec(struct mt7603_dev *dev, struct mt7603_sta *msta)
+{
+	WRITE_ONCE(msta->hw_settled, jiffies);
+	if (!atomic_add_unless(&msta->hw_pending, -1, 0))
+		return;
+
+	if (test_bit(MT_WCID_FLAG_TX_HOLD, &msta->wcid.flags) &&
+	    atomic_read(&msta->hw_pending) <= READ_ONCE(dev->hw_cap_low))
+		mt7603_hw_release(dev, msta);
+}
+
 extern const struct mt76_driver_ops mt7603_drv_ops;
 extern const struct ieee80211_ops mt7603_ops;
 extern struct pci_driver mt7603_pci_driver;
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 3707ee19e4ae7..e16a380c6daf8 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -534,6 +534,10 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,
 		if (stop || mt76_txq_stopped(q))
 			break;
 
+		/* The previous frame may have filled the hardware. */
+		if (test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
+			break;
+
 		skb = mt76_txq_dequeue(phy, mtxq);
 		if (!skb)
 			break;
@@ -605,6 +609,9 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
 
 		if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
 			continue;
+		/* The driver schedules the queues again when it lifts the hold. */
+		if (test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
+			continue;
 		if (dev->queue_ops->tx_cleanup &&
 		    q->queued + 2 * MT_TXQ_FREE_THR >= q->ndesc) {
 			dev->queue_ops->tx_cleanup(dev, q, false);

3/2 2026/09/25 19:23 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 8528
							output: 38
							thoughts: 437
						

Thoughts:
**Analyzing the Proposed Patch**

Okay, so this patch is targeting the MediaTek mt76 wireless driver, specifically within the `mt7603` sub-directory. I immediately need to understand the scope and implications of this. It's touching several key files: `mt76.h`, `debugfs.c`, `dma.c`, `init.c`, `mac.c`, `main.c`, `mt7603.h`, and `tx.c`. That's a good chunk of code, so this could have a significant impact.

First, I need to refresh my understanding of what `mt7603` *is*. What's the underlying hardware here? Is this PCI, MMIO, USB, or something else entirely? I need to know the physical interface to fully grasp the potential impact of the changes. I'll start by searching the codebase for instances of "mt7603" and quickly scanning the Kconfig entries and driver bindings. This will give me a quick overview of how it's used and configured.

Does the `mt76` framework have broader support across different interfaces? Does it handle USB devices, or is `mt7603` strictly PCIe/MMIO? My recollection is that `mt76` covers multiple chipsets, like the `mt76x02` (USB and PCI), `mt7603e` (PCI), and newer families like `mt7615`, `mt7915`, and `mt7921` (USB, PCI, SDIO). Is `mt7603` a real hardware variant, or can it be emulated for testing? Could this be reached via USB gadget, hwsim, or mac80211_hwsim? I need to check these details to have a full understanding of what's going on here.

Right, I'm going to jump straight to the `mt7603` Kconfig and associated driver files. That should give me a solid foundation for interpreting the patch.



4/2 2026/09/25 19:24 tool grepper
0m Args:
{
  "Expression": "config MT7603",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/mediatek/mt76/mt7603/Kconfig:2:config MT7603E\ndrivers/net/wireless/mediatek/mt76/mt7603/Kconfig-3-\ttristate \"MediaTek MT7603E (PCIe) and MT76x8 WLAN support\"\n"
}

5/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 9577
							output: 47
							thoughts: 27
						

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

**Diving into the MT7603 Kconfig File**

Alright, time to get my hands dirty. I need to understand the configuration options for the MT7603 driver within the Mediatek wireless stack. My first thought is to jump directly into the source of truth, the `drivers/net/wireless/mediatek/mt76/mt7603/Kconfig` file. I'm assuming that's where the core configuration parameters, dependencies, and default values for this specific module are defined. I expect to find the building blocks for how this driver is compiled and its operational parameters. I want to see which features are enabled by default, what dependencies exist, and how other drivers or modules interact with it. From there, I'll be in a better position to assess any conflicts, potential performance optimizations, or required modifications for the current project. I'm looking for the granular details, not just a high-level overview. This Kconfig file will be the key to understanding how to configure the MT7603 driver appropriately.



6/2 2026/09/25 19:24 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig",
  "FirstLine": 1,
  "LineCount": 20
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: BSD-3-Clause-Clear\n   2:\tconfig MT7603E\n   3:\t\ttristate \"MediaTek MT7603E (PCIe) and MT76x8 WLAN support\"\n   4:\t\tselect MT76_CORE\n   5:\t\tdepends on MAC80211\n   6:\t\tdepends on PCI\n   7:\t\thelp\n   8:\t\t  This adds support for MT7603E PCIe wireless devices and the WLAN core\n   9:\t\t  on MT7628/MT7688 SoC devices. This family supports IEEE 802.11n 2x2\n  10:\t\t  to 300Mbps PHY rate\n  11:\t\n  12:\t\t  To compile this driver as a module, choose M here.\n"
}

7/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 10103
							output: 36
							thoughts: 552
						

Thoughts:
**My Current Line of Reasoning**

Okay, hold on a second! The MT7603E, as I recall, relies on PCI, doesn't it? I need to clarify: is the MT7603E a *physical* PCIe device? This is critical for understanding the attack surface. Right, now, I should also check `drivers/net/wireless/mediatek/mt76/tx.c` since that is where the important functions relating to transmission reside. Wait a minute... `tx.c` is actually part of the `mt76` core, `MT76_CORE`, which means any changes there are potentially quite impactful.

Let's carefully examine the changes in `drivers/net/wireless/mediatek/mt76/tx.c`. ( *reads the code snippet* ) Okay, interesting... I see a couple of lines related to `MT_WCID_FLAG_TX_HOLD`. This suggests some form of flow control or pausing of transmission, possibly triggered by the hardware being full. And also a check that stops the scheduling function when the hardware is on hold.

Now, a completely different, but relevant, question: Does MT76 support USB? I need to think about that, because, if it does, it opens up the possibility of fuzzing MT76 USB devices in syzkaller using USB emulation – specifically, Raw Gadget or the syzkaller USB fuzzing methods. I should check which drivers select either `MT76_CORE` or `MT76_USB` to confirm the code paths used by each kind of hardware. This is essential to understand where the greatest potential for exploitation lies.



8/2 2026/09/25 19:24 tool grepper
0m Args:
{
  "Expression": "config MT76",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/Kconfig-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/mediatek/mt76/Kconfig:2:config MT76_CORE\ndrivers/net/wireless/mediatek/mt76/Kconfig-3-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-5-\ndrivers/net/wireless/mediatek/mt76/Kconfig:6:config MT76_LEDS\ndrivers/net/wireless/mediatek/mt76/Kconfig-7-\tbool\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-11-\ndrivers/net/wireless/mediatek/mt76/Kconfig:12:config MT76_USB\ndrivers/net/wireless/mediatek/mt76/Kconfig-13-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-15-\ndrivers/net/wireless/mediatek/mt76/Kconfig:16:config MT76_SDIO\ndrivers/net/wireless/mediatek/mt76/Kconfig-17-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-19-\ndrivers/net/wireless/mediatek/mt76/Kconfig:20:config MT76x02_LIB\ndrivers/net/wireless/mediatek/mt76/Kconfig-21-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-23-\ndrivers/net/wireless/mediatek/mt76/Kconfig:24:config MT76x02_USB\ndrivers/net/wireless/mediatek/mt76/Kconfig-25-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-27-\ndrivers/net/wireless/mediatek/mt76/Kconfig:28:config MT76_CONNAC_LIB\ndrivers/net/wireless/mediatek/mt76/Kconfig-29-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig=36=config MT792x_USB\n--\ndrivers/net/wireless/mediatek/mt76/Kconfig-39-\ndrivers/net/wireless/mediatek/mt76/Kconfig:40:config MT76_NPU\ndrivers/net/wireless/mediatek/mt76/Kconfig-41-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/Kconfig-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/mediatek/mt76/mt7603/Kconfig:2:config MT7603E\ndrivers/net/wireless/mediatek/mt76/mt7603/Kconfig-3-\ttristate \"MediaTek MT7603E (PCIe) and MT76x8 WLAN support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-2-\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:3:config MT7615_COMMON\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-4-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-7-\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:8:config MT7615E\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-9-\ttristate \"MediaTek MT7615E and MT7663E (PCIe) support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-20-\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:21:config MT7622_WMAC\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-22-\tbool \"MT7622 (SoC) WMAC support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-31-\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:32:config MT7663_USB_SDIO_COMMON\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-33-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-35-\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:36:config MT7663U\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-37-\ttristate \"MediaTek MT7663U (USB) support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-46-\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:47:config MT7663S\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-48-\ttristate \"MediaTek MT7663S (SDIO) support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig:2:config MT76x0_COMMON\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig-3-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig-5-\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig:6:config MT76x0U\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig-7-\ttristate \"MediaTek MT76x0U (USB) support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig-18-\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig:19:config MT76x0E\ndrivers/net/wireless/mediatek/mt76/mt76x0/Kconfig-20-\ttristate \"MediaTek MT76x0E (PCIe) support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig:2:config MT76x2_COMMON\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig-3-\ttristate\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig-5-\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig:6:config MT76x2E\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig-7-\ttristate \"MediaTek MT76x2E (PCIe) support\"\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig-17-\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig:18:config MT76x2U\ndrivers/net/wireless/mediatek/mt76/mt76x2/Kconfig-19-\ttristate \"MediaTek MT76x2U (USB) support\"\n"
}

9/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 13031
							output: 42
							thoughts: 98
						

Thoughts:
**Analyzing MT76_CORE USB Device Driver Behavior**

Okay, so I'm looking at USB devices that are built on the MT76_CORE architecture – devices like the MT76x0U, MT76x2U, MT7663U, and MT7921U, just to name a few. My immediate thought is to understand the finer details of the driver's inner workings. Specifically, I need to know *who* or *what* is setting the `MT_WCID_FLAG_TX_HOLD` flag, and *when*. This flag is crucial because it likely controls the transmission hold mechanism. My mental flow goes immediately to tracking the usage of this specific flag.

Time to dive into the codebase. I'm going to head over to the `drivers/net/wireless/mediatek/mt76/` directory. That's where the heart of the driver resides. From there, a quick `grep` for `MT_WCID_FLAG_TX_HOLD` will be exactly what's needed to find out who's using this flag, and in what context. This should immediately give me a clear picture of how this transmission hold functionality is managed within the driver.



10/2 2026/09/25 19:24 tool grepper
0m Args:
{
  "Expression": "MT_WCID_FLAG_TX_HOLD",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt76.h=359=enum mt76_wcid_flags {\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h-364-\tMT_WCID_FLAG_TDLS_PEER,\ndrivers/net/wireless/mediatek/mt76/mt76.h:365:\tMT_WCID_FLAG_TX_HOLD,\ndrivers/net/wireless/mediatek/mt76/mt76.h-366-};\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/debugfs.c=97=mt7603_hw_cap_read(struct seq_file *s, void *data)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/debugfs.c-116-\t\t\t   atomic_read(\u0026msta-\u003ehw_pending),\ndrivers/net/wireless/mediatek/mt76/mt7603/debugfs.c:117:\t\t\t   test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags));\ndrivers/net/wireless/mediatek/mt76/mt7603/debugfs.c-118-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c=1887=void mt7603_hw_release(struct mt7603_dev *dev, struct mt7603_sta *msta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1891-\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1892:\tif (!test_and_clear_bit(MT_WCID_FLAG_TX_HOLD, \u0026msta-\u003ewcid.flags))\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1893-\t\treturn;\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c=1908=mt7603_hw_cap_check(struct mt7603_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1918-\t\tif (!wcid || !wcid-\u003esta ||\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1919:\t\t    !test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags))\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1920-\t\t\tcontinue;\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h=190=mt7603_hw_pending_inc(struct mt7603_dev *dev, struct mt7603_sta *msta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h-195-\tif (high \u0026\u0026 pending \u003e= high \u0026\u0026\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h:196:\t    !test_and_set_bit(MT_WCID_FLAG_TX_HOLD, \u0026msta-\u003ewcid.flags))\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h-197-\t\tWRITE_ONCE(msta-\u003ehw_settled, jiffies);\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h=201=mt7603_hw_pending_dec(struct mt7603_dev *dev, struct mt7603_sta *msta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h-206-\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h:207:\tif (test_bit(MT_WCID_FLAG_TX_HOLD, \u0026msta-\u003ewcid.flags) \u0026\u0026\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h-208-\t    atomic_read(\u0026msta-\u003ehw_pending) \u003c= READ_ONCE(dev-\u003ehw_cap_low))\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=490=mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-537-\t\t/* The previous frame may have filled the hardware. */\ndrivers/net/wireless/mediatek/mt76/tx.c:538:\t\tif (test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags))\ndrivers/net/wireless/mediatek/mt76/tx.c-539-\t\t\tbreak;\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=568=mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-612-\t\t/* The driver schedules the queues again when it lifts the hold. */\ndrivers/net/wireless/mediatek/mt76/tx.c:613:\t\tif (test_bit(MT_WCID_FLAG_TX_HOLD, \u0026wcid-\u003eflags))\ndrivers/net/wireless/mediatek/mt76/tx.c-614-\t\t\tcontinue;\n"
}

11/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 14901
							output: 43
							thoughts: 250
						

Thoughts:
**My Assessment of mt7603 Reachability for Fuzzing**

Okay, so I see that `mt7603` is the *only* thing setting the `MT_WCID_FLAG_TX_HOLD` flag. That's interesting, but the first thing I need to figure out is, is it even *reachable* for fuzzing? Can I get at it in a standard virtualized environment like QEMU or GCE? I need to adhere to the guidelines.

Let's see…Section 2 of the fuzzing guidelines says, and this is key, *reachability is the primary gate.* If I can't get the code to execute in a standard virtualized environment, no fuzzing. It emphasizes software-emulated devices like USB gadgets, netdev, or tun/tap are the norm for reachability. Hardware that's *structurally unreachable*, like vendor-specific PCIe switches, SmartNICs, or GPU drivers that need actual hardware or special PCIe cards not emulated in QEMU, are right out. Examples are `mlxsw`, `pds_core`, `qed`, `ionic`, and `amdgpu`.

So back to `mt7603`. Is it a physical PCIe device? Is it an SoC device? I need to know where it binds. I need to know what devices it's talking to to work out where and how I can reach it in a testing environment. Let's find out what devices `MT7603` binds to!



12/2 2026/09/25 19:24 tool grepper
0m Args:
{
  "Expression": "MODULE_DEVICE_TABLE",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7603"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7603/pci.c=66=mt76pci_remove(struct pci_dev *pdev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c-73-\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c:74:MODULE_DEVICE_TABLE(pci, mt76pci_device_table);\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c-75-MODULE_FIRMWARE(MT7603_FIRMWARE_E1);\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c=63=static const struct of_device_id of_wmac_match[] = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c-67-\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c:68:MODULE_DEVICE_TABLE(of, of_wmac_match);\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c-69-MODULE_FIRMWARE(MT7628_FIRMWARE_E1);\n"
}

13/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 15861
							output: 36
							thoughts: 59
						

Thoughts:
Okay, here's my assessment of the situation:

**Initial Assessment of the MT7603 Driver Structure**

Hmm, this is interesting. The `mt7603` driver directory seems... streamlined, to put it mildly. I'm seeing only `pci.c` and `soc.c` files. That's a limited set of source files for a wireless driver, particularly one that likely supports a variety of functions. Given the likely complexity of the MT7603 chipsets, this minimal structure warrants immediate investigation. My next logical step is to dive into those two files directly. I need to understand how the PCI and SoC specific code is structured, and how the core functionality might be partitioned (or integrated) across them. Let's see what's really happening in `drivers/net/wireless/mediatek/mt76/mt7603/pci.c` and `soc.c`.



14/2 2026/09/25 19:24 tool codesearch-dir-index
0m Args:
{
  "Dir": "drivers/net/wireless/mediatek/mt76/mt7603"
}

Results:
{
  "Files": [
    "beacon.c",
    "core.c",
    "debugfs.c",
    "dma.c",
    "eeprom.c",
    "eeprom.h",
    "init.c",
    "mac.c",
    "mac.h",
    "main.c",
    "mcu.c",
    "mcu.h",
    "mt7603.h",
    "pci.c",
    "regs.h",
    "soc.c"
  ],
  "Subdirs": null
}

15/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 16275
							output: 42
							thoughts: 359
						

Thoughts:
**Analyzing the MT7603 Driver's TX Path**

Okay, so I'm focusing on the MT7603 driver. From my knowledge, it's primarily a PCIe device (`pci.c`) and interacts with the MT7628/MT7688 MIPS SoC via the device tree (`soc.c`). But hold on, I remember a change in `tx.c`, right? Let's dig into that.

`tx.c` is located in `drivers/net/wireless/mediatek/mt76/tx.c`. Let's see... looking at the code for `mt76_txq_send_burst()` I see this:

```c
		/* The previous frame may have filled the hardware. */
		if (test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
			break;
```

And in `mt76_txq_schedule_list()`:

```c
		/* The driver schedules the queues again when it lifts the hold. */
		if (test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
			continue;
```

That `MT_WCID_FLAG_TX_HOLD`... Hmm, I wonder if other drivers are using this bit? Let me check its definition in `mt76.h`. Right, only the `mt7603` driver sets and clears it!

Now, even if another driver like the mt76x0u or mt76x2u (USB based) might use `tx.c` directly, I'm pretty sure they *never* set `MT_WCID_FLAG_TX_HOLD`. But let's verify that. Do the USB drivers even call those functions `mt76_txq_send_burst` or `mt76_txq_schedule_list`? Gotta check the code, just to be absolutely sure.



16/2 2026/09/25 19:24 tool grepper
0m Args:
{
  "Expression": "mt76_txq_schedule_list",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/tx.c=567=static int\ndrivers/net/wireless/mediatek/mt76/tx.c:568:mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)\ndrivers/net/wireless/mediatek/mt76/tx.c-569-{\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=645=void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid)\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-656-\t\tieee80211_txq_schedule_start(phy-\u003ehw, qid);\ndrivers/net/wireless/mediatek/mt76/tx.c:657:\t\tlen = mt76_txq_schedule_list(phy, qid);\ndrivers/net/wireless/mediatek/mt76/tx.c-658-\t\tieee80211_txq_schedule_end(phy-\u003ehw, qid);\n"
}

17/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 17407
							output: 40
							thoughts: 46
						

Thoughts:
Okay, let's break this down.

**Analyzing the Call Chain: `mt76_txq_schedule_list`**

Right, so `mt76_txq_schedule_list` – I need to understand its role in this system. From what I'm seeing, it's *only* called by `mt76_txq_schedule`. That narrows down the scope of where I need to look for dependencies and context significantly. Now the crucial question is, who or what actually triggers `mt76_txq_schedule`? Understanding the calling functions of `mt76_txq_schedule` is the key to figuring out the overall flow and purpose of `mt76_txq_schedule_list`. I need to trace back from this point.



18/2 2026/09/25 19:24 tool grepper
0m Args:
{
  "Expression": "mt76_txq_schedule",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mac80211.c=1048=int __mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1055-\tmt76_worker_disable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1056:\tmt76_txq_schedule_pending(phy);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1057-\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h=1536=void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb);\ndrivers/net/wireless/mediatek/mt76/mt76.h:1537:void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid);\ndrivers/net/wireless/mediatek/mt76/mt76.h:1538:void mt76_txq_schedule_all(struct mt76_phy *phy);\ndrivers/net/wireless/mediatek/mt76/mt76.h:1539:void mt76_txq_schedule_pending(struct mt76_phy *phy);\ndrivers/net/wireless/mediatek/mt76/mt76.h-1540-void mt76_tx_worker_run(struct mt76_dev *dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c=1446=static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1455-\t/* lock/unlock all queues to ensure that no tx is pending */\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1456:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1457-\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1520-\tieee80211_wake_queues(dev-\u003emt76.hw);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1521:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1522-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c=201=void mt7615_mac_reset_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-233-\t/* lock/unlock all queues to ensure that no tx is pending */\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c:234:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-235-\tif (ext_phy)\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c:236:\t\tmt76_txq_schedule_all(ext_phy);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-237-\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c=139=static void mt76x02_tx_worker(struct mt76_worker *w)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-147-\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:148:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-149-}\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c=433=static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-523-\t\tieee80211_wake_queues(dev-\u003emt76.hw);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:524:\t\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-525-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c=1290=mt7915_mac_restart(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1322-\t/* lock/unlock all queues to ensure that no tx is pending */\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1323:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1324-\tif (ext_phy)\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1325:\t\tmt76_txq_schedule_all(ext_phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1326-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c=56=int mt7921e_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c-70-\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c:71:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c-72-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c=209=static int mt7921s_suspend(struct device *__dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-234-\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c:235:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-236-\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c=147=int mt7921s_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c-156-\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c:157:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c-158-\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c=89=static int mt7921u_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-96-\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c:97:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-98-\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c=71=int mt7925e_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c-87-\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c:88:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c-89-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c=80=static int mt7925u_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-90-\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c:91:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-92-\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c=381=void mt792x_tx_worker(struct mt76_worker *w)\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-390-\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c:391:\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-392-\tmt76_connac_pm_unref(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c=2286=mt7996_mac_restart(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2309-\tmt7996_for_each_phy(dev, phy)\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c:2310:\t\tmt76_txq_schedule_all(phy-\u003emt76);\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2311-\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=567=static int\ndrivers/net/wireless/mediatek/mt76/tx.c:568:mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)\ndrivers/net/wireless/mediatek/mt76/tx.c-569-{\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-644-\ndrivers/net/wireless/mediatek/mt76/tx.c:645:void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid)\ndrivers/net/wireless/mediatek/mt76/tx.c-646-{\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-656-\t\tieee80211_txq_schedule_start(phy-\u003ehw, qid);\ndrivers/net/wireless/mediatek/mt76/tx.c:657:\t\tlen = mt76_txq_schedule_list(phy, qid);\ndrivers/net/wireless/mediatek/mt76/tx.c-658-\t\tieee80211_txq_schedule_end(phy-\u003ehw, qid);\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-663-}\ndrivers/net/wireless/mediatek/mt76/tx.c:664:EXPORT_SYMBOL_GPL(mt76_txq_schedule);\ndrivers/net/wireless/mediatek/mt76/tx.c-665-\ndrivers/net/wireless/mediatek/mt76/tx.c=666=static int\ndrivers/net/wireless/mediatek/mt76/tx.c:667:mt76_txq_schedule_pending_wcid(struct mt76_phy *phy, struct mt76_wcid *wcid,\ndrivers/net/wireless/mediatek/mt76/tx.c-668-\t\t\t       struct sk_buff_head *head)\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-712-\ndrivers/net/wireless/mediatek/mt76/tx.c:713:void mt76_txq_schedule_pending(struct mt76_phy *phy)\ndrivers/net/wireless/mediatek/mt76/tx.c-714-{\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-733-\t\tif (ret \u003e= 0)\ndrivers/net/wireless/mediatek/mt76/tx.c:734:\t\t\tret = mt76_txq_schedule_pending_wcid(phy, wcid, \u0026wcid-\u003etx_offchannel);\ndrivers/net/wireless/mediatek/mt76/tx.c-735-\t\tif (ret \u003e= 0 \u0026\u0026 !phy-\u003eoffchannel)\ndrivers/net/wireless/mediatek/mt76/tx.c:736:\t\t\tret = mt76_txq_schedule_pending_wcid(phy, wcid, \u0026wcid-\u003etx_pending);\ndrivers/net/wireless/mediatek/mt76/tx.c-737-\t\tspin_lock(\u0026phy-\u003etx_lock);\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-749-\ndrivers/net/wireless/mediatek/mt76/tx.c:750:void mt76_txq_schedule_all(struct mt76_phy *phy)\ndrivers/net/wireless/mediatek/mt76/tx.c-751-{\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-754-\ndrivers/net/wireless/mediatek/mt76/tx.c:755:\tmt76_txq_schedule_pending(phy);\ndrivers/net/wireless/mediatek/mt76/tx.c-756-\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-760-\tfor (i = 0; i \u003c= MT_TXQ_BK; i++)\ndrivers/net/wireless/mediatek/mt76/tx.c:761:\t\tmt76_txq_schedule(phy, i);\ndrivers/net/wireless/mediatek/mt76/tx.c-762-}\ndrivers/net/wireless/mediatek/mt76/tx.c:763:EXPORT_SYMBOL_GPL(mt76_txq_schedule_all);\ndrivers/net/wireless/mediatek/mt76/tx.c-764-\ndrivers/net/wireless/mediatek/mt76/tx.c=765=void mt76_tx_worker_run(struct mt76_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-769-\ndrivers/net/wireless/mediatek/mt76/tx.c:770:\tmt76_txq_schedule_all(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/tx.c-771-\tfor (i = 0; i \u003c ARRAY_SIZE(dev-\u003ephys); i++) {\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-775-\ndrivers/net/wireless/mediatek/mt76/tx.c:776:\t\tmt76_txq_schedule_all(phy);\ndrivers/net/wireless/mediatek/mt76/tx.c-777-\t}\n"
}

19/2 2026/09/25 19:24 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 22058
							output: 49
							thoughts: 880
						

Thoughts:
**Analyzing the Syzkaller Potential for MT76 USB Driver Fuzzing**

Okay, so I'm thinking about how to effectively fuzz MT76 USB devices using syzkaller. The initial question is: can these devices be probed via the raw-gadget functionality? And, if a probe even happens, does it need firmware to complete? My next step is to examine the probe behavior of `mt76x0u`, `mt76x2u`, and `mt7921u`. Can they be probed without firmware, or do they fail early? Can syzkaller trigger their probing?

I need to confirm if syzkaller has any specific descriptions for MT76 devices in its `sys/linux` directory. Or, does the USB raw-gadget fuzzing technique inherently trigger driver probes, which I suspect may be the key. In standard syzkaller setups, USB pseudo-devices are usually enumerated using `/dev/raw-gadget` or dummy_hcd, right? If I plug in a USB device with a VID/PID matching those of the mt76x0u/mt76x2u, will it probe successfully and set up an interface? That's the crux of it.

I then started to dig deeper, specifically thinking about the `MT_WCID_FLAG_TX_HOLD` flag. Can USB devices set this flag? No! It turns out `MT_WCID_FLAG_TX_HOLD` is exclusively set by `mt7603_hw_pending_inc`, which is *only* defined and used within `drivers/net/wireless/mediatek/mt76/mt7603/`! No other MT76 USB driver utilizes this flag. I realized, for all other drivers, `test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags)` will always evaluate to false, so my assumptions are being shifted. I am now questioning whether this flag is even executed during USB packet transmission.

Furthermore, can an MT76 USB device actually transmit a packet within a QEMU environment? Does the raw-gadget setup even allow for wifi packet transmission on MT76? Now I recall that all the MT76 USB drivers require firmware to be loaded before the network interface can even be brought up. Considering QEMU/syzkaller, is the required MT76 firmware even available? Standard syzkaller images don't include the necessary MediaTek wifi firmware files because `linux-firmware` isn't installed. And, even if it was, raw-gadget USB devices can't respond to vendor-specific register reads/writes which are needed for the firmware handshake.

The more significant question here is how accessible MT7603 is in standard virtualized environments like GCE or QEMU. Let me verify what MT7603 entails by examining `drivers/net/wireless/mediatek/mt76/mt7603/`, specifically `mt7603/pci.c`, to check the `mt76pci_device_table` PCI ID.



20/2 2026/09/25 19:25 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7603/pci.c",
  "FirstLine": 1,
  "LineCount": 80
}

Results:
{
  "Contents": "   1:\t// SPDX-License-Identifier: BSD-3-Clause-Clear\n   2:\t\n   3:\t#include \u003clinux/kernel.h\u003e\n   4:\t#include \u003clinux/module.h\u003e\n   5:\t#include \u003clinux/pci.h\u003e\n   6:\t\n   7:\t#include \"mt7603.h\"\n   8:\t\n   9:\tstatic const struct pci_device_id mt76pci_device_table[] = {\n  10:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7603) },\n  11:\t\t{ },\n  12:\t};\n  13:\t\n  14:\tstatic int\n  15:\tmt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n  16:\t{\n  17:\t\tstruct mt7603_dev *dev;\n  18:\t\tstruct mt76_dev *mdev;\n  19:\t\tint ret;\n  20:\t\n  21:\t\tret = pcim_enable_device(pdev);\n  22:\t\tif (ret)\n  23:\t\t\treturn ret;\n  24:\t\n  25:\t\tret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));\n  26:\t\tif (ret)\n  27:\t\t\treturn ret;\n  28:\t\n  29:\t\tpci_set_master(pdev);\n  30:\t\n  31:\t\tret = dma_set_mask(\u0026pdev-\u003edev, DMA_BIT_MASK(32));\n  32:\t\tif (ret)\n  33:\t\t\treturn ret;\n  34:\t\n  35:\t\tmdev = mt76_alloc_device(\u0026pdev-\u003edev, sizeof(*dev), \u0026mt7603_ops,\n  36:\t\t\t\t\t \u0026mt7603_drv_ops);\n  37:\t\tif (!mdev)\n  38:\t\t\treturn -ENOMEM;\n  39:\t\n  40:\t\tdev = container_of(mdev, struct mt7603_dev, mt76);\n  41:\t\tmt76_mmio_init(mdev, pcim_iomap_table(pdev)[0]);\n  42:\t\n  43:\t\tmdev-\u003erev = (mt76_rr(dev, MT_HW_CHIPID) \u003c\u003c 16) |\n  44:\t\t\t    (mt76_rr(dev, MT_HW_REV) \u0026 0xff);\n  45:\t\tdev_info(mdev-\u003edev, \"ASIC revision: %04x\\n\", mdev-\u003erev);\n  46:\t\n  47:\t\tmt76_wr(dev, MT_INT_MASK_CSR, 0);\n  48:\t\n  49:\t\tret = devm_request_irq(mdev-\u003edev, pdev-\u003eirq, mt7603_irq_handler,\n  50:\t\t\t\t       IRQF_SHARED, KBUILD_MODNAME, dev);\n  51:\t\tif (ret)\n  52:\t\t\tgoto error;\n  53:\t\n  54:\t\tret = mt7603_register_device(dev);\n  55:\t\tif (ret)\n  56:\t\t\tgoto error;\n  57:\t\n  58:\t\treturn 0;\n  59:\terror:\n  60:\t\tmt76_free_device(\u0026dev-\u003emt76);\n  61:\t\n  62:\t\treturn ret;\n  63:\t}\n  64:\t\n  65:\tstatic void\n  66:\tmt76pci_remove(struct pci_dev *pdev)\n  67:\t{\n  68:\t\tstruct mt76_dev *mdev = pci_get_drvdata(pdev);\n  69:\t\tstruct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);\n  70:\t\n  71:\t\tmt7603_unregister_device(dev);\n  72:\t}\n  73:\t\n  74:\tMODULE_DEVICE_TABLE(pci, mt76pci_device_table);\n  75:\tMODULE_FIRMWARE(MT7603_FIRMWARE_E1);\n  76:\tMODULE_FIRMWARE(MT7603_FIRMWARE_E2);\n  77:\t\n  78:\tstruct pci_driver mt7603_pci_driver = {\n  79:\t\t.name\t\t= KBUILD_MODNAME,\n  80:\t\t.id_table\t= mt76pci_device_table,\n"
}

21/2 2026/09/25 19:25 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 24859
							output: 38
							thoughts: 768
						

Thoughts:
**Analyzing Reachability for Fuzzing**

Okay, so I've got `mt7603_pci_driver` matching `PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7603)`.  Right, that's a physical MediaTek PCIe NIC. And, I see `soc.c` matching `mediatek,mt7628-wmac`, which confirms that's an on-chip WLAN core for those MediaTek MT7628 / MT7688 MIPS SoCs.  The problem?  Standard QEMU or Google Compute Engine (GCE) *don't* emulate either of these. So, standard QEMU absolutely does NOT emulate that MediaTek MT7603 PCIe NIC or the MT7628 MIPS SoC.

Now, let's carefully consider the core triage philosophy, particularly sections one and two.  Reachability is the primary gate – fuzzing is only effective if the code can execute in those standard virtualized environments. If the modified code is *structurally* unreachable, it shouldn't be fuzzed, no matter what it does with assertions or complex logic.

Specifically, section two says we should return `WorthFuzzing=false` when the modified code falls into the "structurally unreachable hardware" category, like vendor-specific PCIe switches, SmartNICs, or GPU drivers requiring physical ASIC/PCIe cards. Examples given: `mlxsw`, `pds_core`, `qed`, `ionic`, `amdgpu`. These definitely need physical hardware.

So, the next question is: what about the changes in `tx.c`?  That's where things get interesting.  Let's check `drivers/net/wireless/mediatek/mt76/tx.c`. Can *any* virtual or emulated hardware actually reach this code?  Hold on... could another driver potentially *use* `tx.c`?  We need to look at what other drivers exist in `drivers/net/wireless/mediatek/mt76/`.

I see:
*   `mt7603` (PCIe / SoC) - Well, that's physical hardware only, right? It's the one we originally identified as requiring a PCIe card.
*   `mt7615` (PCIe / USB MT7663U / SDIO)
*   `mt76x0` (PCIe / USB MT76x0U)
*   `mt76x2` (PCIe / USB MT76x2U)
*   `mt7915` (PCIe)
*   `mt7921` (PCIe / USB MT7921U / SDIO)
*   `mt7925` (PCIe / USB MT7925U)
*   `mt7996` (PCIe)

Okay, so we've got a bunch of PCIe and USB options. Could an *emulated* USB device, perhaps via raw-gadget in syzkaller, reach `tx.c`?  That’s the critical question.

Can raw-gadget fuzzing reach mt76 USB drivers to the point of running `mt76_txq_send_burst` or `mt76_txq_schedule_list`? This is the core to being worth fuzzing or not.

But first, to even get a network interface registered in mt76 USB: We need to see how the device is registered with the kernel.

So, where is the probe function for mt76 USB? Let's check `mt76x02_usb.c` or similar. I'll start there. We need to identify if there is a path to the functions we are looking for.



22/2 2026/09/25 19:25 tool grepper
0m Args:
{
  "Expression": "mt76.*_probe",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7603/pci.c=14=static int\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c:15:mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c-16-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c=78=struct pci_driver mt7603_pci_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c-80-\t.id_table\t= mt76pci_device_table,\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c:81:\t.probe\t\t= mt76pci_probe,\ndrivers/net/wireless/mediatek/mt76/mt7603/pci.c-82-\t.remove\t\t= mt76pci_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c=9=static int\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c:10:mt76_wmac_probe(struct platform_device *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c-11-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c=72=struct platform_driver mt76_wmac_driver = {\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c:73:\t.probe\t\t= mt76_wmac_probe,\ndrivers/net/wireless/mediatek/mt76/mt7603/soc.c-74-\t.remove\t\t= mt76_wmac_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c=158=static u32 mt7615_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c-165-\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c:166:int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c-167-\t\t      int irq, const u32 *map)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=370=int mt7615_thermal_init(struct mt7615_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:371:int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-372-\t\t      int irq, const u32 *map);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c=15=static const struct pci_device_id mt7615_pci_device_table[] = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-21-\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:22:static int mt7615_pci_probe(struct pci_dev *pdev,\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-23-\t\t\t    const struct pci_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-48-\tmap = id-\u003edevice == 0x7663 ? mt7663e_reg_map : mt7615e_reg_map;\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:49:\tret = mt7615_mmio_probe(\u0026pdev-\u003edev, pcim_iomap_table(pdev)[0],\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-50-\t\t\t\tpdev-\u003eirq, map);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c=188=struct pci_driver mt7615_pci_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-190-\t.id_table\t= mt7615_pci_device_table,\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:191:\t.probe\t\t= mt7615_pci_probe,\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-192-\t.remove\t\t= mt7615_pci_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c=53=static int mt7663s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-75-\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:76:static int mt7663s_probe(struct sdio_func *func,\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-77-\t\t\t const struct sdio_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c=246=static struct sdio_driver mt7663s_driver = {\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-247-\t.name\t\t= KBUILD_MODNAME,\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:248:\t.probe\t\t= mt7663s_probe,\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-249-\t.remove\t\t= mt7663s_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c=16=int mt7622_wmac_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c-31-\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c:32:static int mt7622_wmac_probe(struct platform_device *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c-33-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c-44-\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c:45:\treturn mt7615_mmio_probe(\u0026pdev-\u003edev, mem_base, irq, mt7615e_reg_map);\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c-46-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c=60=struct platform_driver mt7622_wmac_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c-64-\t},\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c:65:\t.probe = mt7622_wmac_probe,\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c-66-\t.remove = mt7622_wmac_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c=101=static void mt7663u_init_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-111-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:112:static int mt7663u_probe(struct usb_interface *usb_intf,\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-113-\t\t\t const struct usb_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c=265=static struct usb_driver mt7663u_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-267-\t.id_table\t= mt7615_device_table,\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:268:\t.probe\t\t= mt7663u_probe,\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-269-\t.disconnect\t= mt7663u_disconnect,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c=153=static int\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c:154:mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-155-{\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c=316=static struct pci_driver mt76x0e_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-318-\t.id_table\t= mt76x0e_device_table,\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c:319:\t.probe\t\t= mt76x0e_probe,\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-320-\t.remove\t\t= mt76x0e_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c=179=static int mt76x0u_register_device(struct mt76x02_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c-212-\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c:213:static int mt76x0u_probe(struct usb_interface *usb_intf,\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c-214-\t\t\t const struct usb_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c=345=static struct usb_driver mt76x0_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c-347-\t.id_table\t= mt76x0_device_table,\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c:348:\t.probe\t\t= mt76x0u_probe,\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c-349-\t.disconnect\t= mt76x0_disconnect,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c=19=static int\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c:20:mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id)\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-21-{\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c=176=static struct pci_driver mt76pci_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-178-\t.id_table\t= mt76x2e_device_table,\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c:179:\t.probe\t\t= mt76x2e_probe,\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-180-\t.remove\t\t= mt76x2e_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c=12=static const struct usb_device_id mt76x2u_device_table[] = {\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c-31-\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c:32:static int mt76x2u_probe(struct usb_interface *intf,\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c-33-\t\t\t const struct usb_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c=137=static struct usb_driver mt76x2u_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c-139-\t.id_table\t= mt76x2u_device_table,\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c:140:\t.probe\t\t= mt76x2u_probe,\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c-141-\t.disconnect\t= mt76x2u_disconnect,\n--\ndrivers/net/wireless/mediatek/mt76/scan.c=53=static void\ndrivers/net/wireless/mediatek/mt76/scan.c:54:mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)\ndrivers/net/wireless/mediatek/mt76/scan.c-55-{\n--\ndrivers/net/wireless/mediatek/mt76/scan.c=124=void mt76_scan_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/scan.c-182-\tfor (i = 0; i \u003c req-\u003en_ssids; i++)\ndrivers/net/wireless/mediatek/mt76/scan.c:183:\t\tmt76_scan_send_probe(dev, \u0026req-\u003essids[i]);\ndrivers/net/wireless/mediatek/mt76/scan.c-184-\tlocal_bh_enable();\n"
}

23/2 2026/09/25 19:25 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 30584
							output: 50
							thoughts: 19
						

Thoughts:
Okay, let's dive into this `mt76x0u_probe` probe. Here's what I'm thinking:

**Analyzing the mt76x0u_probe Probe**

Alright, I'm going to start with a systematic examination of the `mt76x0u_probe` routine. First, I need to understand its role in the driver's overall initialization sequence. Is this where the core hardware identification and setup happen, or is it a later stage? Considering the name, "probe" suggests it's likely involved in detecting and configuring the hardware upon its connection.

I'll be looking for the standard hallmarks of a probe function. Are there checks for device IDs, vendor IDs, and device classes? Are there resource allocations? I'm expecting to see calls to functions that handle the USB communication setup, maybe some power management configuration, and definitely some device initialization sequences. I'll need to know whether it allocates any major data structures to keep track of the driver's state.

It's likely checking if the device can be supported, if this is an supported hardware that is. Is there a specific chip revision that's handled differently, or do we expect a simple if/else construct? This is where I'll look for specific hardware capabilities and configuration. What are the key registers it's reading or writing to? How is interrupt handling configured? I expect there will be at least a few.

Ultimately, my goal is to ascertain the critical steps the driver takes to bring the `mt76x0u` device online. What's the control flow? What are the key data structures used to manage the device, and how are they initialized? It's a matter of going through the code bit by bit to build up a mental model of this driver's initial steps.



24/2 2026/09/25 19:25 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt76x0/usb.c",
  "FirstLine": 213,
  "LineCount": 60
}

Results:
{
  "Contents": " 213:\tstatic int mt76x0u_probe(struct usb_interface *usb_intf,\n 214:\t\t\t\t const struct usb_device_id *id)\n 215:\t{\n 216:\t\tstatic const struct mt76_driver_ops drv_ops = {\n 217:\t\t\t.drv_flags = MT_DRV_SW_RX_AIRTIME |\n 218:\t\t\t\t     MT_DRV_IGNORE_TXS_FAILED,\n 219:\t\t\t.survey_flags = SURVEY_INFO_TIME_TX,\n 220:\t\t\t.update_survey = mt76x02_update_channel,\n 221:\t\t\t.set_channel = mt76x0_set_channel,\n 222:\t\t\t.tx_prepare_skb = mt76x02u_tx_prepare_skb,\n 223:\t\t\t.tx_complete_skb = mt76x02u_tx_complete_skb,\n 224:\t\t\t.tx_status_data = mt76x02_tx_status_data,\n 225:\t\t\t.rx_skb = mt76x02_queue_rx_skb,\n 226:\t\t\t.sta_ps = mt76x02_sta_ps,\n 227:\t\t\t.sta_add = mt76x02_sta_add,\n 228:\t\t\t.sta_remove = mt76x02_sta_remove,\n 229:\t\t};\n 230:\t\tstruct usb_device *usb_dev = interface_to_usbdev(usb_intf);\n 231:\t\tstruct mt76x02_dev *dev;\n 232:\t\tstruct mt76_dev *mdev;\n 233:\t\tu32 mac_rev;\n 234:\t\tint ret;\n 235:\t\n 236:\t\tmdev = mt76_alloc_device(\u0026usb_intf-\u003edev, sizeof(*dev), \u0026mt76x0u_ops,\n 237:\t\t\t\t\t \u0026drv_ops);\n 238:\t\tif (!mdev)\n 239:\t\t\treturn -ENOMEM;\n 240:\t\n 241:\t\tdev = container_of(mdev, struct mt76x02_dev, mt76);\n 242:\t\tmutex_init(\u0026dev-\u003ephy_mutex);\n 243:\t\n 244:\t\t/* Quirk for Archer T1U */\n 245:\t\tif (id-\u003edriver_info)\n 246:\t\t\tdev-\u003eno_2ghz = true;\n 247:\t\n 248:\t\tusb_reset_device(usb_dev);\n 249:\t\n 250:\t\tusb_set_intfdata(usb_intf, dev);\n 251:\t\n 252:\t\tmt76x02u_init_mcu(mdev);\n 253:\t\tret = mt76u_init(mdev, usb_intf);\n 254:\t\tif (ret)\n 255:\t\t\tgoto err;\n 256:\t\n 257:\t\t/* Disable the HW, otherwise MCU fail to initialize on hot reboot */\n 258:\t\tmt76x0_chip_onoff(dev, false, false);\n 259:\t\n 260:\t\tif (!mt76x02_wait_for_mac(mdev)) {\n 261:\t\t\tret = -ETIMEDOUT;\n 262:\t\t\tgoto err;\n 263:\t\t}\n 264:\t\n 265:\t\tmdev-\u003erev = mt76_rr(dev, MT_ASIC_VERSION);\n 266:\t\tmac_rev = mt76_rr(dev, MT_MAC_CSR0);\n 267:\t\tdev_info(mdev-\u003edev, \"ASIC revision: %08x MAC revision: %08x\\n\",\n 268:\t\t\t mdev-\u003erev, mac_rev);\n 269:\t\tif (!is_mt76x0(dev)) {\n 270:\t\t\tret = -ENODEV;\n 271:\t\t\tgoto err;\n 272:\t\t}\n"
}

25/2 2026/09/25 19:25 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 32113
							output: 35
							thoughts: 151
						

Thoughts:
**Analyzing the mt76x0u_probe Function for USB Operation**

Okay, let's dive into this `mt76x0u_probe` function. My primary concern right now is understanding its interaction with the USB interface, specifically, how it's initializing and communicating with the hardware. The first thing I'm seeing is that it's using USB vendor requests directly to read registers, starting with a call to `mt76x02_wait_for_mac(mdev)` which, in turn, calls `mt76_rr(dev, MT_MAC_CSR0)`. This is a pretty standard initialization sequence, but I need to make sure it's robust. If those register reads fail, or worse, return garbage, the probe bails out with an `-ETIMEDOUT` or `-ENODEV`. That's good error handling, but I want to understand *why* it might fail. I need to know the conditions under which that could happen.

More importantly, how are the USB transmit queues being managed? I need to ascertain whether the USB component is utilizing `mt76_txq_schedule_list`. This is critical for understanding the data flow and potential bottlenecks. Is the USB transmission process integrated with the main driver's queuing mechanisms? 

To answer that I'm going to look for any instances where `tx_worker` is set or where `mt76_txq_schedule` is called. So, I'll run a `grep` across the `drivers/net/wireless/mediatek/mt76/` directory. This should reveal all the relevant code paths. The results from this search will be the foundation for figuring out how the USB functionality integrates with the rest of the driver.



26/2 2026/09/25 19:25 tool grepper
0m Args:
{
  "Expression": "tx_worker",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/dma.c=1195=void mt76_dma_cleanup(struct mt76_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/dma.c-1198-\ndrivers/net/wireless/mediatek/mt76/dma.c:1199:\tmt76_worker_disable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/dma.c-1200-\tnapi_disable(\u0026dev-\u003etx_napi);\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c=669=mt76_alloc_device(struct device *pdev, unsigned int size,\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-705-\tmutex_init(\u0026dev-\u003emcu.mutex);\ndrivers/net/wireless/mediatek/mt76/mac80211.c:706:\tdev-\u003etx_worker.fn = mt76_tx_worker;\ndrivers/net/wireless/mediatek/mt76/mac80211.c-707-\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c=748=int mt76_register_device(struct mt76_dev *dev, bool vht,\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-799-\ndrivers/net/wireless/mediatek/mt76/mac80211.c:800:\tWARN_ON(mt76_worker_setup(hw, \u0026dev-\u003etx_worker, NULL, \"tx\"));\ndrivers/net/wireless/mediatek/mt76/mac80211.c-801-\tset_bit(MT76_STATE_REGISTERED, \u0026phy-\u003estate);\ndrivers/net/wireless/mediatek/mt76/mac80211.c:802:\tsched_set_fifo_low(dev-\u003etx_worker.task);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-803-\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c=823=void mt76_free_device(struct mt76_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mac80211.c-824-{\ndrivers/net/wireless/mediatek/mt76/mac80211.c:825:\tmt76_worker_teardown(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-826-\tif (dev-\u003ewq) {\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c=1048=int __mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1054-\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1055:\tmt76_worker_disable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1056-\tmt76_txq_schedule_pending(phy);\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1078-\tclear_bit(MT76_RESET, \u0026phy-\u003estate);\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1079:\tmt76_worker_enable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1080:\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1081-\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h=925=struct mt76_dev {\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h-969-\ndrivers/net/wireless/mediatek/mt76/mt76.h:970:\tstruct mt76_worker tx_worker;\ndrivers/net/wireless/mediatek/mt76/mt76.h-971-\tstruct napi_struct tx_napi;\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h=1539=void mt76_txq_schedule_pending(struct mt76_phy *phy);\ndrivers/net/wireless/mediatek/mt76/mt76.h:1540:void mt76_tx_worker_run(struct mt76_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt76.h:1541:void mt76_tx_worker(struct mt76_worker *w);\ndrivers/net/wireless/mediatek/mt76/mt76.h-1542-void mt76_release_buffered_frames(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/dma.c=155=static int mt7603_poll_tx(struct napi_struct *napi, int budget)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/dma.c-175-\ndrivers/net/wireless/mediatek/mt76/mt7603/dma.c:176:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7603/dma.c-177-\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c=1446=static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1457-\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1458:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1459-\ttasklet_disable(\u0026dev-\u003emt76.pre_tbtt_tasklet);\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1504-\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1505:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1506-\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c=1887=void mt7603_hw_release(struct mt7603_dev *dev, struct mt7603_sta *msta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1898-\t\t\tieee80211_schedule_txq(mt76_hw(dev), sta-\u003etxq[i]);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c:1899:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7603/mac.c-1900-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c=613=void mt7615_init_device(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-619-\tdev-\u003emt76.phy.priv = \u0026dev-\u003ephy;\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:620:\tdev-\u003emt76.tx_worker.fn = mt7615_tx_worker;\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-621-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c=1552=static void mt7615_mac_tx_free(struct mt7615_dev *dev, void *data, int len)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c-1589-\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c:1590:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c-1591-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=704=static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-733-\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:734:void mt7615_tx_worker(struct mt76_worker *w)\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-735-{\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-736-\tstruct mt7615_dev *dev = container_of(w, struct mt7615_dev,\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:737:\t\t\t\t\t      mt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-738-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-743-\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:744:\tmt76_tx_worker_run(\u0026dev-\u003emt76);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-745-\tmt76_connac_pm_unref(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=497=int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-501-\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:502:void mt7615_tx_worker(struct mt76_worker *w);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-503-void mt7615_tx_token_put(struct mt7615_dev *dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c=72=static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-91-\tnapi_disable(\u0026mdev-\u003etx_napi);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:92:\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-93-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c=139=static int mt7615_pci_resume(struct pci_dev *pdev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-165-\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:166:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-167-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c=201=void mt7615_mac_reset_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-237-\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c:238:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-239-\tmt76_for_each_q_rx(\u0026dev-\u003emt76, i)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-263-\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c:264:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c-265-\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c=123=void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-144-\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c:145:\tmt76_worker_schedule(\u0026phy-\u003edev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-146-}\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c=246=static int mt76x0e_suspend(struct pci_dev *pdev, pm_message_t state)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-251-\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c:252:\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-253-\tfor (i = 0; i \u003c ARRAY_SIZE(mdev-\u003ephy.q_tx); i++)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c=272=static int mt76x0e_resume(struct pci_dev *pdev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-283-\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c:284:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-285-\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c=130=static void mt76x02_process_tx_status_fifo(struct mt76x02_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-138-\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:139:static void mt76x02_tx_worker(struct mt76_worker *w)\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-140-{\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-142-\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:143:\tdev = container_of(w, struct mt76x02_dev, mt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-144-\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c=151=static int mt76x02_poll_tx(struct napi_struct *napi, int budget)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-169-\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:170:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-171-\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c=175=int mt76x02_dma_init(struct mt76x02_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-187-\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:188:\tdev-\u003emt76.tx_worker.fn = mt76x02_tx_worker;\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-189-\ttasklet_setup(\u0026dev-\u003emt76.pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet);\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c=433=static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-442-\ttasklet_disable(\u0026dev-\u003emt76.pre_tbtt_tasklet);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:443:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-444-\tnapi_disable(\u0026dev-\u003emt76.tx_napi);\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-502-\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c:503:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x02_mmio.c-504-\ttasklet_enable(\u0026dev-\u003emt76.pre_tbtt_tasklet);\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c=112=mt76x2e_suspend(struct pci_dev *pdev, pm_message_t state)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-118-\ttasklet_kill(\u0026mdev-\u003epre_tbtt_tasklet);\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c:119:\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-120-\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c=141=mt76x2e_resume(struct pci_dev *pdev)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-152-\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c:153:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-154-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c=848=mt7915_mac_tx_free_done(struct mt7915_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-857-\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:858:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-859-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c=1290=mt7915_mac_restart(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1327-\t/* disable all tx/rx napi */\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1328:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1329-\tmt76_for_each_q_rx(mdev, i) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1418-\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1419:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1420-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c=1482=void mt7915_mac_reset_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1536-\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1537:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1538-\tmt76_for_each_q_rx(\u0026dev-\u003emt76, i)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1580-\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1581:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1582-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=755=int mt7915_mcu_add_tx_ba(struct mt7915_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-762-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:763:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-764-\tif (enable \u0026\u0026 !params-\u003eamsdu)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-768-\t\t\t\t     enable, true);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:769:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-770-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c=170=int mt7921_register_device(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-177-\tdev-\u003emt76.phy.priv = \u0026dev-\u003ephy;\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:178:\tdev-\u003emt76.tx_worker.fn = mt792x_tx_worker;\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-179-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=485=static void mt7921_mac_tx_free(struct mt792x_dev *dev, void *data, int len)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-558-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:559:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-560-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c=468=static int mt7921_pci_suspend(struct device *device)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-503-\tnapi_disable(\u0026mdev-\u003etx_napi);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c:504:\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-505-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c=551=static int mt7921_pci_resume(struct device *device)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-576-\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c:577:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-578-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c=56=int mt7921e_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c-72-\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c:73:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c-74-\tmt76_for_each_q_rx(\u0026dev-\u003emt76, i) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c-126-\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c:127:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c-128-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c=209=static int mt7921s_suspend(struct device *__dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-235-\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c:236:\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-237-\tmt76_worker_disable(\u0026mdev-\u003esdio.status_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-267-restore_worker:\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c:268:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-269-\tmt76_worker_enable(\u0026mdev-\u003esdio.status_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c=285=static int mt7921s_resume(struct device *__dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-298-\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c:299:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-300-\tmt76_worker_enable(\u0026mdev-\u003esdio.txrx_worker);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c=147=int mt7921s_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c-157-\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c:158:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c-159-\tset_bit(MT76_MCU_RESET, \u0026dev-\u003emphy.state);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c-195-\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c:196:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c-197-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c=89=static int mt7921u_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-97-\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c:98:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-99-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-144-\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c:145:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-146-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c=243=int mt7925_register_device(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c-250-\tdev-\u003emt76.phy.priv = \u0026dev-\u003ephy;\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c:251:\tdev-\u003emt76.tx_worker.fn = mt792x_tx_worker;\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c-252-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c=1303=mt7925_mac_tx_free(struct mt792x_dev *dev, void *data, int len)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c-1378-\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c:1379:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c-1380-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c=735=static int mt7925_pci_suspend(struct device *device)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c-772-\tnapi_disable(\u0026mdev-\u003etx_napi);\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c:773:\tmt76_worker_disable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c-774-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c=824=static int _mt7925_pci_resume(struct device *device, bool restore)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c-850-\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c:851:\tmt76_worker_enable(\u0026mdev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c-852-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c=71=int mt7925e_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c-89-\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c:90:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c-91-\tif (irq_map-\u003erx.data_complete_mask)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c-155-\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c:156:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c-157-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c=80=static int mt7925u_mac_reset(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-91-\tmt76_txq_schedule_all(\u0026dev-\u003emphy);\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c:92:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-93-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-144-\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c:145:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-146-\n--\ndrivers/net/wireless/mediatek/mt76/mt792x.h=473=void mt792x_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt792x.h-474-\t\t    u64 timestamp);\ndrivers/net/wireless/mediatek/mt76/mt792x.h:475:void mt792x_tx_worker(struct mt76_worker *w);\ndrivers/net/wireless/mediatek/mt76/mt792x.h-476-void mt792x_roc_timer(struct timer_list *timer);\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c=379=EXPORT_SYMBOL_GPL(mt792x_set_tsf);\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-380-\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c:381:void mt792x_tx_worker(struct mt76_worker *w)\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-382-{\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-383-\tstruct mt792x_dev *dev = container_of(w, struct mt792x_dev,\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c:384:\t\t\t\t\t      mt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-385-\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-393-}\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c:394:EXPORT_SYMBOL_GPL(mt792x_tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-395-\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_usb.c=497=void mt792xu_disconnect(struct usb_interface *usb_intf)\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_usb.c-511-\tcancel_work_sync(\u0026dev-\u003einit_work);\ndrivers/net/wireless/mediatek/mt76/mt792x_usb.c:512:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt792x_usb.c-513-\tmt792xu_reset_work_cleanup(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c=1344=mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-1462-\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c:1463:\tmt76_worker_schedule(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-1464-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c=2286=mt7996_mac_restart(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2312-\t/* disable all tx/rx napi */\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c:2313:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2314-\tmt76_for_each_q_rx(mdev, i) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2418-\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c:2419:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2420-\treturn ret;\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c=2523=void mt7996_mac_reset_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2586-\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c:2587:\tmt76_worker_disable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2588-\tmt76_for_each_q_rx(\u0026dev-\u003emt76, i) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2667-\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c:2668:\tmt76_worker_enable(\u0026dev-\u003emt76.tx_worker);\ndrivers/net/wireless/mediatek/mt76/mt7996/mac.c-2669-\n--\ndrivers/net/wireless/mediatek/mt76/sdio.c=461=static void mt76s_status_worker(struct mt76_worker *w)\n--\ndrivers/net/wireless/mediatek/mt76/sdio.c-487-\tif (resched)\ndrivers/net/wireless/mediatek/mt76/sdio.c:488:\t\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/sdio.c-489-}\n--\ndrivers/net/wireless/mediatek/mt76/testmode.c=270=mt76_testmode_tx_start(struct mt76_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/testmode.c-277-\ttd-\u003etx_pending = td-\u003etx_count;\ndrivers/net/wireless/mediatek/mt76/testmode.c:278:\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/testmode.c-279-}\n--\ndrivers/net/wireless/mediatek/mt76/testmode.c=282=mt76_testmode_tx_stop(struct mt76_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/testmode.c-286-\ndrivers/net/wireless/mediatek/mt76/testmode.c:287:\tmt76_worker_disable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/testmode.c-288-\n--\ndrivers/net/wireless/mediatek/mt76/testmode.c-290-\ndrivers/net/wireless/mediatek/mt76/testmode.c:291:\tmt76_worker_enable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/testmode.c-292-\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=253=void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *skb,\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-280-\t\t\t\t\tieee80211_schedule_txq(hw, sta-\u003etxq[i]);\ndrivers/net/wireless/mediatek/mt76/tx.c:281:\t\t\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-282-\t\t}\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=355=mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-391-\ndrivers/net/wireless/mediatek/mt76/tx.c:392:\tmt76_worker_schedule(\u0026phy-\u003edev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-393-}\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=763=EXPORT_SYMBOL_GPL(mt76_txq_schedule_all);\ndrivers/net/wireless/mediatek/mt76/tx.c-764-\ndrivers/net/wireless/mediatek/mt76/tx.c:765:void mt76_tx_worker_run(struct mt76_dev *dev)\ndrivers/net/wireless/mediatek/mt76/tx.c-766-{\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-788-}\ndrivers/net/wireless/mediatek/mt76/tx.c:789:EXPORT_SYMBOL_GPL(mt76_tx_worker_run);\ndrivers/net/wireless/mediatek/mt76/tx.c-790-\ndrivers/net/wireless/mediatek/mt76/tx.c:791:void mt76_tx_worker(struct mt76_worker *w)\ndrivers/net/wireless/mediatek/mt76/tx.c-792-{\ndrivers/net/wireless/mediatek/mt76/tx.c:793:\tstruct mt76_dev *dev = container_of(w, struct mt76_dev, tx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-794-\ndrivers/net/wireless/mediatek/mt76/tx.c:795:\tmt76_tx_worker_run(dev);\ndrivers/net/wireless/mediatek/mt76/tx.c-796-}\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=821=void mt76_sta_ps_transition(struct mt76_dev *dev, struct mt76_wcid *wcid,\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-829-\t\tset_bit(MT_WCID_FLAG_PS, \u0026wcid-\u003eflags);\ndrivers/net/wireless/mediatek/mt76/tx.c:830:\t\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-831-\t\treturn;\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-843-\t\t\tieee80211_schedule_txq(hw, sta-\u003etxq[i]);\ndrivers/net/wireless/mediatek/mt76/tx.c:844:\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-845-}\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=848=void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-852-\ndrivers/net/wireless/mediatek/mt76/tx.c:853:\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-854-}\n--\ndrivers/net/wireless/mediatek/mt76/tx.c=911=void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)\n--\ndrivers/net/wireless/mediatek/mt76/tx.c-932-\tif (!blocked)\ndrivers/net/wireless/mediatek/mt76/tx.c:933:\t\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/tx.c-934-}\n--\ndrivers/net/wireless/mediatek/mt76/usb.c=798=static void mt76u_status_worker(struct mt76_worker *w)\n--\ndrivers/net/wireless/mediatek/mt76/usb.c-826-\ndrivers/net/wireless/mediatek/mt76/usb.c:827:\t\tmt76_worker_schedule(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/usb.c-828-\t}\n--\ndrivers/net/wireless/mediatek/mt76/usb.c=1035=void mt76u_stop_tx(struct mt76_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/usb.c-1058-\ndrivers/net/wireless/mediatek/mt76/usb.c:1059:\t\tmt76_worker_disable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/usb.c-1060-\n--\ndrivers/net/wireless/mediatek/mt76/usb.c-1075-\ndrivers/net/wireless/mediatek/mt76/usb.c:1076:\t\tmt76_worker_enable(\u0026dev-\u003etx_worker);\ndrivers/net/wireless/mediatek/mt76/usb.c-1077-\t}\n"
}

27/2 2026/09/25 19:25 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 46100
							output: 46
							thoughts: 2689
						

Thoughts:
**Analysis of Code Reachability and Fuzzing Feasibility**

Alright, let's break this down. First, the grep results point directly to `mt7603e`, which is the dedicated driver for `mt76/mt7603`. I see changes in multiple files, specifically: a new flag `MT_WCID_FLAG_TX_HOLD`, debugfs entries, and modifications to DMA, initialization, MAC, and main functions, plus the addition of some new constants and structure members. The real crux is within `tx.c`, where this new flag influences the transmit queue scheduling.

My initial thought is to examine hardware reachability. Can this `mt7603` component run in a standard environment? I'm thinking, does QEMU or GCE offer emulation for a MediaTek MT7603E PCIe card or the MT7628 SoC? No, they don't. Standard virtualization doesn't emulate that specific hardware.

Now, let's consider the "REACHABILITY IS THE PRIMARY GATE" principle. My gut says this isn't going to be fuzzed, given that it states: "Structurally unreachable hardware: * Vendor-specific PCIe switches, SmartNICs, or GPU drivers... requiring physical ASIC/PCIe cards not emulated in standard QEMU"

Specifically, what about those eight lines of code in `drivers/net/wireless/mediatek/mt76/tx.c`? Is that code even executed for reachable devices? Does that changed code in `tx.c` do anything or is it reachable? I need to analyze this. Does Syzkaller even have a MediaTek WiFi device? Can a MediaTek WiFi device be emulated in standard QEMU?

1.  Are there virtual MediaTek WiFi devices in QEMU? No! The only emulated WiFi is mac80211\_hwsim, which is a software-simulated WiFi driver, or dummy\_hcd / raw-gadget for USB gadget emulation.

2.  Can Syzkaller use mac80211\_hwsim? Yes, since it's a virtual driver. But does mac80211\_hwsim use `drivers/net/wireless/mediatek/mt76`? No! mac80211\_hwsim is in drivers/net/wireless/virtual/mac80211\_hwsim.c. It directly registers with mac80211. It has NOTHING to do with mt76.

3.  Can Syzkaller reach mt76 via USB gadget?

Suppose Syzkaller creates a USB device with the VID/PID of an mt76 USB device (e.g., mt76x0u or mt76x2u or mt7921u). Let's see what happens when `mt76x0u` probes.

Even if Syzkaller emulated USB packets to satisfy all register reads during probe: Even then, none of the USB drivers ever set `MT_WCID_FLAG_TX_HOLD`! `MT_WCID_FLAG_TX_HOLD` is only used by mt7603!

The two checks added in `tx.c` are:

```c
/* The previous frame may have filled the hardware. */
if (test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
break;
```

and

```c
/* The driver schedules the queues again when it lifts the hold. */
if (test_bit(MT_WCID_FLAG_TX_HOLD, &wcid->flags))
continue;
```

For ANY device other than mt7603, `MT_WCID_FLAG_TX_HOLD` is 0 (never set). And `mt7603` is ONLY a PCI / SoC driver. There is NO USB driver for MT7603! It's a PCIe ASIC device (PCI ID 0x14c3:0x7603) or MT7628 SoC. And requires physical hardware (the MediaTek MT7603E PCIe card or MT7628 MIPS SoC).

I have grepped the entire kernel and only `drivers/net/wireless/mediatek/mt76/mt7603/` sets `MT_WCID_FLAG_TX_HOLD`.

`mt7603_hw_pending_inc()` sets it.

`mt7603_hw_release()` clears it.

`mt7603_hw_cap_check()` checks and resets it.

`mt7603_hw_cap_read()` displays it in debugfs.

And


28/2 2026/09/25 19:25 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7603/Makefile",
  "FirstLine": 1,
  "LineCount": 20
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: BSD-3-Clause-Clear\n   2:\tobj-$(CONFIG_MT7603E) += mt7603e.o\n   3:\t\n   4:\tmt7603e-y := \\\n   5:\t\tpci.o soc.o main.o init.o mcu.o \\\n   6:\t\tcore.o dma.o mac.o eeprom.o \\\n   7:\t\tbeacon.o debugfs.o\n"
}

29/2 2026/09/25 19:25 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 49994
							output: 178
							thoughts: 441
						

Thoughts:
**My Assessment: Not Worth Fuzzing**

Okay, so here's the breakdown. I've analyzed the recent changes and it's pretty straightforward. The modified code, specifically in `drivers/net/wireless/mediatek/mt76/mt7603/` and shared `mt76` files like `tx.c` and `mt76.h`, is directly tied to the MediaTek MT7603E wireless driver (`mt7603e.ko`). This driver is built *only* when `CONFIG_MT7603E` is enabled. It's purpose is to handle the PCIe interface (`pci.o`) and SoC (`soc.o`) support for the physical MediaTek MT7603E PCIe NIC and MT7628 SoC.

The key is that this driver, and the hardware it supports, is *not* emulated by standard virtualization environments like QEMU or Google Compute Engine. These environments simply don't have the hardware profile to work with the `mt7603e`.

The modification centers around the `MT_WCID_FLAG_TX_HOLD` flag. I can see from the code review that this flag is exclusively set and managed within the `mt7603e` driver. The changes in `tx.c` are simply testing this flag. This means that *all* of the code modifications are fundamentally unreachable in any standard virtual fuzzing setup. I'm confident in saying that the changes are part of a TX hold / hardware frame cap mechanism, and that the code is functionally limited to vendor-specific hardware.

Therefore, because the relevant hardware isn't present in the fuzzing environments and the code only acts upon a flag set by the hardware's driver, the modifications are unreachable and not worth the effort. The `WorthFuzzing` flag is false, there are no special `EnableConfigs` or `FocusSymbols` needed, and I can be concise. I'm going to call `set-results`.



30/2 2026/09/25 19:25 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a TX hold mechanism to limit the number of frames queued in hardware for the MediaTek MT7603 wireless driver. The changes are located in drivers/net/wireless/mediatek/mt76/mt7603/ and the shared mt76 core (where MT_WCID_FLAG_TX_HOLD is checked in tx.c, but only ever set by mt7603). The MT7603E driver requires physical MediaTek MT7603E PCIe hardware or an MT7628 SoC, neither of which is emulated in standard virtualized environments (QEMU/GCE). The code is therefore structurally unreachable for fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch introduces a TX hold mechanism to limit the number of frames queued in hardware for the MediaTek MT7603 wireless driver. The changes are located in drivers/net/wireless/mediatek/mt76/mt7603/ and the shared mt76 core (where MT_WCID_FLAG_TX_HOLD is checked in tx.c, but only ever set by mt7603). The MT7603E driver requires physical MediaTek MT7603E PCIe hardware or an MT7628 SoC, neither of which is emulated in standard virtualized environments (QEMU/GCE). The code is therefore structurally unreachable for fuzzing.",
  "WorthFuzzing": false
}

31/1 2026/09/25 19:25 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

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)