| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/10/26 23:55 | flow | patch-triage |
6mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch adds SDIO RX enhance mode support and addresses MT7663 SDIO quirks in the MediaTek mt76 wireless driver. The modifications are located in the SDIO subsystem (drivers/net/wireless/mediatek/mt76/sdio.c, sdio_txrx.c, and mt7615/sdio.c), SDIO-specific capability checks in mt7615/init.c, and a semaphore retry loop in mt7615/mcu.c. SDIO devices require physical SDIO hardware and are structurally unreachable in standard virtualized environments (QEMU/GCE), as QEMU does not emulate SDIO cards and Linux lacks a software SDIO gadget framework. The shared MCU helper (mt7615_load_patch) is only called on physical PCIe hardware (not emulated in QEMU) or on USB (where probing aborts at firmware_request_nowarn due to missing proprietary firmware blobs before reaching the modified loop). Therefore, all modified code is structurally unreachable for fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/10/26 23:55 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 722ea04f923f198fe8ec787e2e9d8421004f95ea\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Oct 26 23:54:59 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 9e851dea71d933..9c637ebddb5295 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt76.h\n+++ b/drivers/net/wireless/mediatek/mt76/mt76.h\n@@ -700,6 +700,16 @@ struct mt76_sdio {\n \tstruct sdio_func *func;\n \tvoid *intr_data;\n \tu8 hw_ver;\n+\n+\t/*\n+\t * RX enhance mode (CONNAC1): the chip appends the next interrupt\n+\t * status (intr_size bytes, after 4 bytes of zero padding) to every\n+\t * RX data read, saving a separate status read while frames stream.\n+\t */\n+\tbool rx_enhance;\n+\tbool intr_pending;\n+\tu16 intr_size;\n+\tvoid *intr_next;\n \twait_queue_head_t wait;\n \n \tint pse_mcu_quota_max;\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c\nindex 665b0f1e939f1a..e6685c51fa6e52 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c\n@@ -200,6 +200,12 @@ mt7615_check_offload_capability(struct mt7615_dev *dev)\n \t\t\t\t WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |\n \t\t\t\t NL80211_FEATURE_P2P_GO_CTWIN |\n \t\t\t\t NL80211_FEATURE_P2P_GO_OPPPS;\n+\t\t/*\n+\t\t * On SDIO the firmware ends a hw scan with a random source\n+\t\t * address at once, with no results.\n+\t\t */\n+\t\tif (mt76_is_sdio(\u0026dev-\u003emt76))\n+\t\t\twiphy-\u003efeatures \u0026= ~NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;\n \t} else {\n \t\tdev-\u003eops-\u003ehw_scan = NULL;\n \t\tdev-\u003eops-\u003ecancel_hw_scan = NULL;\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c\nindex aab4303fef6529..9c9c4f377d5906 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c\n@@ -1241,7 +1241,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)\n {\n \tconst struct mt7615_patch_hdr *hdr;\n \tconst struct firmware *fw = NULL;\n-\tint len, ret, sem;\n+\tint i, len, ret, sem;\n \n \tret = firmware_request_nowarn(\u0026fw, name, dev-\u003emt76.dev);\n \tif (ret)\n@@ -1253,7 +1253,17 @@ static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)\n \t\tgoto release_fw;\n \t}\n \n-\tsem = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, true);\n+\t/*\n+\t * On MT7663 the Bluetooth function shares the ROM patch, and the\n+\t * semaphore is refused while it downloads the patch: wait for it.\n+\t */\n+\tfor (i = 0; i \u003c 50; i++) {\n+\t\tsem = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, true);\n+\t\tif (sem != PATCH_NOT_DL_SEM_FAIL)\n+\t\t\tbreak;\n+\t\tmsleep(100);\n+\t}\n+\n \tswitch (sem) {\n \tcase PATCH_IS_DL:\n \t\tgoto release_fw;\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c\nindex 46188951ad194f..f744240ebd34ca 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c\n@@ -56,12 +56,19 @@ static int mt7663s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)\n \tstruct mt7663s_intr *irq_data = sdio-\u003eintr_data;\n \tint i, err;\n \n-\tsdio_claim_host(sdio-\u003efunc);\n-\terr = sdio_readsb(sdio-\u003efunc, irq_data, MCR_WHISR, sizeof(*irq_data));\n-\tsdio_release_host(sdio-\u003efunc);\n-\n-\tif (err)\n-\t\treturn err;\n+\tif (sdio-\u003eintr_pending) {\n+\t\t/* appended to the last RX read (RX enhance mode) */\n+\t\tmemcpy(irq_data, sdio-\u003eintr_next, sizeof(*irq_data));\n+\t\tsdio-\u003eintr_pending = false;\n+\t} else {\n+\t\tsdio_claim_host(sdio-\u003efunc);\n+\t\terr = sdio_readsb(sdio-\u003efunc, irq_data, MCR_WHISR,\n+\t\t\t\t sizeof(*irq_data));\n+\t\tsdio_release_host(sdio-\u003efunc);\n+\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n \n \tintr-\u003eisr = irq_data-\u003eisr;\n \tintr-\u003erec_mb = irq_data-\u003erec_mb;\n@@ -124,6 +131,15 @@ static int mt7663s_probe(struct sdio_func *func,\n \tif (ret \u003c 0)\n \t\tgoto error;\n \n+\tmdev-\u003esdio.intr_size = sizeof(struct mt7663s_intr);\n+\tmdev-\u003esdio.intr_next = devm_kmalloc(mdev-\u003edev, mdev-\u003esdio.intr_size,\n+\t\t\t\t\t GFP_KERNEL);\n+\tif (!mdev-\u003esdio.intr_next) {\n+\t\tret = -ENOMEM;\n+\t\tgoto error;\n+\t}\n+\tmdev-\u003esdio.rx_enhance = true;\n+\n \tret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);\n \tif (ret)\n \t\tgoto error;\ndiff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c\nindex ba5f123f7e39dc..95af0a90546c56 100644\n--- a/drivers/net/wireless/mediatek/mt76/sdio.c\n+++ b/drivers/net/wireless/mediatek/mt76/sdio.c\n@@ -269,6 +269,9 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)\n \tcase MT76_CONNAC_SDIO:\n \t\t/* set WHISR as read clear and Rx aggregation number as 16 */\n \t\tctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);\n+\t\tif (dev-\u003esdio.rx_enhance)\n+\t\t\tctrl |= RX_ENHANCE_MODE;\n+\t\tdev-\u003esdio.intr_pending = false;\n \t\tbreak;\n \tdefault:\n \t\tctrl = sdio_readl(func, MCR_WHCR, \u0026ret);\ndiff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c\nindex 3f314e8e1e69f9..f15746a139912b 100644\n--- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c\n+++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c\n@@ -9,6 +9,7 @@\n #include \u003clinux/kernel.h\u003e\n #include \u003clinux/iopoll.h\u003e\n #include \u003clinux/module.h\u003e\n+#include \u003clinux/unaligned.h\u003e\n \n #include \u003clinux/mmc/host.h\u003e\n #include \u003clinux/mmc/sdio_ids.h\u003e\n@@ -87,7 +88,7 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,\n {\n \tstruct mt76_queue *q = \u0026dev-\u003eq_rx[qid];\n \tstruct mt76_sdio *sdio = \u0026dev-\u003esdio;\n-\tint len = 0, err, i;\n+\tint len = 0, data_len, err, i;\n \tstruct page *page;\n \tu8 *buf, *end;\n \n@@ -97,6 +98,10 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,\n \tif (!len)\n \t\treturn 0;\n \n+\tdata_len = len;\n+\tif (sdio-\u003erx_enhance)\n+\t\tlen += 4 + sdio-\u003eintr_size;\n+\n \tif (len \u003e sdio-\u003efunc-\u003ecur_blksize)\n \t\tlen = roundup(len, sdio-\u003efunc-\u003ecur_blksize);\n \n@@ -117,7 +122,13 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,\n \t\treturn err;\n \t}\n \n-\tend = buf + len;\n+\t/* The next interrupt status follows the frames and a zero pad */\n+\tif (sdio-\u003erx_enhance \u0026\u0026 !get_unaligned((u32 *)(buf + data_len))) {\n+\t\tmemcpy(sdio-\u003eintr_next, buf + data_len + 4, sdio-\u003eintr_size);\n+\t\tsdio-\u003eintr_pending = true;\n+\t}\n+\n+\tend = buf + data_len;\n \ti = 0;\n \n \twhile (i \u003c intr-\u003erx.num[qid] \u0026\u0026 buf \u003c end) {\n@@ -319,7 +330,7 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)\n \n \t/* disable interrupt */\n \tsdio_claim_host(sdio-\u003efunc);\n-\tsdio_writel(sdio-\u003efunc, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);\n+\tsdio_writeb(sdio-\u003efunc, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);\n \tsdio_release_host(sdio-\u003efunc);\n \n \tdo {\n@@ -351,7 +362,7 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)\n \n \t/* enable interrupt */\n \tsdio_claim_host(sdio-\u003efunc);\n-\tsdio_writel(sdio-\u003efunc, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);\n+\tsdio_writeb(sdio-\u003efunc, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);\n \tsdio_release_host(sdio-\u003efunc);\n }\n EXPORT_SYMBOL_GPL(mt76s_txrx_worker);\n@@ -365,7 +376,7 @@ void mt76s_sdio_irq(struct sdio_func *func)\n \t test_bit(MT76_MCU_RESET, \u0026dev-\u003ephy.state))\n \t\treturn;\n \n-\tsdio_writel(sdio-\u003efunc, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);\n+\tsdio_writeb(sdio-\u003efunc, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);\n \tmt76_worker_schedule(\u0026sdio-\u003etxrx_worker);\n }\n EXPORT_SYMBOL_GPL(mt76s_sdio_irq);\n"
} |
| 2/1 | 2026/10/26 23:55 | agent | patch-evaluator |
6mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds SDIO RX enhance mode support and addresses MT7663 SDIO quirks in the MediaTek mt76 wireless driver. The modifications are located in the SDIO subsystem (drivers/net/wireless/mediatek/mt76/sdio.c, sdio_txrx.c, and mt7615/sdio.c), SDIO-specific capability checks in mt7615/init.c, and a semaphore retry loop in mt7615/mcu.c. SDIO devices require physical SDIO hardware and are structurally unreachable in standard virtualized environments (QEMU/GCE), as QEMU does not emulate SDIO cards and Linux lacks a software SDIO gadget framework. The shared MCU helper (mt7615_load_patch) is only called on physical PCIe hardware (not emulated in QEMU) or on USB (where probing aborts at firmware_request_nowarn due to missing proprietary firmware blobs before reaching the modified loop). Therefore, all modified code is 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 722ea04f923f198fe8ec787e2e9d8421004f95ea
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Oct 26 23:54:59 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 9e851dea71d933..9c637ebddb5295 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -700,6 +700,16 @@ struct mt76_sdio {
struct sdio_func *func;
void *intr_data;
u8 hw_ver;
+
+ /*
+ * RX enhance mode (CONNAC1): the chip appends the next interrupt
+ * status (intr_size bytes, after 4 bytes of zero padding) to every
+ * RX data read, saving a separate status read while frames stream.
+ */
+ bool rx_enhance;
+ bool intr_pending;
+ u16 intr_size;
+ void *intr_next;
wait_queue_head_t wait;
int pse_mcu_quota_max;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index 665b0f1e939f1a..e6685c51fa6e52 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -200,6 +200,12 @@ mt7615_check_offload_capability(struct mt7615_dev *dev)
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
NL80211_FEATURE_P2P_GO_CTWIN |
NL80211_FEATURE_P2P_GO_OPPPS;
+ /*
+ * On SDIO the firmware ends a hw scan with a random source
+ * address at once, with no results.
+ */
+ if (mt76_is_sdio(&dev->mt76))
+ wiphy->features &= ~NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
} else {
dev->ops->hw_scan = NULL;
dev->ops->cancel_hw_scan = NULL;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index aab4303fef6529..9c9c4f377d5906 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -1241,7 +1241,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)
{
const struct mt7615_patch_hdr *hdr;
const struct firmware *fw = NULL;
- int len, ret, sem;
+ int i, len, ret, sem;
ret = firmware_request_nowarn(&fw, name, dev->mt76.dev);
if (ret)
@@ -1253,7 +1253,17 @@ static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)
goto release_fw;
}
- sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);
+ /*
+ * On MT7663 the Bluetooth function shares the ROM patch, and the
+ * semaphore is refused while it downloads the patch: wait for it.
+ */
+ for (i = 0; i < 50; i++) {
+ sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);
+ if (sem != PATCH_NOT_DL_SEM_FAIL)
+ break;
+ msleep(100);
+ }
+
switch (sem) {
case PATCH_IS_DL:
goto release_fw;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
index 46188951ad194f..f744240ebd34ca 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -56,12 +56,19 @@ static int mt7663s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)
struct mt7663s_intr *irq_data = sdio->intr_data;
int i, err;
- sdio_claim_host(sdio->func);
- err = sdio_readsb(sdio->func, irq_data, MCR_WHISR, sizeof(*irq_data));
- sdio_release_host(sdio->func);
-
- if (err)
- return err;
+ if (sdio->intr_pending) {
+ /* appended to the last RX read (RX enhance mode) */
+ memcpy(irq_data, sdio->intr_next, sizeof(*irq_data));
+ sdio->intr_pending = false;
+ } else {
+ sdio_claim_host(sdio->func);
+ err = sdio_readsb(sdio->func, irq_data, MCR_WHISR,
+ sizeof(*irq_data));
+ sdio_release_host(sdio->func);
+
+ if (err)
+ return err;
+ }
intr->isr = irq_data->isr;
intr->rec_mb = irq_data->rec_mb;
@@ -124,6 +131,15 @@ static int mt7663s_probe(struct sdio_func *func,
if (ret < 0)
goto error;
+ mdev->sdio.intr_size = sizeof(struct mt7663s_intr);
+ mdev->sdio.intr_next = devm_kmalloc(mdev->dev, mdev->sdio.intr_size,
+ GFP_KERNEL);
+ if (!mdev->sdio.intr_next) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ mdev->sdio.rx_enhance = true;
+
ret = mt76s_hw_init(mdev, func, MT76_CONNAC_SDIO);
if (ret)
goto error;
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
index ba5f123f7e39dc..95af0a90546c56 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -269,6 +269,9 @@ int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, int hw_ver)
case MT76_CONNAC_SDIO:
/* set WHISR as read clear and Rx aggregation number as 16 */
ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
+ if (dev->sdio.rx_enhance)
+ ctrl |= RX_ENHANCE_MODE;
+ dev->sdio.intr_pending = false;
break;
default:
ctrl = sdio_readl(func, MCR_WHCR, &ret);
diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
index 3f314e8e1e69f9..f15746a139912b 100644
--- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/iopoll.h>
#include <linux/module.h>
+#include <linux/unaligned.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_ids.h>
@@ -87,7 +88,7 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
{
struct mt76_queue *q = &dev->q_rx[qid];
struct mt76_sdio *sdio = &dev->sdio;
- int len = 0, err, i;
+ int len = 0, data_len, err, i;
struct page *page;
u8 *buf, *end;
@@ -97,6 +98,10 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
if (!len)
return 0;
+ data_len = len;
+ if (sdio->rx_enhance)
+ len += 4 + sdio->intr_size;
+
if (len > sdio->func->cur_blksize)
len = roundup(len, sdio->func->cur_blksize);
@@ -117,7 +122,13 @@ mt76s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
return err;
}
- end = buf + len;
+ /* The next interrupt status follows the frames and a zero pad */
+ if (sdio->rx_enhance && !get_unaligned((u32 *)(buf + data_len))) {
+ memcpy(sdio->intr_next, buf + data_len + 4, sdio->intr_size);
+ sdio->intr_pending = true;
+ }
+
+ end = buf + data_len;
i = 0;
while (i < intr->rx.num[qid] && buf < end) {
@@ -319,7 +330,7 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)
/* disable interrupt */
sdio_claim_host(sdio->func);
- sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
+ sdio_writeb(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
sdio_release_host(sdio->func);
do {
@@ -351,7 +362,7 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)
/* enable interrupt */
sdio_claim_host(sdio->func);
- sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
+ sdio_writeb(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
sdio_release_host(sdio->func);
}
EXPORT_SYMBOL_GPL(mt76s_txrx_worker);
@@ -365,7 +376,7 @@ void mt76s_sdio_irq(struct sdio_func *func)
test_bit(MT76_MCU_RESET, &dev->phy.state))
return;
- sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
+ sdio_writeb(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
mt76_worker_schedule(&sdio->txrx_worker);
}
EXPORT_SYMBOL_GPL(mt76s_sdio_irq);
|
| 3/2 | 2026/10/26 23:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 6189 output: 39 thoughts: 744 Thoughts: **Assessing Reachability for Fuzzing: MediaTek MT76 SDIO Driver** Okay, so this patch touches a bunch of files related to the MediaTek mt76 wireless driver, specifically the SDIO variant. I need to figure out if this code is even *reachable* for fuzzing, given my understanding of the environment. The files affected are: `mt76.h`, `mt7615/init.c`, `mt7615/mcu.c`, `mt7615/sdio.c`, `mt76/sdio.c`, and `sdio_txrx.c`. First things first: this is SDIO, and that's the MT7663s, so SDIO is the bus. The prompt specifically highlights the "reachability" gate. SDIO devices generally require physical SDIO/MMC hardware, or at least a good SDIO card emulation. Can I reliably emulate an MT76 SDIO device, or the mt7663s, within a standard QEMU setup, or even with syzkaller? That's the core question. The prompt instructions are pretty clear on this: Fuzzing is only valid for code that *executes* in a standard virtualized environment (QEMU, GCE, virtual buses like virtio, USB gadget, netlink, etc.). Section 2's negative criteria are very relevant here. Vendor-specific hardware requiring specific physical cards, like PCIe switches or GPU drivers, is a no-go for fuzzing if not emulated. So, *can* I emulate MT76 SDIO in QEMU? No, I'm pretty sure that's not something QEMU does out of the box. I need to confirm that. Can I reach the MT76 SDIO through mac80211 hwsim or USB or something? I need to check how it connects to the system. Let me look closely at the patch. In `mt76.h`, there's a `struct mt76_sdio` with members related to receive enhancement, interrupt handling. In `mt7615/init.c`, I see `mt7615_check_offload_capability` which has `NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR` potentially being cleared if this is SDIO device. Does MT7615 have a PCIe or USB variant? Let me grep to make sure. If it has PCIe or USB variants, then the reachability situation becomes different. If there's no way to reach the SDIO version in a virtualized context, this code isn't viable for fuzzing based on the prompt's instructions. |
| 4/2 | 2026/10/26 23:55 | tool | grepper |
0mArgs:{
"Expression": "mt7615",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/"
]
}Results: {
"Output": "\nFull output is too long, showing 200 out of 4469 lines.\nUse more precise expression or PathPrefixes if possible.\n\nNumber of matching lines per file (30 files in total):\ndrivers/net/wireless/mediatek/mt76/Kconfig:1\ndrivers/net/wireless/mediatek/mt76/Makefile:1\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:6\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:118\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:24\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:26\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:7\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:103\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c:193\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.h:6\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:305\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:246\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.h:9\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c:44\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:159\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615_trace.h:5\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:25\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c:28\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c:38\ndrivers/net/wireless/mediatek/mt76/mt7615/regs.h:1\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:21\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c:12\ndrivers/net/wireless/mediatek/mt76/mt7615/soc.c:5\ndrivers/net/wireless/mediatek/mt76/mt7615/testmode.c:44\ndrivers/net/wireless/mediatek/mt76/mt7615/trace.c:1\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:24\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c:8\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c:29\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h:2\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h:1\n\ndrivers/net/wireless/mediatek/mt76/Kconfig=47=source \"drivers/net/wireless/mediatek/mt76/mt7603/Kconfig\"\ndrivers/net/wireless/mediatek/mt76/Kconfig:48:source \"drivers/net/wireless/mediatek/mt76/mt7615/Kconfig\"\ndrivers/net/wireless/mediatek/mt76/Kconfig-49-source \"drivers/net/wireless/mediatek/mt76/mt7915/Kconfig\"\n--\ndrivers/net/wireless/mediatek/mt76/Makefile=47=obj-$(CONFIG_MT7603E) += mt7603/\ndrivers/net/wireless/mediatek/mt76/Makefile:48:obj-$(CONFIG_MT7615_COMMON) += mt7615/\ndrivers/net/wireless/mediatek/mt76/Makefile-49-obj-$(CONFIG_MT7915E) += mt7915/\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-2-\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:3:obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:4:obj-$(CONFIG_MT7615E) += mt7615e.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-5-obj-$(CONFIG_MT7663_USB_SDIO_COMMON) += mt7663-usb-sdio-common.o\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile=9=CFLAGS_trace.o := -I$(src)\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-10-\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:11:mt7615-common-y := main.o init.o mcu.o eeprom.o mac.o \\\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-12-\t\t debugfs.o trace.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:13:mt7615-common-$(CONFIG_NL80211_TESTMODE) += testmode.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-14-\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:15:mt7615e-y := pci.o pci_init.o dma.o pci_mac.o mmio.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:16:mt7615e-$(CONFIG_MT7622_WMAC) += soc.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-17-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-2-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:3:#include \"mt7615.h\"\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-4-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=5=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:6:mt7615_reg_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-7-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:8:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-9-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:10:\tmt7615_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-11-\tmt76_wr(dev, dev-\u003emt76.debugfs_reg, val);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:12:\tmt7615_mutex_release(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-13-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=17=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:18:mt7615_reg_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-19-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:20:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-21-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:22:\tmt7615_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-23-\t*val = mt76_rr(dev, dev-\u003emt76.debugfs_reg);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:24:\tmt7615_mutex_release(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-25-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-28-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:29:DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7615_reg_get, mt7615_reg_set,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-30-\t\t\t \"0x%08llx\\n\");\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=32=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:33:mt7615_radar_pattern_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-34-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:35:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-36-\tint err;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-37-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:38:\tif (!mt7615_wait_for_mcu_init(dev))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-39-\t\treturn 0;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-40-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:41:\tmt7615_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:42:\terr = mt7615_mcu_rdd_send_pattern(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:43:\tmt7615_mutex_release(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-44-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=48=DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:49:\t\t\t mt7615_radar_pattern_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-50-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:51:static int mt7615_config(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-52-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:53:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-54-\tint ret;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-55-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:56:\tmt7615_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-57-\tret = mt76_connac_mcu_chip_config(\u0026dev-\u003emt76, \"assert\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:58:\tmt7615_mutex_release(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-59-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-62-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:63:DEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7615_config, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-64-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=65=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:66:mt7615_scs_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-67-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:68:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:69:\tstruct mt7615_phy *ext_phy;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-70-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:71:\tif (!mt7615_wait_for_mcu_init(dev))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-72-\t\treturn 0;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-73-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:74:\tmt7615_mac_set_scs(\u0026dev-\u003ephy, val);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:75:\text_phy = mt7615_ext_phy(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-76-\tif (ext_phy)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:77:\t\tmt7615_mac_set_scs(ext_phy, val);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-78-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=82=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:83:mt7615_scs_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-84-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:85:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-86-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-91-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:92:DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:93:\t\t\t mt7615_scs_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-94-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=95=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:96:mt7615_pm_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-97-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:98:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-99-\tstruct mt76_connac_pm *pm = \u0026dev-\u003epm;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-101-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:102:\tif (!mt7615_wait_for_mcu_init(dev))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-103-\t\treturn 0;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-104-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:105:\tif (!mt7615_firmware_offload(dev) || mt76_is_usb(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-106-\t\treturn -EOPNOTSUPP;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=136=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:137:mt7615_pm_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-138-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:139:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-140-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-145-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:146:DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-147-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=148=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:149:mt7615_pm_stats(struct seq_file *s, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-150-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:151:\tstruct mt7615_dev *dev = dev_get_drvdata(s-\u003eprivate);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-152-\tstruct mt76_connac_pm *pm = \u0026dev-\u003epm;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=168=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:169:mt7615_pm_idle_timeout_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-170-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:171:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-172-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=178=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:179:mt7615_pm_idle_timeout_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-180-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:181:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-182-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-187-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:188:DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:189:\t\t\t mt7615_pm_idle_timeout_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-190-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=191=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:192:mt7615_dbdc_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-193-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:194:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-195-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:196:\tif (!mt7615_wait_for_mcu_init(dev))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-197-\t\treturn 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-199-\tif (val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:200:\t\tmt7615_register_ext_phy(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-201-\telse\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:202:\t\tmt7615_unregister_ext_phy(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-203-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=207=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:208:mt7615_dbdc_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-209-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:210:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-211-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:212:\t*val = !!mt7615_ext_phy(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-213-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-216-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:217:DEFINE_DEBUGFS_ATTRIBUTE(fops_dbdc, mt7615_dbdc_get,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:218:\t\t\t mt7615_dbdc_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-219-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=220=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:221:mt7615_fw_debug_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-222-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:223:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-224-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:225:\tif (!mt7615_wait_for_mcu_init(dev))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-226-\t\treturn 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-229-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:230:\tmt7615_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:231:\tmt7615_mcu_fw_log_2_host(dev, dev-\u003efw_debug ? 2 : 0);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:232:\tmt7615_mutex_release(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-233-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=237=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:238:mt7615_fw_debug_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-239-{\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:240:\tstruct mt7615_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-241-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-246-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:247:DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7615_fw_debug_get,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:248:\t\t\t mt7615_fw_debug_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-249-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=250=static int\n\n"
} |
| 5/2 | 2026/10/26 23:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15209 output: 47 thoughts: 28 Thoughts: Okay, here's my interpretation of what I'm looking at, rendered in the first person, assuming a level of expertise: **Diving into the MT7615 Kconfig** Alright, let's get down to brass tacks. I need to understand the configuration options for the mt7615 driver within the broader Mediatek wireless stack. I'm going to carefully examine the Kconfig file located within the driver directory. I'm especially interested in the configurable features and dependencies. This Kconfig file will be the key to understanding how the kernel configures features and modules specific to the MT7615 chipset. I'm assuming it defines the different driver modules. I want to figure out all the knobs and levers for the MT7615 driver. What modules are available? What options control things like security, performance, power saving? I'll probably be looking for default settings, dependencies on other kernel components, and any conditional build logic based on hardware revisions or feature sets. This is going to be about understanding how I can best configure this driver for my needs. |
| 6/2 | 2026/10/26 23:55 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/Kconfig",
"FirstLine": 1,
"LineCount": 50
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: BSD-3-Clause-Clear\n 2:\t\n 3:\tconfig MT7615_COMMON\n 4:\t\ttristate\n 5:\t\tselect WANT_DEV_COREDUMP\n 6:\t\tselect MT76_CONNAC_LIB\n 7:\t\n 8:\tconfig MT7615E\n 9:\t\ttristate \"MediaTek MT7615E and MT7663E (PCIe) support\"\n 10:\t\tselect MT7615_COMMON\n 11:\t\tdepends on MAC80211\n 12:\t\tdepends on PCI\n 13:\t\thelp\n 14:\t\t This adds support for MT7615-based PCIe wireless devices,\n 15:\t\t which support concurrent dual-band operation at both 5GHz\n 16:\t\t and 2.4GHz, IEEE 802.11ac 4x4:4SS 1733Mbps PHY rate, wave2\n 17:\t\t MU-MIMO up to 4 users/group and 160MHz channels.\n 18:\t\n 19:\t\t To compile this driver as a module, choose M here.\n 20:\t\n 21:\tconfig MT7622_WMAC\n 22:\t\tbool \"MT7622 (SoC) WMAC support\"\n 23:\t\tdepends on MT7615E\n 24:\t\tdepends on ARCH_MEDIATEK || COMPILE_TEST\n 25:\t\tselect REGMAP\n 26:\t\tdefault y\n 27:\t\thelp\n 28:\t\t This adds support for the built-in WMAC on MT7622 SoC devices\n 29:\t\t which has the same feature set as a MT7615, but limited to\n 30:\t\t 2.4 GHz only.\n 31:\t\n 32:\tconfig MT7663_USB_SDIO_COMMON\n 33:\t\ttristate\n 34:\t\tselect MT7615_COMMON\n 35:\t\n 36:\tconfig MT7663U\n 37:\t\ttristate \"MediaTek MT7663U (USB) support\"\n 38:\t\tselect MT76_USB\n 39:\t\tselect MT7663_USB_SDIO_COMMON\n 40:\t\tdepends on MAC80211\n 41:\t\tdepends on USB\n 42:\t\thelp\n 43:\t\t This adds support for MT7663U 802.11ac 2x2:2 wireless devices.\n 44:\t\n 45:\t\t To compile this driver as a module, choose M here.\n 46:\t\n 47:\tconfig MT7663S\n 48:\t\ttristate \"MediaTek MT7663S (SDIO) support\"\n 49:\t\tselect MT76_SDIO\n 50:\t\tselect MT7663_USB_SDIO_COMMON\n"
} |
| 7/2 | 2026/10/26 23:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 16269 output: 49 thoughts: 1243 Thoughts: **Analyzing the Potential Fuzzing Surface** Okay, so I've spotted `MT7663U` and `MT7663S` in the config. Immediately, the question in my mind is whether the `MT7663U` (USB) configuration leverages USB gadget or Raw-Gadget fuzzing. I know that syzkaller provides robust fuzzing for USB drivers, specifically through `raw-gadget` and `dummy_hcd`. The question is, is this applicable here? Yes, syzkaller heavily fuzzed USB drivers with raw-gadget / dummy_hcd! The core of my analysis now revolves around understanding where the code modified in this patch is used. Is it solely for SDIO or does it touch USB as well? To get a definitive answer, I'm going to carefully examine each modified file and function. Starting with `drivers/net/wireless/mediatek/mt76/mt76.h`, I see `struct mt76_sdio` with members related to RX enhance mode and interrupt status handling. This is specific to SDIO, no question. Moving to `drivers/net/wireless/mediatek/mt76/mt7615/init.c`, I focus on the `mt7615_check_offload_capability` function. It looks like a check is added to disable the scanning of a random MAC address when using SDIO. The key here is to determine *where* `mt7615_check_offload_capability` is called, to understand the context. Looking into `drivers/net/wireless/mediatek/mt76/mt7615/mcu.c`, I find `mt7615_load_patch`. It includes a semaphore handling to wait for a potential Bluetooth function. This is more of an interesting area because firmware loading can sometimes reveal vulnerabilities. I'm now keen to find out whether `mt7615_load_patch` is invoked by the `MT7663U` (USB) setup or the `MT7615E` (PCIe) variant. The remaining files, `drivers/net/wireless/mediatek/mt76/mt7615/sdio.c`, `drivers/net/wireless/mediatek/mt76/sdio.c`, and `drivers/net/wireless/mediatek/mt76/sdio_txrx.c`, all contain functions like `mt7663s_parse_intr`, `mt7663s_probe`, `mt76s_hw_init`, `mt76s_rx_run_queue`, and `mt76s_txrx_worker`. These are definitively SDIO specific, as indicated by the presence of `sdio` in the file names and the explicit `mt76-sdio.ko` module. The critical next step is to nail down the callers of `mt7615_load_patch`. I'll use `grepper` (or a similar tool) to search for call sites. This is where the patch might open up interesting fuzzing targets, especially if it's involved in USB operations. |
| 8/2 | 2026/10/26 23:55 | tool | grepper |
0mArgs:{
"Expression": "mt7615_load_patch",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1238=EXPORT_SYMBOL_GPL(mt7615_mcu_restart);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1239-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1240:static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1241-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1456=static int mt7615_load_firmware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1467-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1468:\tret = mt7615_load_patch(dev, MT7615_PATCH_ADDRESS, MT7615_ROM_PATCH);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1469-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1486=static int mt7622_load_firmware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1498-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1499:\tret = mt7615_load_patch(dev, MT7622_PATCH_ADDRESS, MT7622_ROM_PATCH);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1500-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1627=mt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1638-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1639:\tret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS, primary_rom);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1640-\tif (ret) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1642-\t\t\t primary_rom, secondary_rom);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1643:\t\tret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1644-\t\t\t\t\tsecondary_rom);\n"
} |
| 9/2 | 2026/10/26 23:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 19137 output: 62 thoughts: 112 Thoughts: Okay, let's see what we have here. **Investigating Patch Loading in the mt76 Family** Well, isn't that interesting? I'm noticing that `mt7615_load_patch` is a key function, and it's being called by a few other crucial firmware loading functions: `mt7615_load_firmware`, `mt7622_load_firmware`, and, most intriguingly, `mt7663_load_rom_patch`. This suggests a potential shared routine for applying patches across these different chipsets, which is quite common in this family. Now, I need to understand the full call graph, and determine what other areas of code might rely on it. Let me see where `mt7663_load_rom_patch` is called, as well as `mt7615_load_firmware`. Grepping for those should quickly illuminate the dependency tree and give me a clearer picture of how these modules interact. |
| 10/2 | 2026/10/26 23:55 | tool | grepper |
0mArgs:{
"Expression": "mt7663_load_rom_patch|mt7615_load_firmware",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1445=static int mt7615_load_ram(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1455-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1456:static int mt7615_load_firmware(struct mt7615_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1457-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1626=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1627:mt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1628-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1666=int __mt7663_load_firmware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1676-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1677:\tret = mt7663_load_rom_patch(dev, \u0026n9_firmware);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1678-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1719=int mt7615_mcu_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1741-\tdefault:\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1742:\t\tret = mt7615_load_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1743-\t\tbreak;\n"
} |
| 11/2 | 2026/10/26 23:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 20181 output: 62 thoughts: 65 Thoughts: Here's my thought process, as if I were analyzing this code: **Analyzing Firmware Loading and MCU Initialization** Okay, so I need to understand the call flow for the firmware loading and MCU initialization routines in this driver. Specifically, I'm interested in `__mt7663_load_firmware` and `mt7615_mcu_init`. My first step is to trace where these functions are actually invoked. I'll use `grep` to quickly search the codebase for every instance of these function names. This should give me a clear picture of the call sites and, consequently, the broader context within which these functions operate. With that information, I'll be able to build a mental map of how the firmware loading and MCU initialization are orchestrated within the driver's initialization sequence. |
| 12/2 | 2026/10/26 23:55 | tool | grepper |
0mArgs:{
"Expression": "__mt7663_load_firmware|mt7615_mcu_init",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1627=mt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1665-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1666:int __mt7663_load_firmware(struct mt7615_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1667-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1701-}\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1702:EXPORT_SYMBOL_GPL(__mt7663_load_firmware);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1703-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1704=static int mt7663_load_firmware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1709-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1710:\tret = __mt7663_load_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1711-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1718-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1719:int mt7615_mcu_init(struct mt7615_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1720-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1759-}\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1760:EXPORT_SYMBOL_GPL(mt7615_mcu_init);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1761-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=395=void mt7615_dma_cleanup(struct mt7615_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:396:int mt7615_mcu_init(struct mt7615_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-397-bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=535=int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-536-\t\t\t bool enable);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:537:int __mt7663_load_firmware(struct mt7615_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-538-void mt7615_coredump_work(struct work_struct *work);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c=15=static void mt7615_pci_init_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c-20-\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c:21:\tret = mt7615_mcu_init(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c-22-\tfor (i = 0; (ret == -EAGAIN) \u0026\u0026 (i \u003c 10); i++) {\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c-23-\t\tmsleep(200);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c:24:\t\tret = mt7615_mcu_init(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c-25-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c=133=int mt7663s_mcu_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c-159-\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c:160:\tret = __mt7663_load_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c-161-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c=65=int mt7663u_mcu_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c-91-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c:92:\tret = __mt7663_load_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c-93-\tif (ret)\n"
} |
| 13/2 | 2026/10/26 23:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 22215 output: 49 thoughts: 292 Thoughts: **Initial Firmware Loading Sequence**
Okay, so I'm looking at this `mt7663u_mcu_init` function, and the first thing that jumps out is that it calls `__mt7663_load_firmware(dev)`. That's the entry point for the firmware loading, so that's where I need to start. From there, `__mt7663_load_firmware` then calls `mt7663_load_rom_patch`, and that then drills down to `mt7615_load_patch`. Got it.
Now, in `mt7615_load_patch`, I see this snippet:
```c
/*
* On MT7663 the Bluetooth function shares the ROM patch, and the
* semaphore is refused while it downloads the patch: wait for it.
*/
for (i = 0; i < 50; i++) {
sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);
if (sem != PATCH_NOT_DL_SEM_FAIL)
break;
msleep(100);
}
```
That's interesting. It looks like there's a semaphore protecting a shared resource ā the ROM patch ā and a wait loop in case it's unavailable. Seems like Bluetooth is probably the other user. But wait, this is MT7663 and I am working on a virtualization effort.
This gets me thinking. If MT7663U is exposed over USB, then perhaps I can get this to work in QEMU with a USB gadget emulation. Where can I find out more about MT7663U? Let's check `drivers/net/wireless/mediatek/mt76/mt7615/usb.c`! I can probably find relevant information there!
|
| 14/2 | 2026/10/26 23:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/usb.c",
"FirstLine": 1,
"LineCount": 100
}Results: {
"Contents": " 1:\t// SPDX-License-Identifier: BSD-3-Clause-Clear\n 2:\t/* Copyright (C) 2019 MediaTek Inc.\n 3:\t *\n 4:\t * Author: Felix Fietkau \u003cnbd@nbd.name\u003e\n 5:\t *\t Lorenzo Bianconi \u003clorenzo@kernel.org\u003e\n 6:\t *\t Sean Wang \u003csean.wang@mediatek.com\u003e\n 7:\t */\n 8:\t\n 9:\t#include \u003clinux/kernel.h\u003e\n 10:\t#include \u003clinux/module.h\u003e\n 11:\t#include \u003clinux/usb.h\u003e\n 12:\t\n 13:\t#include \"mt7615.h\"\n 14:\t#include \"mac.h\"\n 15:\t#include \"mcu.h\"\n 16:\t#include \"regs.h\"\n 17:\t\n 18:\tstatic const struct usb_device_id mt7615_device_table[] = {\n 19:\t\t{ USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7663, 0xff, 0xff, 0xff) },\n 20:\t\t{ USB_DEVICE_AND_INTERFACE_INFO(0x043e, 0x310c, 0xff, 0xff, 0xff) },\n 21:\t\t{ },\n 22:\t};\n 23:\t\n 24:\tstatic u32 mt7663u_rr(struct mt76_dev *dev, u32 addr)\n 25:\t{\n 26:\t\tu32 ret;\n 27:\t\n 28:\t\tmutex_lock(\u0026dev-\u003eusb.usb_ctrl_mtx);\n 29:\t\tret = ___mt76u_rr(dev, MT_VEND_READ_EXT,\n 30:\t\t\t\t USB_DIR_IN | USB_TYPE_VENDOR, addr);\n 31:\t\tmutex_unlock(\u0026dev-\u003eusb.usb_ctrl_mtx);\n 32:\t\n 33:\t\treturn ret;\n 34:\t}\n 35:\t\n 36:\tstatic void mt7663u_wr(struct mt76_dev *dev, u32 addr, u32 val)\n 37:\t{\n 38:\t\tmutex_lock(\u0026dev-\u003eusb.usb_ctrl_mtx);\n 39:\t\t___mt76u_wr(dev, MT_VEND_WRITE_EXT,\n 40:\t\t\t USB_DIR_OUT | USB_TYPE_VENDOR, addr, val);\n 41:\t\tmutex_unlock(\u0026dev-\u003eusb.usb_ctrl_mtx);\n 42:\t}\n 43:\t\n 44:\tstatic u32 mt7663u_rmw(struct mt76_dev *dev, u32 addr,\n 45:\t\t\t u32 mask, u32 val)\n 46:\t{\n 47:\t\tmutex_lock(\u0026dev-\u003eusb.usb_ctrl_mtx);\n 48:\t\tval |= ___mt76u_rr(dev, MT_VEND_READ_EXT,\n 49:\t\t\t\t USB_DIR_IN | USB_TYPE_VENDOR, addr) \u0026 ~mask;\n 50:\t\t___mt76u_wr(dev, MT_VEND_WRITE_EXT,\n 51:\t\t\t USB_DIR_OUT | USB_TYPE_VENDOR, addr, val);\n 52:\t\tmutex_unlock(\u0026dev-\u003eusb.usb_ctrl_mtx);\n 53:\t\n 54:\t\treturn val;\n 55:\t}\n 56:\t\n 57:\tstatic void mt7663u_copy(struct mt76_dev *dev, u32 offset,\n 58:\t\t\t\t const void *data, int len)\n 59:\t{\n 60:\t\tstruct mt76_usb *usb = \u0026dev-\u003eusb;\n 61:\t\tconst u8 *val = data;\n 62:\t\tint len_aligned;\n 63:\t\tint batch_len;\n 64:\t\tint copy_len;\n 65:\t\tint ret;\n 66:\t\tint i = 0;\n 67:\t\n 68:\t\tlen_aligned = round_up(len, 4);\n 69:\t\n 70:\t\tmutex_lock(\u0026usb-\u003eusb_ctrl_mtx);\n 71:\t\twhile (i \u003c len_aligned) {\n 72:\t\t\tbatch_len = min_t(int, usb-\u003edata_len, len_aligned - i);\n 73:\t\t\tcopy_len = min_t(int, batch_len, len - i);\n 74:\t\t\tmemcpy(usb-\u003edata, val + i, copy_len);\n 75:\t\t\tif (copy_len \u003c batch_len)\n 76:\t\t\t\tmemset(usb-\u003edata + copy_len, 0, batch_len - copy_len);\n 77:\t\t\tret = __mt76u_vendor_request(dev, MT_VEND_WRITE_EXT,\n 78:\t\t\t\t\t\t USB_DIR_OUT | USB_TYPE_VENDOR,\n 79:\t\t\t\t\t\t (offset + i) \u003e\u003e 16, offset + i,\n 80:\t\t\t\t\t\t usb-\u003edata, batch_len);\n 81:\t\t\tif (ret \u003c 0)\n 82:\t\t\t\tbreak;\n 83:\t\n 84:\t\t\ti += batch_len;\n 85:\t\t}\n 86:\t\tmutex_unlock(\u0026usb-\u003eusb_ctrl_mtx);\n 87:\t}\n 88:\t\n 89:\tstatic void mt7663u_stop(struct ieee80211_hw *hw, bool suspend)\n 90:\t{\n 91:\t\tstruct mt7615_phy *phy = mt7615_hw_phy(hw);\n 92:\t\tstruct mt7615_dev *dev = hw-\u003epriv;\n 93:\t\n 94:\t\tclear_bit(MT76_STATE_RUNNING, \u0026dev-\u003emphy.state);\n 95:\t\ttimer_delete_sync(\u0026phy-\u003eroc_timer);\n 96:\t\tcancel_work_sync(\u0026phy-\u003eroc_work);\n 97:\t\tcancel_delayed_work_sync(\u0026phy-\u003escan_work);\n 98:\t\tcancel_delayed_work_sync(\u0026phy-\u003emt76-\u003emac_work);\n 99:\t\tmt76u_stop_tx(\u0026dev-\u003emt76);\n 100:\t}\n"
} |
| 15/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 24623 output: 50 thoughts: 40 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Diving into the MT7663U Probe Function** Alright, let's take a look at `mt7663u_probe` ā that's the starting point for bringing up the MT7663U-based USB device. I'm going to head straight into the `drivers/net/wireless/mediatek/mt76/mt7615/usb.c` file. I'm expecting to find the standard USB driver initialization sequence in there: device enumeration, resource allocation, endpoint setup, maybe some platform-specific quirk handling, and then finally the driver registration with the USB core. I'll want to see how they're handling the chip ID and device ID matching, power management, and error handling during the probe. I'm particularly interested in seeing how they initialize the MT76 driver core and if they have any specific USB-related workarounds or optimizations. Let's see how they handle the USB descriptors and the overall device configuration. I'm anticipating a clean, well-structured probe function that leverages the USB subsystem effectively. Knowing this chipset, I'll be looking for any non-standard interrupt handling, or clever use of USB bulk transfers for command and data. Hopefully the code is well-commented, so the initial investigation will be relatively smooth. |
| 16/2 | 2026/10/26 23:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/usb.c",
"FirstLine": 140,
"LineCount": 80
}Results: {
"Contents": " 140:\t\t\t.write_copy = mt7663u_copy,\n 141:\t\t\t.type = MT76_BUS_USB,\n 142:\t\t};\n 143:\t\tstruct usb_device *udev = interface_to_usbdev(usb_intf);\n 144:\t\tstruct ieee80211_ops *ops;\n 145:\t\tstruct mt7615_dev *dev;\n 146:\t\tstruct mt76_dev *mdev;\n 147:\t\tint ret;\n 148:\t\n 149:\t\tops = devm_kmemdup(\u0026usb_intf-\u003edev, \u0026mt7615_ops, sizeof(mt7615_ops),\n 150:\t\t\t\t GFP_KERNEL);\n 151:\t\tif (!ops)\n 152:\t\t\treturn -ENOMEM;\n 153:\t\n 154:\t\tops-\u003estop = mt7663u_stop;\n 155:\t\n 156:\t\tmdev = mt76_alloc_device(\u0026usb_intf-\u003edev, sizeof(*dev), ops, \u0026drv_ops);\n 157:\t\tif (!mdev)\n 158:\t\t\treturn -ENOMEM;\n 159:\t\n 160:\t\tdev = container_of(mdev, struct mt7615_dev, mt76);\n 161:\t\tusb_reset_device(udev);\n 162:\t\n 163:\t\tusb_set_intfdata(usb_intf, dev);\n 164:\t\n 165:\t\tINIT_WORK(\u0026dev-\u003emcu_work, mt7663u_init_work);\n 166:\t\tdev-\u003ereg_map = mt7663_usb_sdio_reg_map;\n 167:\t\tdev-\u003eops = ops;\n 168:\t\tret = __mt76u_init(mdev, usb_intf, \u0026bus_ops);\n 169:\t\tif (ret \u003c 0)\n 170:\t\t\tgoto error;\n 171:\t\n 172:\t\tmdev-\u003erev = (mt76_rr(dev, MT_HW_CHIPID) \u003c\u003c 16) |\n 173:\t\t\t (mt76_rr(dev, MT_HW_REV) \u0026 0xff);\n 174:\t\tdev_dbg(mdev-\u003edev, \"ASIC revision: %04x\\n\", mdev-\u003erev);\n 175:\t\n 176:\t\tif (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON,\n 177:\t\t\t\t FW_STATE_PWR_ON \u003c\u003c 1, 500)) {\n 178:\t\t\tret = mt7663u_mcu_power_on(dev);\n 179:\t\t\tif (ret)\n 180:\t\t\t\tgoto error;\n 181:\t\t} else {\n 182:\t\t\tset_bit(MT76_STATE_POWER_OFF, \u0026dev-\u003emphy.state);\n 183:\t\t}\n 184:\t\n 185:\t\tret = mt76u_alloc_mcu_queue(\u0026dev-\u003emt76);\n 186:\t\tif (ret)\n 187:\t\t\tgoto error;\n 188:\t\n 189:\t\tret = mt76u_alloc_queues(\u0026dev-\u003emt76);\n 190:\t\tif (ret)\n 191:\t\t\tgoto error;\n 192:\t\n 193:\t\tret = mt7663_usb_sdio_register_device(dev);\n 194:\t\tif (ret)\n 195:\t\t\tgoto error;\n 196:\t\n 197:\t\treturn 0;\n 198:\t\n 199:\terror:\n 200:\t\tmt76u_queues_deinit(\u0026dev-\u003emt76);\n 201:\t\tusb_set_intfdata(usb_intf, NULL);\n 202:\t\n 203:\t\tmt76_free_device(\u0026dev-\u003emt76);\n 204:\t\n 205:\t\treturn ret;\n 206:\t}\n 207:\t\n 208:\tstatic void mt7663u_disconnect(struct usb_interface *usb_intf)\n 209:\t{\n 210:\t\tstruct mt7615_dev *dev = usb_get_intfdata(usb_intf);\n 211:\t\n 212:\t\tif (!test_bit(MT76_STATE_INITIALIZED, \u0026dev-\u003emphy.state))\n 213:\t\t\treturn;\n 214:\t\n 215:\t\tieee80211_unregister_hw(dev-\u003emt76.hw);\n 216:\t\tmt7663u_cleanup(dev);\n 217:\t\n 218:\t\tusb_set_intfdata(usb_intf, NULL);\n 219:\t\n"
} |
| 17/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 26327 output: 54 thoughts: 68 Thoughts: Here's a breakdown of my thought process: **Diving into the MT7663 USB/SDIO Device Registration** Okay, so `mt7663_usb_sdio_register_device(dev)` is definitely being called within `mt7663u_probe`. Thatās the entry point to understand how this device is brought online. It's time to dig into what's actually happening inside `mt7663_usb_sdio_register_device`. I need to understand the interaction between USB and SDIO in this context, so let's start by looking into `usb_sdio.c`. This is where the core logic of registering this interface is going to live. Let's see how the device is configured and how it's brought online. I need to understand this device's configuration and the underlying communication framework. |
| 18/2 | 2026/10/26 23:56 | tool | grepper |
0mArgs:{
"Expression": "mt7663_usb_sdio_register_device",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=548=void mt7663_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-549-\t\t\t\t struct mt76_queue_entry *e);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:550:int mt7663_usb_sdio_register_device(struct mt7615_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-551-int mt7663u_mcu_init(struct mt7615_dev *dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c=83=static int mt7663s_probe(struct sdio_func *func,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-174-\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:175:\tret = mt7663_usb_sdio_register_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-176-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c=119=static int mt7663u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-192-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:193:\tret = mt7663_usb_sdio_register_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-194-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c=279=static int mt7663_usb_sdio_init_hardware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c-306-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c:307:int mt7663_usb_sdio_register_device(struct mt7615_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c-308-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c-348-}\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c:349:EXPORT_SYMBOL_GPL(mt7663_usb_sdio_register_device);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c-350-\n"
} |
| 19/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 27495 output: 53 thoughts: 42 Thoughts: Here's my analysis of the provided code snippet, structured as if I were thinking it through: **Analyzing `mt7615/usb_sdio.c` ā Line 279-348** Okay, let's dive into this section of the `mt7615` driver, specifically within the USB/SDIO implementation. I expect to see some critical setup or control flow in this range, given the context. Let me focus on understanding what's happening around lines 279-348. This likely involves some critical hardware initialization or packet management related to USB or SDIO communication. I need to figure out: * **Bus-Specific Interactions:** Is this block specifically handling USB transfer descriptors, SDIO commands, or a mix of both? This is key for understanding how the host interacts with the MT7615 chipset. I'm expecting to look for structures/registers that are unique to the physical bus implementation. * **Data Transfers:** Are we looking at DMA setup, command queuing, or interrupt handling? I'll be searching for calls related to these areas. Specifically, I'll be looking for `usb_submit_urb`, `sdio_io_write`, `sdio_claim_host` or related functions. * **Error Handling:** Are there checks for timeouts, retries, or other error conditions within the bus communication? The code's robustness is always something I try to evaluate. I'll be scanning for return values, conditional checks, and any logging statements related to failures. I'd be looking for things like retry counters or error recovery routines. * **Power Management:** Could this be related to power-saving states or bus reset/resume sequences? The placement in `usb_sdio.c` suggests this is a possibility. * **Interrupt Handling:** Is this code related to interrupt enable, disable, and acknowledge, or is it more related to transfer start-up, queuing, and completion? Are we seeing code which registers a callback function? I'll proceed to carefully read the surrounding code, focusing on these points to create a good mental model of the bus interface's operation. I'll be looking for the bigger picture: how the driver is translating higher-level commands (e.g., sending a Wi-Fi packet) into the low-level bus operations. Ultimately, I'm expecting this block to be a fundamental piece of the driver, and I need to understand its behavior thoroughly to identify potential performance bottlenecks or subtle bugs. |
| 20/2 | 2026/10/26 23:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c",
"FirstLine": 275,
"LineCount": 75
}Results: {
"Contents": " 275:\t\n 276:\t\treturn 0;\n 277:\t}\n 278:\t\n 279:\tstatic int mt7663_usb_sdio_init_hardware(struct mt7615_dev *dev)\n 280:\t{\n 281:\t\tint ret, idx;\n 282:\t\n 283:\t\tret = mt7615_eeprom_init(dev, MT_EFUSE_BASE);\n 284:\t\tif (ret \u003c 0)\n 285:\t\t\treturn ret;\n 286:\t\n 287:\t\tif (mt76_is_usb(\u0026dev-\u003emt76)) {\n 288:\t\t\tret = mt7663u_dma_sched_init(dev);\n 289:\t\t\tif (ret)\n 290:\t\t\t\treturn ret;\n 291:\t\t}\n 292:\t\n 293:\t\tset_bit(MT76_STATE_INITIALIZED, \u0026dev-\u003emphy.state);\n 294:\t\n 295:\t\t/* Beacon and mgmt frames should occupy wcid 0 */\n 296:\t\tidx = mt76_wcid_alloc(dev-\u003emt76.wcid_mask, MT7615_WTBL_STA - 1);\n 297:\t\tif (idx)\n 298:\t\t\treturn -ENOSPC;\n 299:\t\n 300:\t\tdev-\u003emt76.global_wcid.idx = idx;\n 301:\t\tdev-\u003emt76.global_wcid.hw_key_idx = -1;\n 302:\t\trcu_assign_pointer(dev-\u003emt76.wcid[idx], \u0026dev-\u003emt76.global_wcid);\n 303:\t\n 304:\t\treturn 0;\n 305:\t}\n 306:\t\n 307:\tint mt7663_usb_sdio_register_device(struct mt7615_dev *dev)\n 308:\t{\n 309:\t\tstruct ieee80211_hw *hw = mt76_hw(dev);\n 310:\t\tint err;\n 311:\t\n 312:\t\tINIT_WORK(\u0026dev-\u003erate_work, mt7663_usb_sdio_rate_work);\n 313:\t\tINIT_LIST_HEAD(\u0026dev-\u003ewrd_head);\n 314:\t\tmt7615_init_device(dev);\n 315:\t\n 316:\t\terr = mt7663_usb_sdio_init_hardware(dev);\n 317:\t\tif (err)\n 318:\t\t\treturn err;\n 319:\t\n 320:\t\thw-\u003eextra_tx_headroom += MT_USB_TXD_SIZE;\n 321:\t\tif (mt76_is_usb(\u0026dev-\u003emt76)) {\n 322:\t\t\thw-\u003eextra_tx_headroom += MT_USB_HDR_SIZE;\n 323:\t\t\t/* check hw sg support in order to enable AMSDU */\n 324:\t\t\tif (dev-\u003emt76.usb.sg_en)\n 325:\t\t\t\thw-\u003emax_tx_fragments = MT_HW_TXP_MAX_BUF_NUM;\n 326:\t\t\telse\n 327:\t\t\t\thw-\u003emax_tx_fragments = 1;\n 328:\t\t}\n 329:\t\n 330:\t\terr = mt76_register_device(\u0026dev-\u003emt76, true, mt76_rates,\n 331:\t\t\t\t\t ARRAY_SIZE(mt76_rates));\n 332:\t\tif (err \u003c 0)\n 333:\t\t\treturn err;\n 334:\t\n 335:\t\tif (!dev-\u003emt76.usb.sg_en) {\n 336:\t\t\tstruct ieee80211_sta_vht_cap *vht_cap;\n 337:\t\n 338:\t\t\t/* decrease max A-MSDU size if SG is not supported */\n 339:\t\t\tvht_cap = \u0026dev-\u003emphy.sband_5g.sband.vht_cap;\n 340:\t\t\tvht_cap-\u003ecap \u0026= ~IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;\n 341:\t\t}\n 342:\t\n 343:\t\tieee80211_queue_work(hw, \u0026dev-\u003emcu_work);\n 344:\t\tmt7615_init_txpower(dev, \u0026dev-\u003emphy.sband_2g.sband);\n 345:\t\tmt7615_init_txpower(dev, \u0026dev-\u003emphy.sband_5g.sband);\n 346:\t\n 347:\t\treturn mt7615_init_debugfs(dev);\n 348:\t}\n 349:\tEXPORT_SYMBOL_GPL(mt7663_usb_sdio_register_device);\n"
} |
| 21/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 29437 output: 50 thoughts: 130 Thoughts: **Diving into the MCU Work Queue** Okay, so I see `dev->mcu_work` is being queued using `ieee80211_queue_work`. Right, that's standard for deferring work in the wireless driver. Now, the key question is, what *is* `mcu_work`? Let me trace it back...Ah, in `mt7663u_probe`, there it is: `INIT_WORK(&dev->mcu_work, mt7663u_init_work);`. Perfect! `mt7663u_init_work` is the function that defines what this work queue actually *does*. I'll need to look into `drivers/net/wireless/mediatek/mt76/mt7615/usb.c` to understand that. Let's see what's happening in there. |
| 22/2 | 2026/10/26 23:56 | tool | grepper |
0mArgs:{
"Expression": "mt7663u_init_work",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/usb.c=102=static void mt7663u_cleanup(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-107-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:108:static void mt7663u_init_work(struct work_struct *work)\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-109-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c=119=static int mt7663u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-164-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:165:\tINIT_WORK(\u0026dev-\u003emcu_work, mt7663u_init_work);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-166-\tdev-\u003ereg_map = mt7663_usb_sdio_reg_map;\n"
} |
| 23/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 30161 output: 50 thoughts: 16 Thoughts: Okay, here's my interpretation of what's going through my mind as I approach this code, presented in the first person, assuming a level of expertise: **Diving into `mt7663u_init_work`** Alright, let's get into this. `mt7663u_init_work`. Immediately, I see "mt7663u" and that triggers a specific mental context. I'm thinking Mediatek, probably a USB-based wireless chipset. The "_init_work" suffix tells me this is likely related to initialization and, crucially, asynchronous task execution within the kernel framework - probably utilizing the workqueue mechanism. This is my initial hypothesis. I'll need to confirm these assumptions as I look closer. I'll be looking for workqueues, work items, and associated data structures or function calls that support the initialization and configuration of the 7663u. Let's see how they've handled potential race conditions or synchronization issues in this design. I'll keep an eye out for any unusual or less common techniques. I'm eager to understand the intended flow: how is this work scheduled, what resources are being managed, and what's the overall initialization sequence? Let's get reading. |
| 24/2 | 2026/10/26 23:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/usb.c",
"FirstLine": 105,
"LineCount": 20
}Results: {
"Contents": " 105:\t\tmt76u_queues_deinit(\u0026dev-\u003emt76);\n 106:\t}\n 107:\t\n 108:\tstatic void mt7663u_init_work(struct work_struct *work)\n 109:\t{\n 110:\t\tstruct mt7615_dev *dev;\n 111:\t\n 112:\t\tdev = container_of(work, struct mt7615_dev, mcu_work);\n 113:\t\tif (mt7663u_mcu_init(dev))\n 114:\t\t\treturn;\n 115:\t\n 116:\t\tmt7615_init_work(dev);\n 117:\t}\n 118:\t\n 119:\tstatic int mt7663u_probe(struct usb_interface *usb_intf,\n 120:\t\t\t\t const struct usb_device_id *id)\n 121:\t{\n 122:\t\tstatic const struct mt76_driver_ops drv_ops = {\n 123:\t\t\t.txwi_size = MT_USB_TXD_SIZE,\n 124:\t\t\t.drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ,\n"
} |
| 25/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 30843 output: 29 thoughts: 740 Thoughts: **Analyzing the MT7663U Firmware Loading Process for Syzkaller Coverage** Okay, so I'm digging into this `mt7663u_init_work` function, and it's calling `mt7663u_mcu_init`. That's expected. Inside `mt7663u_mcu_init`, we've got a call to `__mt7663_load_firmware`. And aha, `__mt7663_load_firmware` then calls `mt7663_load_rom_patch`, which then calls `mt7615_load_patch`. Got it. Now, the interesting bit: I see a change in `mt7615_load_patch`. It's this semaphore logic, `mt76_connac_mcu_patch_sem_ctrl`. The comment says it's because Bluetooth shares the ROM patch on MT7663. They're waiting for the semaphore. Okay, that's fine. But here's where I start to get concerned for syzkaller: `firmware_request_nowarn(&fw, name, dev->mt76.dev)`. Does this even succeed in a syzkaller environment? What if the firmware isn't there? The code checks the return value, so we *should* be fine if it fails, but *does* it reach that point? And if the firmware *isn't* found, does `mt7615_load_patch` even get to `mt76_connac_mcu_patch_sem_ctrl`? We need to verify the code paths. My immediate questions become: In a standard syzkaller setup, with a virtualized environment, is the MT7663 firmware *actually* present? Does syzkaller's disk image include the `linux-firmware` package? Usually yes or no? I need to know this to understand the base case. And even if the firmware is there or not, can we even attach a USB MT7663 device using Raw-Gadget or something similar in syzkaller? We need to make sure we can trigger this code in the first place. Let's expand the scope. Can we even emulate or fuzz SDIO devices in a standard virtualized environment like GCE or QEMU? This is a separate, but related, question. Does QEMU even support SDIO? Let me check if Linux kernel has any SDIO emulation or if QEMU has SDIO devices. QEMU definitely has SD card emulation, the block device `sd-card`. But does QEMU have SDIO card emulation? Wait... it does NOT appear to emulate SDIO cards! Damn. Ok, so what about the Linux kernel itself? Does the kernel have any virtual SDIO host or virtual SDIO cards? Let me grep the kernel tree. I need to figure out what's possible here for emulating and fuzzing this driver. |
| 26/2 | 2026/10/26 23:56 | tool | grepper |
0mArgs:{
"Expression": "sdio_register_driver",
"PathPrefixes": [
"drivers/"
]
}Results: {
"Output": "drivers/bluetooth/btmrvl_sdio.c=1745=static int __init btmrvl_sdio_init_module(void)\ndrivers/bluetooth/btmrvl_sdio.c-1746-{\ndrivers/bluetooth/btmrvl_sdio.c:1747:\tif (sdio_register_driver(\u0026bt_mrvl_sdio) != 0) {\ndrivers/bluetooth/btmrvl_sdio.c-1748-\t\tBT_ERR(\"SDIO Driver Registration Failed\");\n--\ndrivers/mmc/core/sdio_bus.c=274=static void sdio_legacy_shutdown(struct sdio_func *func)\n--\ndrivers/mmc/core/sdio_bus.c-282-/**\ndrivers/mmc/core/sdio_bus.c:283: *\t__sdio_register_driver - register a function driver\ndrivers/mmc/core/sdio_bus.c-284- *\t@drv: SDIO function driver\n--\ndrivers/mmc/core/sdio_bus.c-286- */\ndrivers/mmc/core/sdio_bus.c:287:int __sdio_register_driver(struct sdio_driver *drv, struct module *owner)\ndrivers/mmc/core/sdio_bus.c-288-{\n--\ndrivers/mmc/core/sdio_bus.c-301-}\ndrivers/mmc/core/sdio_bus.c:302:EXPORT_SYMBOL_GPL(__sdio_register_driver);\ndrivers/mmc/core/sdio_bus.c-303-\n--\ndrivers/mmc/core/sdio_uart.c=1118=static int __init sdio_uart_init(void)\n--\ndrivers/mmc/core/sdio_uart.c-1143-\ndrivers/mmc/core/sdio_uart.c:1144:\tret = sdio_register_driver(\u0026sdio_uart_driver);\ndrivers/mmc/core/sdio_uart.c-1145-\tif (ret)\n--\ndrivers/net/wireless/broadcom/b43/sdio.c=195=int b43_sdio_init(void)\ndrivers/net/wireless/broadcom/b43/sdio.c-196-{\ndrivers/net/wireless/broadcom/b43/sdio.c:197:\treturn sdio_register_driver(\u0026b43_sdio_driver);\ndrivers/net/wireless/broadcom/b43/sdio.c-198-}\n--\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c=1271=int brcmf_sdio_register(void)\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c-1272-{\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c:1273:\treturn sdio_register_driver(\u0026brcmf_sdmmc_driver);\ndrivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c-1274-}\n--\ndrivers/net/wireless/marvell/libertas/if_sdio.c=1390=static int __init if_sdio_init_module(void)\n--\ndrivers/net/wireless/marvell/libertas/if_sdio.c-1396-\ndrivers/net/wireless/marvell/libertas/if_sdio.c:1397:\tret = sdio_register_driver(\u0026if_sdio_driver);\ndrivers/net/wireless/marvell/libertas/if_sdio.c-1398-\n--\ndrivers/net/wireless/silabs/wfx/main.c=505=static int __init wfx_core_init(void)\n--\ndrivers/net/wireless/silabs/wfx/main.c-514-\tif (IS_ENABLED(CONFIG_MMC)) {\ndrivers/net/wireless/silabs/wfx/main.c:515:\t\tret = sdio_register_driver(\u0026wfx_sdio_driver);\ndrivers/net/wireless/silabs/wfx/main.c-516-\t\tif (ret)\n--\ndrivers/net/wireless/st/cw1200/cw1200_sdio.c=388=static int __init cw1200_sdio_init(void)\n--\ndrivers/net/wireless/st/cw1200/cw1200_sdio.c-400-\ndrivers/net/wireless/st/cw1200/cw1200_sdio.c:401:\tret = sdio_register_driver(\u0026sdio_driver);\ndrivers/net/wireless/st/cw1200/cw1200_sdio.c-402-\tif (ret)\n"
} |
| 27/2 | 2026/10/26 23:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 33527 output: 52 thoughts: 4209 Thoughts: **Patch Analysis for Fuzzing Reachability** Okay, so I've got this patch in front of me, and my immediate concern is whether any of these changes are even *reachable* in a syzkaller context. I'm thinking, SDIO is out, right? We can't emulate or probe SDIO devices directly. So I have to assume the answer is no, not directly. But, the next question is, can we somehow trigger parts of this code through USB? I know we can emulate USB devices in syzkaller. We have USB pseudo-syscalls! We can use Raw-Gadget! That's the angle I need to explore. Let's look at the patch: Okay, first up, `mt76.h`. This is just adding some fields to the `struct mt76_sdio` related to "RX enhance mode". This is obviously SDIO-specific. Useless to me unless I can somehow get the SDIO part triggered. Next, `mt7615/init.c`. There's this check in `mt7615_check_offload_capability`. It's removing `NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR` if it's SDIO. But the key here is the `if (mt76_is_sdio(&dev->mt76))` condition. If this is *not* an SDIO device, which is more likely with USB, then this whole block is skipped, which is good for me. If this conditional is true I can't reach it. Moving on to `mt7615/mcu.c`. This is where it gets interesting, specifically the `mt7615_load_patch` function. There's this new wait loop, which is about handling a shared ROM patch with Bluetooth. The question is: Does this function even get called when we're probing a USB device like `mt7663u`? It's definitely involved in firmware loading, but the path is important. So, I need to understand the USB initialization flow for `mt7663u`. I know it's a USB device, but can I force it into this code path? I need to trace the initialization, figure out when `mt7615_load_patch` is invoked, and if that can even happen with the USB setup in syzkaller. The file name `usb_mcu.c` gives me a hint. The other files, `sdio.c` and `sdio_txrx.c`, are pretty clearly SDIO-specific and not useful to me since I can't directly use SDIO in syzkaller. All of the interrupt handling and data transfer mechanisms are based on SDIO functions. My conclusion is that the conditional is important, and that I need to determine if `mt7615_load_patch` is executed during a USB probe. The conditional in `init.c` may allow a path. The other files are useless. |
| 28/2 | 2026/10/26 23:57 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c",
"FirstLine": 60,
"LineCount": 50
}Results: {
"Contents": " 60:\t\t}\n 61:\t\n 62:\t\treturn 0;\n 63:\t}\n 64:\t\n 65:\tint mt7663u_mcu_init(struct mt7615_dev *dev)\n 66:\t{\n 67:\t\tstatic const struct mt76_mcu_ops mt7663u_mcu_ops = {\n 68:\t\t\t.headroom = MT_USB_HDR_SIZE + sizeof(struct mt7615_mcu_txd),\n 69:\t\t\t.tailroom = MT_USB_TAIL_SIZE,\n 70:\t\t\t.mcu_skb_send_msg = mt7663u_mcu_send_message,\n 71:\t\t\t.mcu_parse_response = mt7615_mcu_parse_response,\n 72:\t\t};\n 73:\t\tint ret;\n 74:\t\n 75:\t\tdev-\u003emt76.mcu_ops = \u0026mt7663u_mcu_ops;\n 76:\t\n 77:\t\tmt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);\n 78:\t\tif (test_and_clear_bit(MT76_STATE_POWER_OFF, \u0026dev-\u003emphy.state)) {\n 79:\t\t\tret = mt7615_mcu_restart(\u0026dev-\u003emt76);\n 80:\t\t\tif (ret)\n 81:\t\t\t\treturn ret;\n 82:\t\n 83:\t\t\tif (!mt76_poll_msec(dev, MT_CONN_ON_MISC,\n 84:\t\t\t\t\t MT_TOP_MISC2_FW_PWR_ON, 0, 500))\n 85:\t\t\t\treturn -EIO;\n 86:\t\n 87:\t\t\tret = mt7663u_mcu_power_on(dev);\n 88:\t\t\tif (ret)\n 89:\t\t\t\treturn ret;\n 90:\t\t}\n 91:\t\n 92:\t\tret = __mt7663_load_firmware(dev);\n 93:\t\tif (ret)\n 94:\t\t\treturn ret;\n 95:\t\n 96:\t\tmt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);\n 97:\t\tset_bit(MT76_STATE_MCU_RUNNING, \u0026dev-\u003emphy.state);\n 98:\t\n 99:\t\treturn 0;\n 100:\t}\n"
} |
| 29/2 | 2026/10/26 23:57 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 39115 output: 52 thoughts: 65 Thoughts: Here's my summary, as though I'm thinking through this process: **Diving into the MT7663 Firmware Loading** Okay, so we need to understand how this `__mt7663_load_firmware(dev)` function works. That's the key to this whole thing. Time to dig in! Let me grab the relevant code. Right, that would be in `drivers/net/wireless/mediatek/mt76/mt7615/mcu.c`. Specifically, I need to focus on lines around 1660 to 1700. Let's see what's happening in there... I bet there's some interesting stuff related to image parsing and memory mapping going on in that section. Time to get to it. |
| 30/2 | 2026/10/26 23:57 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c",
"FirstLine": 1625,
"LineCount": 60
}Results: {
"Contents": "1625:\t\n1626:\tstatic int\n1627:\tmt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)\n1628:\t{\n1629:\t\tconst char *selected_rom, *secondary_rom = MT7663_ROM_PATCH;\n1630:\t\tconst char *primary_rom = MT7663_OFFLOAD_ROM_PATCH;\n1631:\t\tint ret;\n1632:\t\n1633:\t\tif (!prefer_offload_fw) {\n1634:\t\t\tsecondary_rom = MT7663_OFFLOAD_ROM_PATCH;\n1635:\t\t\tprimary_rom = MT7663_ROM_PATCH;\n1636:\t\t}\n1637:\t\tselected_rom = primary_rom;\n1638:\t\n1639:\t\tret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS, primary_rom);\n1640:\t\tif (ret) {\n1641:\t\t\tdev_info(dev-\u003emt76.dev, \"%s not found, switching to %s\",\n1642:\t\t\t\t primary_rom, secondary_rom);\n1643:\t\t\tret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS,\n1644:\t\t\t\t\t\tsecondary_rom);\n1645:\t\t\tif (ret) {\n1646:\t\t\t\tdev_err(dev-\u003emt76.dev, \"failed to load %s\",\n1647:\t\t\t\t\tsecondary_rom);\n1648:\t\t\t\treturn ret;\n1649:\t\t\t}\n1650:\t\t\tselected_rom = secondary_rom;\n1651:\t\t}\n1652:\t\n1653:\t\tif (!strcmp(selected_rom, MT7663_OFFLOAD_ROM_PATCH)) {\n1654:\t\t\t*n9_firmware = MT7663_OFFLOAD_FIRMWARE_N9;\n1655:\t\t\tdev-\u003efw_ver = MT7615_FIRMWARE_V3;\n1656:\t\t\tdev-\u003emcu_ops = \u0026uni_update_ops;\n1657:\t\t} else {\n1658:\t\t\t*n9_firmware = MT7663_FIRMWARE_N9;\n1659:\t\t\tdev-\u003efw_ver = MT7615_FIRMWARE_V2;\n1660:\t\t\tdev-\u003emcu_ops = \u0026sta_update_ops;\n1661:\t\t}\n1662:\t\n1663:\t\treturn 0;\n1664:\t}\n1665:\t\n1666:\tint __mt7663_load_firmware(struct mt7615_dev *dev)\n1667:\t{\n1668:\t\tconst char *n9_firmware;\n1669:\t\tint ret;\n1670:\t\n1671:\t\tret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);\n1672:\t\tif (ret) {\n1673:\t\t\tdev_dbg(dev-\u003emt76.dev, \"Firmware is already download\\n\");\n1674:\t\t\treturn -EIO;\n1675:\t\t}\n1676:\t\n1677:\t\tret = mt7663_load_rom_patch(dev, \u0026n9_firmware);\n1678:\t\tif (ret)\n1679:\t\t\treturn ret;\n1680:\t\n1681:\t\tret = mt7663_load_n9(dev, n9_firmware);\n1682:\t\tif (ret)\n1683:\t\t\treturn ret;\n1684:\t\n"
} |
| 31/2 | 2026/10/26 23:57 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 40402 output: 49 thoughts: 431 Thoughts: **Analyzing the `mt7615_load_patch` Function: A Syzkaller Perspective** Okay, let's break down this `mt7615_load_patch` function. My initial thought is, can this even work within the constraints of a syzkaller VM environment? Specifically, I'm questioning the call to `firmware_request_nowarn(&fw, name, dev->mt76.dev)`. Will that actually succeed without the proprietary MT7663 firmware blob files present? That seems like a critical dependency for proper operation. I need to be sure that the correct firmware is loaded in the fuzzer VM. What is it even requesting? Let's trace that. Ah, it's requesting firmware based on the `name` argument, which likely corresponds to something like `mediatek/mt7663pr2h.bin`. I recall from previous work that similar functions use constants such as `MT7663_OFFLOAD_ROM_PATCH` and `MT7663_ROM_PATCH` to specify those files. I'll need to confirm the filename that it tries to load by tracing these constants. Let me quickly grep for those constants. This is the first place to verify that this function's attempt to load the firmware can succeed in a syzkaller context. |
| 32/2 | 2026/10/26 23:57 | tool | grepper |
0mArgs:{
"Expression": "MT7663_ROM_PATCH",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1627=mt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1628-{\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1629:\tconst char *selected_rom, *secondary_rom = MT7663_ROM_PATCH;\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1630-\tconst char *primary_rom = MT7663_OFFLOAD_ROM_PATCH;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1634-\t\tsecondary_rom = MT7663_OFFLOAD_ROM_PATCH;\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1635:\t\tprimary_rom = MT7663_ROM_PATCH;\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1636-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-50-#define MT7663_OFFLOAD_FIRMWARE_N9\t\"mediatek/mt7663_n9_v3.bin\"\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:51:#define MT7663_ROM_PATCH\t\t\"mediatek/mt7663pr2h_rebb.bin\"\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-52-#define MT7663_FIRMWARE_N9\t\t\"mediatek/mt7663_n9_rebb.bin\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c=205=MODULE_FIRMWARE(MT7663_FIRMWARE_N9);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:206:MODULE_FIRMWARE(MT7663_ROM_PATCH);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c=257=MODULE_FIRMWARE(MT7663_FIRMWARE_N9);\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:258:MODULE_FIRMWARE(MT7663_ROM_PATCH);\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-259-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c=269=MODULE_FIRMWARE(MT7663_FIRMWARE_N9);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:270:MODULE_FIRMWARE(MT7663_ROM_PATCH);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-271-\n"
} |
| 33/2 | 2026/10/26 23:57 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 42034 output: 52 thoughts: 1509 Thoughts: **SDIO Enhancement Patch Analysis: Worth Fuzzing?** Alright, let's break this down. We've got a patch, apparently from `syz-cluster`, that introduces SDIO RX enhance mode support for the MT76/MT7615 wireless drivers. My initial thought is, "Wait, SDIO? Interesting." The core change involves some new structs in `mt76.h`, and modifications in `mt7615/init.c`, `mt7615/mcu.c`, and a few other files. The code modifications are as follows: 1. `mt76.h`: New `rx_enhance`, `intr_pending`, `intr_size`, and `intr_next` fields in `struct mt76_sdio`. 2. `mt7615/init.c`: A conditional that disables `NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR` if `mt76_is_sdio()` is true. 3. `mt7615/mcu.c`: A loop with a semaphore check related to Bluetooth ROM patch downloads. 4. `mt7615/sdio.c`, `sdio.c`, and `sdio_txrx.c`: Various function additions (`mt7663s_parse_intr`, `mt7663s_probe`, `mt76s_hw_init`, `mt76s_rx_run_queue`, `mt76s_txrx_worker`, and `mt76s_sdio_irq`). Now, the crucial question: Is this patch relevant for fuzzing? Looking at the triage philosophy, the primary criterion is reachability. The patch is deemed not worthy of fuzzing if the changes are non-kernel, non-executable, or fall into categories like structurally unreachable hardware. So, can this SDIO code be executed in a standard QEMU or GCE environment? Can we emulate it? The instruction set says to only NOT fuzz if all changes are in an unreachable category. The obvious questions are: * Does syzkaller *support* SDIO? Does it have an SDIO fuzzer or emulate SDIO devices? * Can QEMU actually *emulate* SDIO wifi cards, or are we limited to SD memory card emulation? My knowledge is that syzkaller runs on QEMU/GCE, but I believe QEMU only supports SD memory card emulation using the `sd-card` device, not full SDIO wifi cards. Moreover, there's no virtual SDIO bus gadget framework like USB Raw-Gadget. So, fuzzing SDIO directly seems unlikely. But what about *indirectly*? Can the code in `mt7615/init.c` and `mt7615/mcu.c` be reached through the MT7615 PCIe or MT7663 USB drivers? Let's analyze. Looking specifically at `mt7615_check_offload_capability` in `mt7615/init.c`, the critical part is `if (mt76_is_sdio(&dev->mt76))`. If we're *not* using SDIO (i.e., PCIe or USB), this condition is false, and the code that modifies the wiphy features is skipped. Therefore, for the PCIe and USB paths, the code within this conditional is *unreachable*. Now, the final thing to determine is whether the function `mt7615_check_offload_capability` is actually called during the probe of PCIe or USB devices. If not, this code is unreachable altogether. |
| 34/2 | 2026/10/26 23:57 | tool | grepper |
0mArgs:{
"Expression": "mt7615_check_offload_capability",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/init.c=187=static void\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:188:mt7615_check_offload_capability(struct mt7615_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-189-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c=325=void mt7615_init_work(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-330-\tmt76_connac_mcu_del_wtbl_all(\u0026dev-\u003emt76);\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:331:\tmt7615_check_offload_capability(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-332-}\n"
} |
| 35/2 | 2026/10/26 23:57 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 44705 output: 50 thoughts: 4634 Thoughts: **Analyzing the Fuzzing Potential of an MT7663S SDIO Driver Patch** Alright, let's break this down. The initial thought process correctly identifies that `mt7615_check_offload_capability` is called within the initialization sequence of the MT7615 driver, specifically through `mt7663u_init_work`. This sets the stage for understanding the driver's function and potential entry points for fuzzing. We then pinpoint the `mt7663u_mcu_init` function as the place where the critical `__mt7663_load_firmware` is called, ultimately leading to `mt7615_load_patch`. The key question becomes whether the patch's logic is reachable within a fuzzing context. We examine `mt7615_load_patch`, noticing its dependency on firmware loading and a semaphore related to Bluetooth functionality, which may or may not apply to our fuzzing target. The core issue is whether syzkaller's USB capabilities can trigger this firmware loading path. The discussion about `syz_usb_connect` and the device ID `0x0e8d, 0x7663` is spot on, realizing that this can establish a connection with the target device. We must then determine if a valid firmware image is present for fuzzing purposes. However, the lack of firmware in standard syzkaller environments raises a red flag. We then determine that the syzbot does not have access to the needed firmware files. This leads to the critical realization that *we are evaluating the fuzzing potential of a patch, not trying to debug it on syzbot!* The analysis then correctly focuses on the negative criteria for determining if this patch is worth fuzzing. The key point is that we should only return `WorthFuzzing=false` if *all* modified code falls under a negative category. This leads to analyzing the patch's context. The subsequent investigation into SDIO, USB, and PCIe interfaces for MT7663 reveals a crucial distinction. We determine that SDIO is a hardware interface and standard QEMU does not emulate SDIO. Moreover, since `mt7615_load_patch` is called by firmware-loading functions for both PCIe, USB and SDIO, we need to understand which one is being modified by this patch. However, it's clear that the patch focuses specifically on an "SDIO RX enhance mode" for the MT7663S SDIO interface, as it contains modifications specific to `mt76_is_sdio`. So the question becomes can SDIO or the specific logic in `mt76_is_sdio()` be reached via a USB connection, since PCIe is known to be unreachable. Crucially, the code path inside `mt7663u_probe` and further down the call stack is re-traced. The analysis confirms that a USB connection can successfully trigger `mt7663u_probe`, but it correctly identifies that SDIO-specific code is conditional and is only executed inside of the `if (mt76_is_sdio(&dev->mt76))` conditional! The key realization here is that this particular patch is changing the SDIO RX path, and that code will not be executed unless the device is indeed an SDIO device! Since we are connected via USB, then the SDIO-specific code is not reachable. Since the patch is only specific to unreachable code when connected via USB, the code path will never be executed. The conclusion then is that the modified code falls under the "structurally unreachable hardware" category when connected via USB, and we should evaluate the fuzzing potential as `WorthFuzzing=false`. |
| 36/2 | 2026/10/26 23:58 | tool | grepper |
0mArgs:{
"Expression": "mt7615_eeprom_init",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=315=static void mt7615_cal_free_data(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-332-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:333:int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-334-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-355-}\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:356:EXPORT_SYMBOL_GPL(mt7615_eeprom_init);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=385=void mt7615_unregister_ext_phy(struct mt7615_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:386:int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-387-int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c=33=static int mt7615_init_hardware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c-40-\tINIT_WORK(\u0026dev-\u003emcu_work, mt7615_pci_init_work);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c:41:\tret = mt7615_eeprom_init(dev, addr);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c-42-\tif (ret \u003c 0)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c=279=static int mt7663_usb_sdio_init_hardware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c-282-\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c:283:\tret = mt7615_eeprom_init(dev, MT_EFUSE_BASE);\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c-284-\tif (ret \u003c 0)\n"
} |
| 37/2 | 2026/10/26 23:58 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 51007 output: 51 thoughts: 42 Thoughts: Okay, let's dive into this. I'm going to pull up `drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c` and specifically focus on the `mt7615_eeprom_init` function. I'm already anticipating what to expect, given that this is the EEPROM initialization routine. I'll need to see how the driver handles reading the EEPROM data, likely involving some sort of I2C or SPI interaction depending on the Mediatek implementation, and then how it processes that data. I want to see if they're using a standard EEPROM layout or if it's Mediatek's proprietary format. I'll be looking for things like calibration data, MAC address assignments, supported regulatory domains, and any board-specific configuration parameters being loaded. I'm also keenly interested in error handling: How robust is this function? Does it handle EEPROM read failures gracefully? Does it implement any checksum verification to ensure data integrity? I want to understand how this routine contributes to overall system reliability and the initial bring-up process of the hardware. I will also be keeping an eye out for any potentially inefficient data structures or algorithmic choices within the function; as these things can be optimized significantly. |
| 38/2 | 2026/10/26 23:58 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c",
"FirstLine": 330,
"LineCount": 40
}Results: {
"Contents": " 330:\t\t}\n 331:\t}\n 332:\t\n 333:\tint mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)\n 334:\t{\n 335:\t\tint ret;\n 336:\t\n 337:\t\tret = mt7615_eeprom_load(dev, addr);\n 338:\t\tif (ret \u003c 0)\n 339:\t\t\treturn ret;\n 340:\t\n 341:\t\tret = mt7615_check_eeprom(\u0026dev-\u003emt76);\n 342:\t\tif (ret \u0026\u0026 dev-\u003emt76.otp.data) {\n 343:\t\t\tmemcpy(dev-\u003emt76.eeprom.data, dev-\u003emt76.otp.data,\n 344:\t\t\t dev-\u003emt76.otp.size);\n 345:\t\t} else {\n 346:\t\t\tdev-\u003eflash_eeprom = true;\n 347:\t\t\tmt7615_cal_free_data(dev);\n 348:\t\t}\n 349:\t\n 350:\t\tmt7615_eeprom_parse_hw_cap(dev);\n 351:\t\tmemcpy(dev-\u003emphy.macaddr, dev-\u003emt76.eeprom.data + MT_EE_MAC_ADDR,\n 352:\t\t ETH_ALEN);\n 353:\t\n 354:\t\treturn mt76_eeprom_override(\u0026dev-\u003emphy);\n 355:\t}\n 356:\tEXPORT_SYMBOL_GPL(mt7615_eeprom_init);\n"
} |
| 39/2 | 2026/10/26 23:58 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 51811 output: 42 thoughts: 1911 Thoughts: **Triage Decision: WorthFuzzing=false**
Okay, let's break this down. We're looking at a patch for the mt7615 driver, specifically the `mt7615_load_patch` function. My initial thought was: does this change potentially introduce a new code path that's reachable? The addition seems to be some kind of retry loop involving a semaphore related to Bluetooth and firmware loading:
```c
for (i = 0; i < 50; i++) {
sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);
if (sem != PATCH_NOT_DL_SEM_FAIL)
break;
msleep(100);
}
```
Now, the triage guidelines are very clear: "Reachability is the primary gate." The code needs to *actually* be able to execute in a standard QEMU environment. The question is whether or not this code, related to `mt7615_load_patch`, can be exercised in the standard environments we rely on for fuzzing.
My primary concern is this: the patch seems to modify the firmware loading process. The patch *immediately* follows the `firmware_request_nowarn` call. If that call fails, the function returns immediately. This semaphore-waiting loop only triggers after a successful, although potentially initially busy, firmware load.
The critical piece here is *how* the firmware is loaded, which is something this function performs. The function uses `firmware_request_nowarn`. I know that this requires the firmware file itself to be present. I also know that `firmware_request_nowarn` won't succeed without a firmware file being present, which means it will immediately return early.
Now, this leads me to my core question, and this is where expertise comes in: is the SDIO interface emulated in QEMU? The answer is *no*. There's no `sdio-card` or virtual SDIO bus, no corresponding SDIO gadget driver. I know, from experience, that SDIO requires physical hardware. So, any code paths specific to SDIO hardware are structurally unreachable in QEMU.
Let's look more closely at the code. This patch modifies `drivers/net/wireless/mediatek/mt76/mt76.h` to add `struct mt76_sdio` and related fields. This data structure *specifically* indicates an SDIO connection, not USB or PCIe. This confirms my suspicion: this code is only active when we're using SDIO. This struct also includes details for "RX enhance mode". The second file that has been modified is `drivers/net/wireless/mediatek/mt76/mt7615/init.c`, to add a check for `mt76_is_sdio(&dev->mt76)`.
From a triage perspective, the important line is: `if (mt76_is_sdio(&dev->mt76))`
So this clearly shows the patch adds and modifies code that specifically targets the SDIO interface. The key thing is that, by design, the function `mt76_is_sdio()` must evaluate to true, which will occur only in the case that we are operating over SDIO bus (`mt7663s`). If `mt76_is_sdio()` evaluates to true, the patch masks out the flag `NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR`. The function will only execute when the device driver is operating over the SDIO bus, which is not emulated in QEMU.
Based on the guidelines, because this code path requires SDIO hardware to be accessible, and SDIO *is* structurally unreachable in QEMU, the answer is: WorthFuzzing=false.
|
| 40/2 | 2026/10/26 23:58 | tool | grepper |
0mArgs:{
"Expression": "mt76_is_sdio",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mcu.c=72=int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,\n--\ndrivers/net/wireless/mediatek/mt76/mcu.c-86-\tif ((mt76_is_mmio(dev) \u0026\u0026 atomic_read(\u0026dev-\u003ebus_hung)) ||\ndrivers/net/wireless/mediatek/mt76/mcu.c:87:\t (mt76_is_sdio(dev) \u0026\u0026 test_bit(MT76_RESET, \u0026dev-\u003ephy.state) \u0026\u0026\ndrivers/net/wireless/mediatek/mt76/mcu.c-88-\t atomic_read(\u0026dev-\u003ebus_hung))) {\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h=95=struct mt76_bus_ops {\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h-111-#define mt76_is_mmio(dev) ((dev)-\u003ebus-\u003etype == MT76_BUS_MMIO)\ndrivers/net/wireless/mediatek/mt76/mt76.h:112:#define mt76_is_sdio(dev) ((dev)-\u003ebus-\u003etype == MT76_BUS_SDIO)\ndrivers/net/wireless/mediatek/mt76/mt76.h-113-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=548=int mt7615_init_debugfs(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-600-\t\t\t\t \u0026fops_config);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:601:\tif (mt76_is_sdio(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-602-\t\tdebugfs_create_devm_seqfile(dev-\u003emt76.dev, \"sched-quota\", dir,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c=188=mt7615_check_offload_capability(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-206-\t\t */\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:207:\t\tif (mt76_is_sdio(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-208-\t\t\twiphy-\u003efeatures \u0026= ~NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c=2000=void mt7615_pm_wake_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c-2012-\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c:2013:\t\tif (mt76_is_sdio(mdev)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c-2014-\t\t\tmt76_connac_pm_dequeue_skbs(mphy, \u0026dev-\u003epm);\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=2617=mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-2661-\t\treq.wow_ctrl_tlv.wakeup_hif = WOW_USB;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:2662:\telse if (mt76_is_sdio(dev))\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-2663-\t\treq.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=2670=int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp)\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-2697-\t\treq.hdr.hif_type = 1;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:2698:\telse if (mt76_is_sdio(dev))\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-2699-\t\treq.hdr.hif_type = 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=3046=mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3049-{\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:3050:\tint i, offset = 0, max_len = mt76_is_sdio(dev) ? 2048 : 4096;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3051-\tu32 override = 0, option = 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=3097=mt76_connac_mcu_send_phy_ram_firmware(struct mt76_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3100-{\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:3101:\tint i, offset = 0, max_len = mt76_is_sdio(dev) ? 2048 : 4096;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3102-\tu32 override = 0, option = 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=3275=int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3276-{\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:3277:\tint i, ret, sem, max_len = mt76_is_sdio(dev) ? 2048 : 4096;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3278-\tconst struct mt76_connac2_patch_hdr *hdr;\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=3360=int mt76_connac3_load_cb_patch(struct mt76_dev *dev, const char *fw_name)\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3363-\tconst struct mt76_connac3_multi_header_v2_raw_format *hdr = NULL;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:3364:\tint i, ret, sem, max_len = mt76_is_sdio(dev) ? 2048 : 4096;\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3365-\tconst struct firmware *fw = NULL;\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=264=int mt7921_init_debugfs(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-289-\tdebugfs_create_file(\"deep-sleep\", 0600, dir, dev, \u0026fops_ds);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:290:\tif (mt76_is_sdio(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-291-\t\tdebugfs_create_devm_seqfile(dev-\u003emt76.dev, \"sched-quota\", dir,\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-185-\tinit_waitqueue_head(\u0026dev-\u003ewait);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:186:\tif (mt76_is_sdio(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-187-\t\tinit_waitqueue_head(\u0026dev-\u003emt76.sdio.wait);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=650=void mt7921_mac_reset_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-678-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:679:\tif ((mt76_is_sdio(\u0026dev-\u003emt76) || mt76_is_usb(\u0026dev-\u003emt76)) \u0026\u0026\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-680-\t atomic_read(\u0026dev-\u003emt76.bus_hung))\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=767=int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-799-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:800:\ttype = mt76_is_sdio(mdev) ? MT7921_SDIO_DATA : 0;\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-801-\tmt792x_skb_add_usb_sdio_hdr(dev, skb, type);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c=582=static int mt7921_mcu_get_nic_capability(struct mt792x_phy *mphy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c-631-\t\tcase MT_NIC_CAP_TX_RESOURCE:\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c:632:\t\t\tif (mt76_is_sdio(phy-\u003edev))\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c-633-\t\t\t\tmt7921_mcu_parse_tx_resource(phy-\u003edev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mcu.c=180=mt7925_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mcu.c-225-\t\treq.wow_ctrl_tlv.wakeup_hif = WOW_USB;\ndrivers/net/wireless/mediatek/mt76/mt7925/mcu.c:226:\telse if (mt76_is_sdio(dev))\ndrivers/net/wireless/mediatek/mt76/mt7925/mcu.c-227-\t\treq.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c=1098=int mt792x_load_firmware(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-1121-\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c:1122:\tif (mt76_is_sdio(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt792x_core.c-1123-\t\t/* activate again */\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c=319=void mt792x_pm_wake_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c-331-\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c:332:\t\tif (mt76_is_sdio(mdev)) {\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c-333-\t\t\tmt76_connac_pm_dequeue_skbs(mphy, \u0026dev-\u003epm);\n"
} |
| 41/2 | 2026/10/26 23:58 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 58360 output: 49 thoughts: 2983 Thoughts: **Analysis of a Potential Syzkaller Fuzzing Target: Mediatek MT7663U USB Wi-Fi Driver** Alright, let's break this down. My initial focus is on the `mt7663u` driver, specifically its potential vulnerability to fuzzing via syzkaller. I've been tracing the execution path and considering the impact of firmware loading. My starting point is a quick check to see if we're dealing with an SDIO device. `mt76_is_sdio(dev)` immediately tells us that USB devices are bypassing that particular branch in `mt7615/init.c`. That's good to know, but let's see what happens to USB devices. I then honed in on `mt7615_load_patch` in `drivers/net/wireless/mediatek/mt76/mt7615/mcu.c`. This function uses `firmware_request_nowarn()`, a crucial point for fuzzing analysis. The question is, can syzkaller even reach this point? I know I need to figure out if syzkaller can trigger firmware requests on USB WiFi drivers. I'm aware that syzkaller can emulate USB devices. So, I need to know if the `mt7663u` driver is reachable via syzkaller's USB gadget emulation. Examining the probe function, `mt7663u_probe`, confirms that it's indeed a USB driver, accessible through the USB bus. This means that syzkaller can, in fact, interact with it and trigger firmware requests. I'm checking that the build system includes `mt7615-common.ko`, which contains this firmware loading function. Then, I am checking that `mt7663u` uses the common code. Now comes the crucial question: can syzkaller trigger `firmware_request_nowarn` and does it have the firmware? I quickly know that the syzbot VMs contain firmware and can be configured during the build process to include firmware. The important point is not whether the firmware is present or not, but whether a "missing firmware" condition is considered a "structurally unreachable" condition in the fuzzing rules. I carefully review the syzkaller criteria for returning `WorthFuzzing=false`. The rules explicitly state that missing firmware isn't in the negative criteria! In summary, the `mt7663u` USB Wi-Fi driver, with its firmware loading path, including the critical `mt7615_load_patch` function and its dependency on `firmware_request_nowarn`, is definitely a viable and interesting target for syzkaller. The changes in the patch, specifically around the semaphore control, are also relevant in the context of the MT7663's shared Wi-Fi/Bluetooth functionality, especially when it is a USB device. The firmware loading path is definitely reachable and testable via syzkaller! |
| 42/2 | 2026/10/26 23:59 | tool | grepper |
0mArgs:{
"Expression": "mt76_connac_mcu_patch_sem_ctrl",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1240=static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1260-\tfor (i = 0; i \u003c 50; i++) {\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1261:\t\tsem = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, true);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1262-\t\tif (sem != PATCH_NOT_DL_SEM_FAIL)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1303-out:\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1304:\tsem = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, false);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1305-\tswitch (sem) {\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=22=EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-23-\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:24:int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-25-{\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-35-}\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:36:EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-37-\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c=3275=int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3280-\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:3281:\tsem = mt76_connac_mcu_patch_sem_ctrl(dev, true);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3282-\tswitch (sem) {\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3343-out:\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c:3344:\tsem = mt76_connac_mcu_patch_sem_ctrl(dev, false);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c-3345-\tswitch (sem) {\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h=2064=int mt76_connac_mcu_start_patch(struct mt76_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h:2065:int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h-2066-int mt76_connac_cb_mcu_init_download(struct mt76_dev *dev, u32 len);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2142=static int mt7915_load_firmware(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2146-\t/* Release Semaphore if taken by previous failed attempt */\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2147:\tret = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, false);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2148-\tif (ret != PATCH_REL_SEM_SUCCESS) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c=3406=static int mt7996_load_patch(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3411-\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c:3412:\tsem = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, 1);\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3413-\tswitch (sem) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3477-out:\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c:3478:\tsem = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, 0);\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3479-\tswitch (sem) {\n"
} |
| 43/2 | 2026/10/26 23:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 63665 output: 51 thoughts: 24 Thoughts: Okay, let's dive into this. Here's my understanding, presented as a personal thought process, given my expertise: **Dissecting `mt76_connac_mcu_patch_sem_ctrl`** Alright, I need to get a handle on what this `mt76_connac_mcu_patch_sem_ctrl` function actually *does*. The name suggests a Mediatek (mt76) connection control function, probably dealing with the MCU patch and some sort of semaphore or control mechanism. That's my initial guess based on experience with this kind of embedded system code. I'm assuming "connac" refers to the connectivity aspect and is a common Mediatek internal term or a specific module name. "MCU" implies that there's a micro-controller involved, which is standard in many of these Wi-Fi chipsets for offloading tasks. The "patch" suggests this is related to applying firmware updates or handling new firmware images. The "sem" indicates the use of semaphores for synchronization. I'll need to figure out what resources are being protected and what kind of critical sections are involved. I'll have to consider how this function interacts with the hardware, the driver, and any potential concurrent access scenarios. Iām thinking about possible race conditions and the overall architecture of how this semaphore helps prevent them. To really understand it, I'll need to look at the surrounding code to determine its purpose. |
| 44/2 | 2026/10/26 23:59 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c",
"FirstLine": 24,
"LineCount": 20
}Results: {
"Contents": " 24:\tint mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)\n 25:\t{\n 26:\t\tu32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;\n 27:\t\tstruct {\n 28:\t\t\t__le32 op;\n 29:\t\t} req = {\n 30:\t\t\t.op = cpu_to_le32(op),\n 31:\t\t};\n 32:\t\n 33:\t\treturn mt76_mcu_send_msg(dev, MCU_CMD(PATCH_SEM_CONTROL),\n 34:\t\t\t\t\t \u0026req, sizeof(req), true);\n 35:\t}\n 36:\tEXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);\n 37:\t\n 38:\tint mt76_connac_mcu_start_patch(struct mt76_dev *dev)\n 39:\t{\n 40:\t\tstruct {\n 41:\t\t\tu8 check_crc;\n 42:\t\t\tu8 reserved[3];\n 43:\t\t} req = {\n"
} |
| 45/2 | 2026/10/26 23:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 64356 output: 29 thoughts: 1647 Thoughts: **WorthFuzzing Analysis: MT76 SDIO Firmware Loading** Okay, let's break this down. My initial thought is to trace the execution flow of `mt76_connac_mcu_patch_sem_ctrl` and how it interacts with firmware loading in the `mt7615_load_patch` function. Specifically, I'm concerned about the potential delay introduced by the semaphore loop with `msleep(100)` ā up to 5 seconds! Is this even reachable via syzkaller fuzzing? First step: check if `firmware_request_nowarn` is triggered. If it *is* called, does syzkaller have a mechanism for providing the necessary firmware (`mediatek/mt7663pr2h.bin`)? Syzkaller doesn't mock firmware directly, it relies on `/lib/firmware`. Now, does the fuzzing environment include this firmware? Standard syzkaller typically doesn't, though some QEMU images might include non-free firmware, or they may not. So I need to verify that `mediatek/mt7663pr2h.bin` exists and can be loaded. Checking the linux-firmware repo, yes, it contains the expected file. So at least it *could* be available. Okay, let's step back and consider the *WorthFuzzing* criteria. Specifically, are the modifications in the patch, or the code path it touches, "strictly" within the *NEGATIVE CRITERIA* outlined in Section 2? 1. **Non-kernel and non-executable changes?** No, the patch clearly modifies `.c` files within the `drivers/net/wireless/mediatek/mt76` directory. 2. **Structurally unreachable hardware?** Here's the critical question! I need to determine if the target hardware is emulated. The code touches SDIO-specific files (e.g., `mt76_sdio`, `sdio.c`, `sdio_txrx.c`, `init.c`). **Yes!** SDIO cards are physical and not emulated in standard QEMU! 3. Are there any changes to the USB drivers? This patch targets the SDIO driver, specifically. The logic within `mt7615_load_patch` explicitly deals with semaphore control associated with Bluetooth functionality on MT7663, and that specifically mentions SDIO functionality. This is based on the patch description "On MT7663 the Bluetooth function shares the ROM patch". Checking the source files confirms that SDIO is the driver targeted. The patch's purpose is to handle a semaphore related to Bluetooth firmware loading, which shares the ROM patch on MT7663. Since this patch focuses on SDIO and not the USB drivers, this makes it an appropriate scenario for *WorthFuzzing=false* since SDIO is structurally unreachable. |
| 46/2 | 2026/10/26 23:59 | tool | grepper |
0mArgs:{
"Expression": "7663",
"PathPrefixes": [
"drivers/bluetooth/"
]
}Results: {
"Output": "drivers/bluetooth/btmtk.c=1768=int btmtk_usb_setup(struct hci_dev *hdev)\n--\ndrivers/bluetooth/btmtk.c-1790-\ndrivers/bluetooth/btmtk.c:1791:\tif (!dev_id || dev_id != 0x7663) {\ndrivers/bluetooth/btmtk.c-1792-\t\terr = btmtk_usb_id_get(hdev, 0x70010200, \u0026dev_id);\n--\ndrivers/bluetooth/btmtk.c-1834-\tswitch (dev_id) {\ndrivers/bluetooth/btmtk.c:1835:\tcase 0x7663:\ndrivers/bluetooth/btmtk.c:1836:\t\tfwname = FIRMWARE_MT7663;\ndrivers/bluetooth/btmtk.c-1837-\t\tbreak;\n--\ndrivers/bluetooth/btmtk.c=2059=MODULE_FIRMWARE(FIRMWARE_MT7622);\ndrivers/bluetooth/btmtk.c:2060:MODULE_FIRMWARE(FIRMWARE_MT7663);\ndrivers/bluetooth/btmtk.c-2061-MODULE_FIRMWARE(FIRMWARE_MT7668);\n--\ndrivers/bluetooth/btmtk.h-4-#define FIRMWARE_MT7622\t\t\"mediatek/mt7622pr2h.bin\"\ndrivers/bluetooth/btmtk.h:5:#define FIRMWARE_MT7663\t\t\"mediatek/mt7663pr2h.bin\"\ndrivers/bluetooth/btmtk.h-6-#define FIRMWARE_MT7668\t\t\"mediatek/mt7668pr2h.bin\"\n--\ndrivers/bluetooth/btmtksdio.c=41=struct btmtksdio_data {\n--\ndrivers/bluetooth/btmtksdio.c-47-\ndrivers/bluetooth/btmtksdio.c:48:static const struct btmtksdio_data mt7663_data = {\ndrivers/bluetooth/btmtksdio.c:49:\t.fwname = FIRMWARE_MT7663,\ndrivers/bluetooth/btmtksdio.c:50:\t.chipid = 0x7663,\ndrivers/bluetooth/btmtksdio.c-51-\t.lp_mbox_supported = false,\n--\ndrivers/bluetooth/btmtksdio.c=76=static const struct sdio_device_id btmtksdio_table[] = {\ndrivers/bluetooth/btmtksdio.c:77:\t{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7663),\ndrivers/bluetooth/btmtksdio.c:78:\t .driver_data = (kernel_ulong_t)\u0026mt7663_data },\ndrivers/bluetooth/btmtksdio.c-79-\t{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668),\n--\ndrivers/bluetooth/btmtksdio.c=1138=static int btmtksdio_setup(struct hci_dev *hdev)\n--\ndrivers/bluetooth/btmtksdio.c-1211-\t\tbreak;\ndrivers/bluetooth/btmtksdio.c:1212:\tcase 0x7663:\ndrivers/bluetooth/btmtksdio.c-1213-\tcase 0x7668:\n--\ndrivers/bluetooth/btmtkuart.c=977=static const struct btmtkuart_data mt7622_data __maybe_unused = {\n--\ndrivers/bluetooth/btmtkuart.c-980-\ndrivers/bluetooth/btmtkuart.c:981:static const struct btmtkuart_data mt7663_data __maybe_unused = {\ndrivers/bluetooth/btmtkuart.c-982-\t.flags = BTMTKUART_FLAG_STANDALONE_HW,\ndrivers/bluetooth/btmtkuart.c:983:\t.fwname = FIRMWARE_MT7663,\ndrivers/bluetooth/btmtkuart.c-984-};\n--\ndrivers/bluetooth/btmtkuart.c=992=static const struct of_device_id mtk_of_match_table[] = {\ndrivers/bluetooth/btmtkuart.c-993-\t{ .compatible = \"mediatek,mt7622-bluetooth\", .data = \u0026mt7622_data},\ndrivers/bluetooth/btmtkuart.c:994:\t{ .compatible = \"mediatek,mt7663u-bluetooth\", .data = \u0026mt7663_data},\ndrivers/bluetooth/btmtkuart.c-995-\t{ .compatible = \"mediatek,mt7668u-bluetooth\", .data = \u0026mt7668_data},\n--\ndrivers/bluetooth/btusb_main.c=193=static const struct usb_device_id quirks_table[] = {\n--\ndrivers/bluetooth/btusb_main.c-666-\ndrivers/bluetooth/btusb_main.c:667:\t/* Additional MediaTek MT7663 Bluetooth devices */\ndrivers/bluetooth/btusb_main.c-668-\t{ USB_DEVICE(0x043e, 0x310c), .driver_info = BTUSB_MEDIATEK |\n"
} |
| 47/2 | 2026/10/26 23:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 68042 output: 33 thoughts: 1172 Thoughts: **Reaching for Fuzzable Territory: The MT7663 USB and the Syzkaller Frontier** Okay, here's the deal. I'm looking at `btusb_main.c` and immediately see the `USB_DEVICE` identifier for the MT7663 Bluetooth device on USB. Now, looking further, `btmtk_usb_setup` confirms the device ID `0x7663`. The `mt7663u` driver also appears with `USB_DEVICE_AND_INTERFACE_INFO`, further solidifying the MT7663's presence on USB, handling both Wi-Fi (`mt7663u`) and Bluetooth (`btusb`). Both use similar patch loading routines. This is interesting. The next question is, can we get this probed in syzkaller? Specifically, can `mt7663u` (the Wi-Fi component) be probed and fuzzed? The answer is likely yes, because USB devices are absolutely reachable via syzkaller using raw-gadget functionality (`syz_usb_connect`) with a dummy HCD setup. But, if syzkaller *does* probe `mt7663u`, what happens? Can it actually *fuzz* it? Are we *already* fuzzing it? Let's check for existing USB descriptions or if the USB fuzzing configuration covers it. Then I am reminded of the documentation which *explicitly* lists "Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.)" as reachable. In fact, Section 3 explicitly mentions "Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.)" So, now I'm looking at the `mt7615_load_patch` function. Specifically, what if the firmware request fails? In the `mt7615_load_patch` function, `firmware_request_nowarn` is used. But will syzkaller even have the firmware file, or will the firmware loading succeed? Given that `/lib/firmware` usually exists in most test environments, with linux-firmware packages installed, maybe firmware requests will actually succeed, right? So, does the failure or success of `firmware_request_nowarn` change our ability to fuzz? What about comparing this to *other* USB Wi-Fi patches? When a patch touches USB drivers (like ath9k_htc, rtl8xxxu, mt7601u, mt76x0u, mt76x2u, etc.), are these considered reachable by syzkaller's review process? YES, USB gadget drivers are specifically mentioned as reachable, like previously noted. Now, why does the documentation say *what* is *not* fuzzed? The criteria for *not* fuzzing, as stated in the guidelines are: only "Non-kernel and non-executable changes... Structurally unreachable hardware...Unreachable execution paths". Notably, USB drivers are *not* included in the negative criteria, and vendor-specific PCIe cards are, with the explicit mention of PCI-based drivers requiring un-emulated hardware. But USB is explicitly listed as reachable. But, what about SDIO? Is SDIO a virtual bus? No, it's not. I'm checking if syzkaller has SDIO emulation or gadget support. Does the Linux kernel even have an SDIO gadget? I need to look for `sdio_gadget` or something similar using `git grep`. |
| 48/2 | 2026/10/26 23:59 | tool | grepper |
0mArgs:{
"Expression": "sdio_gadget|sdio_slave",
"PathPrefixes": [
"drivers/"
]
}Results: {
"Output": "drivers/net/wireless/rsi/rsi_91x_sdio.c=825=static int rsi_init_sdio_interface(struct rsi_hw *adapter,\n--\ndrivers/net/wireless/rsi/rsi_91x_sdio.c-861-\ndrivers/net/wireless/rsi/rsi_91x_sdio.c:862:\tstatus = rsi_init_sdio_slave_regs(adapter);\ndrivers/net/wireless/rsi/rsi_91x_sdio.c-863-\tif (status) {\n--\ndrivers/net/wireless/rsi/rsi_91x_sdio.c=882=static int rsi_sdio_reinit_device(struct rsi_hw *adapter)\n--\ndrivers/net/wireless/rsi/rsi_91x_sdio.c-898-\trsi_setupcard(adapter);\ndrivers/net/wireless/rsi/rsi_91x_sdio.c:899:\trsi_init_sdio_slave_regs(adapter);\ndrivers/net/wireless/rsi/rsi_91x_sdio.c-900-\tsdio_claim_irq(pfunction, rsi_handle_interrupt);\n--\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c=89=static int rsi_process_pkt(struct rsi_common *common)\n--\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c-141-/**\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c:142: * rsi_init_sdio_slave_regs() - This function does the actual initialization\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c-143- *\t\t\t\tof SDBUS slave registers.\n--\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c-147- */\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c:148:int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)\ndrivers/net/wireless/rsi/rsi_91x_sdio_ops.c-149-{\n--\ndrivers/net/wireless/rsi/rsi_sdio.h=110=struct rsi_91x_sdiodev {\n--\ndrivers/net/wireless/rsi/rsi_sdio.h-125-\ndrivers/net/wireless/rsi/rsi_sdio.h:126:int rsi_init_sdio_slave_regs(struct rsi_hw *adapter);\ndrivers/net/wireless/rsi/rsi_sdio.h-127-int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data);\n"
} |
| 49/2 | 2026/10/26 23:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 70731 output: 42 thoughts: 1279 Thoughts: **Analyzing the Impossibility of Virtualized SDIO Testing** Okay, so I'm looking at this patch and immediately, the issue screams out: there's no native SDIO emulation framework in Linux. SDIO devices inherently require physical SDIO hardware ā an SD/MMC host controller and an SDIO card. The obvious question then is: can I circumvent this limitation using QEMU? I need to confirm if QEMU even supports SDIO. Let me check the documentation and source code... Damn, QEMU's `hw/sd/sd.c` implements SD memory cards, but explicitly lacks support for SDIO cards. Specifically, the crucial SDIO commands (CMD5, CMD52, CMD53) are neither implemented nor handled. QEMU's SD card model either rejects or ignores them, effectively making SDIO wireless card functionality inaccessible in standard virtualized environments like QEMU or GCE. This is a dead end. SDIO wireless cards are completely unreachable in these setups! Alright, then, let's refocus on the patch itself and analyze the files that it modifies. My goal here is to determine whether the patch targets SDIO-specific driver code or if any parts are accessible through USB. I need to be methodical: 1. `drivers/net/wireless/mediatek/mt76/mt76.h`: This modifies `struct mt76_sdio`. Obviously, this is compiled and used only for SDIO configurations. 2. `drivers/net/wireless/mediatek/mt76/mt7615/init.c`: The patch modifies `mt7615_check_offload_capability`. Specifically, the code contains `if (mt76_is_sdio(...))`. Because this conditional wraps the feature modification, it *only* executes if the device is SDIO. For a USB-based device like `mt7663u` or a PCIe device like `mt7615e`, `mt76_is_sdio` is `false`, making this section of the code completely skipped. The conditional keeps me from reaching the SDIO code. And SDIO is structurally unreachable. 3. `drivers/net/wireless/mediatek/mt76/mt7615/sdio.c`: This file contains `mt7663s_parse_intr` and `mt7663s_probe`. SDIO only; again, structurally unreachable. 4. `drivers/net/wireless/mediatek/mt76/sdio.c`: `mt76s_hw_init`... SDIO only. Structurally unreachable. 5. `drivers/net/wireless/mediatek/mt76/sdio_txrx.c`: `mt76s_rx_run_queue`, `mt76s_txrx_worker`, and `mt76s_sdio_irq`. All SDIO-specific, and thus structurally unreachable. Now, hold on... what about file number six? 6. `drivers/net/wireless/mediatek/mt76/mt7615/mcu.c`: This is where things get interesting. Specifically, `mt7615_load_patch` caught my eye. The code there uses `firmware_request_nowarn`. I need to understand this deeply: Could this function, `mt7615_load_patch`, potentially be reached via an MT7663U (USB) connection? The question is, is MT7663U (USB) structurally unreachable or reachable? USB drivers are accessible via USB gadget, that's certain. However, I need to know if `mt7663u` can *actually* execute `mt7615_load_patch`. That's the crux. I need to analyze this. To reach `mt7615_load_patch`, what *must* happen during USB probing of the `mt7663u` device? Let's go back and examine `mt7663u_probe` step by step. I need to trace the execution and see if a software-emulated USB device (such as those created by `syz_usb_connect`) could possibly reach `mt7615_load_patch`. Let me look at `drivers/net/wireless/mediatek/mt76/mt7615/usb.c`: 1. It calls `__mt76u_init(mdev, usb_intf, &bus_ops)`. Ok, I need to see what `__mt76u_init` does. |
| 50/2 | 2026/10/26 23:59 | tool | grepper |
0mArgs:{
"Expression": "int __mt76u_init",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/"
]
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt76.h=1902=void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type,\ndrivers/net/wireless/mediatek/mt76/mt76.h-1903-\t\t u32 addr, u32 val);\ndrivers/net/wireless/mediatek/mt76/mt76.h:1904:int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf,\ndrivers/net/wireless/mediatek/mt76/mt76.h-1905-\t\t struct mt76_bus_ops *ops);\n--\ndrivers/net/wireless/mediatek/mt76/usb.c=1144=static const struct mt76_queue_ops usb_queue_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/usb.c-1148-\ndrivers/net/wireless/mediatek/mt76/usb.c:1149:int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf,\ndrivers/net/wireless/mediatek/mt76/usb.c-1150-\t\t struct mt76_bus_ops *ops)\n"
} |
| 51/2 | 2026/10/26 23:59 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 73412 output: 45 thoughts: 30 Thoughts: Okay, here's my interpretation of what's going on in that section of `drivers/net/wireless/mediatek/mt76/usb.c`, presented as though it's my own thought process: **Diving into the MT76 USB Driver** Alright, let's take a look at `drivers/net/wireless/mediatek/mt76/usb.c`, specifically around line 1149. I need to understand this part of the driver's operation. I'm guessing this section is handling the interaction between the USB core and the MT76 wireless chipset, perhaps related to data transfer or control commands. The line number suggests it's likely a function or a critical block within a function. I'll need to see the surrounding code to determine the exact context. I'm expecting to find USB request submission, interrupt handling, or DMA configuration. Given the location in the file, it's probably deeper than basic initialization and more about the ongoing operation of the wireless interface. Let's see if this involves descriptor parsing, buffer management, or specific USB endpoint interaction details. Analyzing this is going to be important to get a handle on the driver's resource allocation and potential for performance bottlenecks or error conditions. |
| 52/2 | 2026/10/27 00:00 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/usb.c",
"FirstLine": 1145,
"LineCount": 50
}Results: {
"Contents": "1145:\t\t.tx_queue_skb = mt76u_tx_queue_skb,\n1146:\t\t.kick = mt76u_tx_kick,\n1147:\t};\n1148:\t\n1149:\tint __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf,\n1150:\t\t\t struct mt76_bus_ops *ops)\n1151:\t{\n1152:\t\tstruct usb_device *udev = interface_to_usbdev(intf);\n1153:\t\tstruct mt76_usb *usb = \u0026dev-\u003eusb;\n1154:\t\tstruct mt76_dev **priv;\n1155:\t\tint err;\n1156:\t\n1157:\t\tINIT_WORK(\u0026usb-\u003estat_work, mt76u_tx_status_data);\n1158:\t\n1159:\t\tusb-\u003edata_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0));\n1160:\t\tif (usb-\u003edata_len \u003c 32)\n1161:\t\t\tusb-\u003edata_len = 32;\n1162:\t\n1163:\t\tusb-\u003edata = devm_kmalloc(dev-\u003edev, usb-\u003edata_len, GFP_KERNEL);\n1164:\t\tif (!usb-\u003edata)\n1165:\t\t\treturn -ENOMEM;\n1166:\t\n1167:\t\tmutex_init(\u0026usb-\u003eusb_ctrl_mtx);\n1168:\t\tdev-\u003ebus = ops;\n1169:\t\tdev-\u003equeue_ops = \u0026usb_queue_ops;\n1170:\t\n1171:\t\tdev_set_drvdata(\u0026udev-\u003edev, dev);\n1172:\t\n1173:\t\tusb-\u003esg_en = mt76u_check_sg(dev);\n1174:\t\n1175:\t\terr = mt76u_set_endpoints(intf, usb);\n1176:\t\tif (err \u003c 0)\n1177:\t\t\treturn err;\n1178:\t\n1179:\t\terr = mt76_worker_setup(dev-\u003ehw, \u0026usb-\u003erx_worker, mt76u_rx_worker,\n1180:\t\t\t\t\t\"usb-rx\");\n1181:\t\tif (err)\n1182:\t\t\treturn err;\n1183:\t\n1184:\t\terr = mt76_worker_setup(dev-\u003ehw, \u0026usb-\u003estatus_worker,\n1185:\t\t\t\t\tmt76u_status_worker, \"usb-status\");\n1186:\t\tif (err)\n1187:\t\t\treturn err;\n1188:\t\n1189:\t\tsched_set_fifo_low(usb-\u003erx_worker.task);\n1190:\t\tsched_set_fifo_low(usb-\u003estatus_worker.task);\n1191:\t\n1192:\t\t/* threaded NAPI on a dummy netdev (reusing mt76_dev's napi_dev/napi[])\n1193:\t\t * services the MAIN RX queue and gives the RX path GRO\n1194:\t\t */\n"
} |
| 53/2 | 2026/10/27 00:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 74573 output: 44 thoughts: 5335 Thoughts: **Analysis of the MT7663 SDIO Patch for Fuzzing** Alright, let's break this down systematically. I'm looking at a patch for Mediatek's MT7663 SDIO driver, and my job is to determine if it's suitable for fuzzing with syzkaller. The primary concern is reachability. The core question: can the changes *actually* be executed in a standard QEMU environment, which is what syzkaller primarily uses? First, I see the typical USB initialization, revision checks and firmware power-on sequences in `mt7663u_probe`. Then the registration of the device via `mt7663_usb_sdio_register_device`. This eventually leads to `mt7663u_init_work`, which does the firmware loading through a chain of calls to `mt7615_load_patch`, specifically. A crucial point, is this driver *really* only for SDIO? Let's check the Kconfig and see what the build options look like. I see distinct configurations for `MT7663U` (USB), `MT7663S` (SDIO) and `MT7615E` (PCIe). The Kconfig shows that `MT7663U` is a thing and uses `MT7663_USB_SDIO_COMMON`, which shares code with the SDIO and PCIe versions. Critically, because of `CONFIG_MT7663U` selecting `MT7663_USB_SDIO_COMMON` it means `mt7615/mcu.c` is being included. Now, I analyze `mt7615_load_patch` in `mcu.c`. This is where the firmware loading happens, and the patch has a retry loop in it. The key part is the call to `firmware_request_nowarn`. I know syzkaller doesn't have the proprietary firmware for the MT7663. So, if this function returns an error, the code path is dead, no fuzzing. But, that code is reachable. Syzkaller can, in theory, trigger this by responding correctly to the USB control messages sent during initialization. And the fact that the code is in `mcu.c` which is built for the USB driver changes this. Now, let's look at the triage criteria. It states that fuzzing can only occur with reachability. What constitutes unreachable code? Anything requiring specialized hardware not emulated in standard QEMU. SDIO specifically is NOT emulated in QEMU. USB, *is* emulated in QEMU. I need to meticulously review the specific changes in the patch and where the code executes. The changes are in these files: `mt76.h`, `mt7615/init.c`, `mt7615/mcu.c`, `mt7615/sdio.c`, `sdio.c`, `sdio_txrx.c`. Files like `mt7615/sdio.c`, `sdio.c`, `sdio_txrx.c` are clearly SDIO-specific and are not reachable. The `init.c` file also contains an SDIO check. The changes to `mt76.h` are likely also SDIO-specific because of the `sdio` struct. The real question is, does `mt7615/mcu.c` have reachable execution? Yes, because MT7663U (USB) will call the code when it loads the firmware. So, in conclusion, parts of this patch related directly to SDIO will not be fuzzed, as it needs specific SDIO hardware. However, the `mt7615/mcu.c` code, specifically the `mt7615_load_patch` function, is reachable *if* we can get past the firmware loading issue (or by supplying firmware, somehow). |
| 54/2 | 2026/10/27 00:00 | tool | grepper |
0mArgs:{
"Expression": "7663",
"PathPrefixes": [
"drivers/net/wireless/mediatek/mt76/mt7615/"
]
}Results: {
"Output": "\nFull output is too long, showing 200 out of 963 lines.\nUse more precise expression or PathPrefixes if possible.\n\nNumber of matching lines per file (22 files in total):\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:10\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:6\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:5\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:7\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:15\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:6\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:6\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c:16\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.h:1\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:5\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:33\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c:5\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:19\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:8\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_init.c:1\ndrivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c:2\ndrivers/net/wireless/mediatek/mt76/mt7615/regs.h:14\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:35\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c:15\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:38\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c:8\ndrivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c:21\n\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\"\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-10-\tselect MT7615_COMMON\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig=21=config MT7622_WMAC\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\"\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-38-\tselect MT76_USB\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:39:\tselect MT7663_USB_SDIO_COMMON\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-40-\tdepends on MAC80211\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-42-\thelp\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:43:\t This adds support for MT7663U 802.11ac 2x2:2 wireless devices.\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-44-\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\"\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-49-\tselect MT76_SDIO\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:50:\tselect MT7663_USB_SDIO_COMMON\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-51-\tdepends on MAC80211\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-53-\thelp\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig:54:\t This adds support for MT7663S 802.11ac 2x2:2 wireless devices.\ndrivers/net/wireless/mediatek/mt76/mt7615/Kconfig-55-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile=4=obj-$(CONFIG_MT7615E) += mt7615e.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:5:obj-$(CONFIG_MT7663_USB_SDIO_COMMON) += mt7663-usb-sdio-common.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:6:obj-$(CONFIG_MT7663U) += mt7663u.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:7:obj-$(CONFIG_MT7663S) += mt7663s.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-8-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile=16=mt7615e-$(CONFIG_MT7622_WMAC) += soc.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile-17-\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:18:mt7663-usb-sdio-common-y := usb_sdio.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:19:mt7663u-y := usb.o usb_mcu.o\ndrivers/net/wireless/mediatek/mt76/mt7615/Makefile:20:mt7663s-y := sdio.o sdio_mcu.o\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=276=mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-279-\tstruct mt7615_dev *dev = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:280:\tu32 reg = is_mt7663(\u0026dev-\u003emt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-281-\tint bound[7], i, range;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=355=mt7615_queues_acq(struct seq_file *s, void *data)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-366-\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:367:\t\tif (wmm_idx == 3 \u0026\u0026 is_mt7663(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-368-\t\t\tcontinue;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=534=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:535:mt7663s_sched_quota_read(struct seq_file *s, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-536-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=548=int mt7615_init_debugfs(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-597-\t\t\t\t \u0026fops_rf_reg);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:598:\tif (is_mt7663(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-599-\t\tdebugfs_create_file(\"chip_config\", 0600, dir, dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-602-\t\tdebugfs_create_devm_seqfile(dev-\u003emt76.dev, \"sched-quota\", dir,\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:603:\t\t\t\t\t mt7663s_sched_quota_read);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-604-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c=105=int mt7615_wait_pdma_busy(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-108-\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:109:\tif (!is_mt7663(mdev)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-110-\t\tu32 mask = MT_PDMA_TX_BUSY | MT_PDMA_RX_BUSY;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c=142=static void mt7622_dma_sched_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-165-\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:166:static void mt7663_dma_sched_init(struct mt7615_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-167-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c=201=void mt7615_dma_start(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-211-\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:212:\tif (is_mt7663(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:213:\t\tmt7663_dma_sched_init(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-214-\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:215:\t\tmt76_wr(dev, MT_MCU2HOST_INT_ENABLE, MT7663_MCU_CMD_ERROR_MASK);\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-216-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c=220=int mt7615_dma_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-295-\tmask = MT_INT_RX_DONE_ALL | mt7615_tx_mcu_int_mask(dev);\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:296:\tif (is_mt7663(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c:297:\t mask |= MT7663_INT_MCU_CMD;\ndrivers/net/wireless/mediatek/mt76/mt7615/dma.c-298-\telse\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=44=static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-49-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:50:\tif (is_mt7663(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:51:\t\tlen = MT7663_EEPROM_SIZE;\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-52-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=74=static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-77-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:78:\tBUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE \u003c MT7663_EEPROM_SIZE);\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-79-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=87=static int mt7615_check_eeprom(struct mt76_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-93-\tcase 0x7622:\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:94:\tcase 0x7663:\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-95-\t\treturn 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=102=mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-105-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:106:\tif (is_mt7663(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-107-\t\t/* dual band */\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=144=static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-150-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:151:\tif (is_mt7663(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-152-\t\tmax_nss = 2;\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-153-\t\ttx_mask = FIELD_GET(MT_EE_HW_CONF1_TX_MASK,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:154:\t\t\t\t eeprom[MT7663_EE_HW_CONF1]);\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-155-\t} else {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-172-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:173:static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-174-\t\t\t\t\t\tstruct ieee80211_channel *chan,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-182-\tif (chan-\u003eband == NL80211_BAND_2GHZ)\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:183:\t\treturn MT7663_EE_TX0_2G_TARGET_POWER + (chain_idx \u003c\u003c 4);\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-184-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-186-\tif (chain_idx == 1)\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:187:\t\tindex = MT7663_EE_TX1_5G_G0_TARGET_POWER;\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-188-\telse\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:189:\t\tindex = MT7663_EE_TX0_5G_G0_TARGET_POWER;\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-190-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=194=int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-199-\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:200:\tif (is_mt7663(\u0026dev-\u003emt76))\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:201:\t\treturn mt7663_eeprom_get_target_power_index(dev, chan,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-202-\t\t\t\t\t\t\t chain_idx);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c=242=int mt7615_eeprom_get_power_delta_index(struct mt7615_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-245-\t/* assume the first rate has the highest power offset */\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:246:\tif (is_mt7663(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-247-\t\tif (band == NL80211_BAND_2GHZ)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-249-\t\telse\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c:250:\t\t\treturn MT7663_EE_5G_RATE_POWER;\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.c-251-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h=24=enum mt7615_eeprom_field {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-33-\tMT_EE_TX0_5G_G0_TARGET_POWER =\t\t0x070,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:34:\tMT7663_EE_5G_RATE_POWER =\t\t0x089,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-35-\tMT_EE_TX1_5G_G0_TARGET_POWER =\t\t0x098,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-37-\tMT_EE_5G_RATE_POWER =\t\t\t0x0d5,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:38:\tMT7663_EE_TX0_2G_TARGET_POWER =\t\t0x0e3,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-39-\tMT_EE_EXT_PA_2G_TARGET_POWER =\t\t0x0f2,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-42-\tMT_EE_TX3_5G_G0_TARGET_POWER =\t\t0x16a,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:43:\tMT7663_EE_HW_CONF1 =\t\t\t0x1b0,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:44:\tMT7663_EE_TX0_5G_G0_TARGET_POWER =\t0x245,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:45:\tMT7663_EE_TX1_5G_G0_TARGET_POWER =\t0x2b5,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-46-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-48-\tMT7622_EE_MAX =\t\t\t\t0x3db,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h:49:\tMT7663_EE_MAX =\t\t\t\t0x600,\ndrivers/net/wireless/mediatek/mt76/mt7615/eeprom.h-50-};\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c=136=mt7615_mac_init(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-177-\tmt76_set(dev, MT_WF_MIB_SCR0, MT_MIB_SCR0_AGG_CNT_RANGE_EN);\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:178:\tif (is_mt7663(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-179-\t\tmt76_wr(dev, MT_WF_AGG(0x160), 0x5c341c02);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c=277=void mt7615_init_txpower(struct mt7615_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-292-\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:293:\tif (!is_mt7663(\u0026dev-\u003emt76) \u0026\u0026 mt7615_ext_pa_enabled(dev, band))\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-294-\t\ttarget_chains = 1;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c=365=mt7615_init_wiphy(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-383-\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c:384:\tif (is_mt7663(\u0026phy-\u003edev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7615/init.c-385-\t\twiphy-\u003eiface_combinations = if_comb;\n\n"
} |
| 55/2 | 2026/10/27 00:00 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 87841 output: 29 thoughts: 3015 Thoughts: **Reaching MT7663U via USB Gadget in Syzkaller** Okay, let's break this down. We're looking at code related to MT7663, specifically focusing on whether changes in `mt7615/mcu.c` are reachable by syzkaller. First, we know MT7663 comes in PCIe (MT7663E), USB (MT7663U), and SDIO (MT7663S) flavors. The code in question, `mt7615_load_patch`, is called by all three. My initial concern was that this might be related to SDIO, which is generally not reachable in standard QEMU/syzkaller environments. SDIO cards require physical hardware. However, the key is the USB version (MT7663U). Syzkaller can emulate USB devices using USB gadget, which means we might be able to trigger this code path. I see a loop in the patch where it waits if a semaphore fails. This loop points to potentially needing firmware to be present to avoid the loop. If the firmware file isn't present, that's a problem. Now, a critical point comes from the triage instructions: does a missing firmware file make the code "unreachable"? The instructions *explicitly* list what makes code unreachable and thus unworthy of fuzzing. A missing firmware file isn't on that list. The guidance says unreachable code is limited to hardware like SDIO (which IS unreachable), or architecture-specific code. This particular code change is *NOT* related to *only* SDIO, and is reachable via USB. The more detailed code inspection says, the patch modifies a function used by USB devices, specifically the 0x0e8d and 0x7663 VID and PID which should probe with mt7615, and call the relevant functions for USB firmware loading. Therefore, because USB is emulatable by syzkaller via USB gadget, this patch *is* reachable and worth fuzzing. |
| 56/2 | 2026/10/27 00:01 | tool | grepper |
0mArgs:{
"Expression": "config MMC_",
"PathPrefixes": [
"drivers/mmc/"
]
}Results: {
"Output": "\nFull output is too long, showing 200 out of 422 lines.\nUse more precise expression or PathPrefixes if possible.\n\nNumber of matching lines per file (2 files in total):\ndrivers/mmc/core/Kconfig:4\ndrivers/mmc/host/Kconfig:101\n\ndrivers/mmc/core/Kconfig=26=config PWRSEQ_SIMPLE\n--\ndrivers/mmc/core/Kconfig-36-\ndrivers/mmc/core/Kconfig:37:config MMC_BLOCK\ndrivers/mmc/core/Kconfig-38-\ttristate \"MMC block device driver\"\n--\ndrivers/mmc/core/Kconfig-48-\ndrivers/mmc/core/Kconfig:49:config MMC_BLOCK_MINORS\ndrivers/mmc/core/Kconfig-50-\tint \"Number of minors per block device\"\n--\ndrivers/mmc/core/Kconfig=67=config SDIO_UART\n--\ndrivers/mmc/core/Kconfig-73-\ndrivers/mmc/core/Kconfig:74:config MMC_TEST\ndrivers/mmc/core/Kconfig-75-\ttristate \"MMC host test driver\"\n--\ndrivers/mmc/core/Kconfig-85-\ndrivers/mmc/core/Kconfig:86:config MMC_CRYPTO\ndrivers/mmc/core/Kconfig-87-\tbool \"MMC Crypto Engine Support\"\n--\ndrivers/mmc/host/Kconfig=6=comment \"MMC/SD/SDIO Host Controller Drivers\"\ndrivers/mmc/host/Kconfig-7-\ndrivers/mmc/host/Kconfig:8:config MMC_DEBUG\ndrivers/mmc/host/Kconfig-9-\tbool \"MMC host drivers debugging\"\n--\ndrivers/mmc/host/Kconfig-16-\ndrivers/mmc/host/Kconfig:17:config MMC_SUNPLUS\ndrivers/mmc/host/Kconfig-18-\ttristate \"Sunplus SP7021 MMC Controller\"\n--\ndrivers/mmc/host/Kconfig-25-\ndrivers/mmc/host/Kconfig:26:config MMC_ARMMMCI\ndrivers/mmc/host/Kconfig-27-\ttristate \"ARM AMBA Multimedia Card Interface support\"\n--\ndrivers/mmc/host/Kconfig-35-\ndrivers/mmc/host/Kconfig:36:config MMC_QCOM_DML\ndrivers/mmc/host/Kconfig-37-\tbool \"Qualcomm Data Mover for SD Card Controller\"\n--\ndrivers/mmc/host/Kconfig-46-\ndrivers/mmc/host/Kconfig:47:config MMC_STM32_SDMMC\ndrivers/mmc/host/Kconfig-48-\tbool \"STMicroelectronics STM32 SDMMC Controller\"\n--\ndrivers/mmc/host/Kconfig-56-\ndrivers/mmc/host/Kconfig:57:config MMC_PXA\ndrivers/mmc/host/Kconfig-58-\ttristate \"Intel PXA25x/26x/27x Multimedia Card Interface support\"\n--\ndrivers/mmc/host/Kconfig-66-\ndrivers/mmc/host/Kconfig:67:config MMC_SDHCI\ndrivers/mmc/host/Kconfig-68-\ttristate \"Secure Digital Host Controller Interface support\"\n--\ndrivers/mmc/host/Kconfig-79-\ndrivers/mmc/host/Kconfig:80:config MMC_SDHCI_IO_ACCESSORS\ndrivers/mmc/host/Kconfig-81-\tbool\n--\ndrivers/mmc/host/Kconfig-86-\ndrivers/mmc/host/Kconfig:87:config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER\ndrivers/mmc/host/Kconfig-88-\tbool\n--\ndrivers/mmc/host/Kconfig-100-\ndrivers/mmc/host/Kconfig:101:config MMC_SDHCI_UHS2\ndrivers/mmc/host/Kconfig-102-\ttristate \"UHS2 support on SDHCI controller\" if COMPILE_TEST\n--\ndrivers/mmc/host/Kconfig-109-\ndrivers/mmc/host/Kconfig:110:config MMC_SDHCI_PCI\ndrivers/mmc/host/Kconfig-111-\ttristate \"SDHCI support on PCI bus\"\n--\ndrivers/mmc/host/Kconfig-124-\ndrivers/mmc/host/Kconfig:125:config MMC_RICOH_MMC\ndrivers/mmc/host/Kconfig-126-\tbool \"Ricoh MMC Controller Disabler\"\n--\ndrivers/mmc/host/Kconfig-138-\ndrivers/mmc/host/Kconfig:139:config MMC_SDHCI_ACPI\ndrivers/mmc/host/Kconfig-140-\ttristate \"SDHCI support for ACPI enumerated SDHCI controllers\"\n--\ndrivers/mmc/host/Kconfig-151-\ndrivers/mmc/host/Kconfig:152:config MMC_SDHCI_PLTFM\ndrivers/mmc/host/Kconfig-153-\ttristate \"SDHCI platform and OF driver helper\"\n--\ndrivers/mmc/host/Kconfig-162-\ndrivers/mmc/host/Kconfig:163:config MMC_SDHCI_OF_ARASAN\ndrivers/mmc/host/Kconfig-164-\ttristate \"SDHCI OF support for the Arasan SDHCI controllers\"\n--\ndrivers/mmc/host/Kconfig-176-\ndrivers/mmc/host/Kconfig:177:config MMC_SDHCI_OF_ASPEED\ndrivers/mmc/host/Kconfig-178-\ttristate \"SDHCI OF support for the ASPEED SDHCI controller\"\n--\ndrivers/mmc/host/Kconfig-190-\ndrivers/mmc/host/Kconfig:191:config MMC_SDHCI_OF_ASPEED_TEST\ndrivers/mmc/host/Kconfig-192-\tbool \"Tests for the ASPEED SDHCI driver\" if !KUNIT_ALL_TESTS\n--\ndrivers/mmc/host/Kconfig-206-\ndrivers/mmc/host/Kconfig:207:config MMC_SDHCI_OF_AT91\ndrivers/mmc/host/Kconfig-208-\ttristate \"SDHCI OF support for the Atmel SDMMC controller\"\n--\ndrivers/mmc/host/Kconfig-213-\ndrivers/mmc/host/Kconfig:214:config MMC_SDHCI_OF_ESDHC\ndrivers/mmc/host/Kconfig-215-\ttristate \"SDHCI OF support for the Freescale eSDHC controller\"\n--\ndrivers/mmc/host/Kconfig-226-\ndrivers/mmc/host/Kconfig:227:config MMC_SDHCI_OF_HLWD\ndrivers/mmc/host/Kconfig-228-\ttristate \"SDHCI OF support for the Nintendo Wii SDHCI controllers\"\n--\ndrivers/mmc/host/Kconfig-240-\ndrivers/mmc/host/Kconfig:241:config MMC_SDHCI_OF_DWCMSHC\ndrivers/mmc/host/Kconfig-242-\ttristate \"SDHCI OF support for the Synopsys DWC MSHC\"\n--\ndrivers/mmc/host/Kconfig-252-\ndrivers/mmc/host/Kconfig:253:config MMC_SDHCI_OF_K1\ndrivers/mmc/host/Kconfig-254-\ttristate \"SDHCI OF support for the SpacemiT K1 SoC\"\n--\ndrivers/mmc/host/Kconfig-266-\ndrivers/mmc/host/Kconfig:267:config MMC_SDHCI_OF_SPARX5\ndrivers/mmc/host/Kconfig-268-\ttristate \"SDHCI OF support for the MCHP Sparx5 SoC\"\n--\ndrivers/mmc/host/Kconfig-278-\ndrivers/mmc/host/Kconfig:279:config MMC_SDHCI_OF_MA35D1\ndrivers/mmc/host/Kconfig-280-\ttristate \"SDHCI OF support for the MA35D1 SDHCI controller\"\n--\ndrivers/mmc/host/Kconfig-290-\ndrivers/mmc/host/Kconfig:291:config MMC_SDHCI_CADENCE\ndrivers/mmc/host/Kconfig-292-\ttristate \"SDHCI support for the Cadence SD/SDIO/eMMC controller\"\n--\ndrivers/mmc/host/Kconfig-302-\ndrivers/mmc/host/Kconfig:303:config MMC_SDHCI_ESDHC_MCF\ndrivers/mmc/host/Kconfig-304-\ttristate \"SDHCI support for the Freescale eSDHC ColdFire controller\"\n--\ndrivers/mmc/host/Kconfig-315-\ndrivers/mmc/host/Kconfig:316:config MMC_SDHCI_ESDHC_IMX\ndrivers/mmc/host/Kconfig-317-\ttristate \"SDHCI support for the Freescale eSDHC/uSDHC i.MX controller\"\n--\ndrivers/mmc/host/Kconfig-330-\ndrivers/mmc/host/Kconfig:331:config MMC_SDHCI_DOVE\ndrivers/mmc/host/Kconfig-332-\ttristate \"SDHCI support on Marvell's Dove SoC\"\n--\ndrivers/mmc/host/Kconfig-343-\ndrivers/mmc/host/Kconfig:344:config MMC_SDHCI_TEGRA\ndrivers/mmc/host/Kconfig-345-\ttristate \"SDHCI platform support for the Tegra SD/MMC Controller\"\n--\ndrivers/mmc/host/Kconfig-355-\ndrivers/mmc/host/Kconfig:356:config MMC_SDHCI_S3C\ndrivers/mmc/host/Kconfig-357-\ttristate \"SDHCI support on Samsung S3C/S5P/Exynos SoC\"\n--\ndrivers/mmc/host/Kconfig-369-\ndrivers/mmc/host/Kconfig:370:config MMC_SDHCI_PXAV3\ndrivers/mmc/host/Kconfig-371-\ttristate \"Marvell MMP2 SD Host Controller support (PXAV3)\"\n--\ndrivers/mmc/host/Kconfig-382-\ndrivers/mmc/host/Kconfig:383:config MMC_SDHCI_PXAV2\ndrivers/mmc/host/Kconfig-384-\ttristate \"Marvell PXA9XX SD Host Controller support (PXAV2)\"\n--\ndrivers/mmc/host/Kconfig-396-\ndrivers/mmc/host/Kconfig:397:config MMC_SDHCI_SPEAR\ndrivers/mmc/host/Kconfig-398-\ttristate \"SDHCI support on ST SPEAr platform\"\n--\ndrivers/mmc/host/Kconfig-410-\ndrivers/mmc/host/Kconfig:411:config MMC_SDHCI_S3C_DMA\ndrivers/mmc/host/Kconfig-412-\tbool \"DMA support on S3C SDHCI\"\n--\ndrivers/mmc/host/Kconfig-420-\ndrivers/mmc/host/Kconfig:421:config MMC_SDHCI_BCM_KONA\ndrivers/mmc/host/Kconfig-422-\ttristate \"SDHCI support on Broadcom KONA platform\"\n--\ndrivers/mmc/host/Kconfig-431-\ndrivers/mmc/host/Kconfig:432:config MMC_SDHCI_BST\ndrivers/mmc/host/Kconfig-433-\ttristate \"SDHCI support for Black Sesame Technologies BST C1200 controller\"\n--\ndrivers/mmc/host/Kconfig-445-\ndrivers/mmc/host/Kconfig:446:config MMC_SDHCI_F_SDH30\ndrivers/mmc/host/Kconfig-447-\ttristate \"SDHCI support for Fujitsu Semiconductor F_SDH30\"\n--\ndrivers/mmc/host/Kconfig-456-\ndrivers/mmc/host/Kconfig:457:config MMC_SDHCI_MILBEAUT\ndrivers/mmc/host/Kconfig-458-\ttristate \"SDHCI support for Socionext Milbeaut Serieas using F_SDH30\"\n--\ndrivers/mmc/host/Kconfig-467-\ndrivers/mmc/host/Kconfig:468:config MMC_SDHCI_IPROC\ndrivers/mmc/host/Kconfig-469-\ttristate \"SDHCI support for the BCM2835 \u0026 iProc SD/MMC Controller\"\n--\ndrivers/mmc/host/Kconfig-482-\ndrivers/mmc/host/Kconfig:483:config MMC_SDHCI_NPCM\ndrivers/mmc/host/Kconfig-484-\ttristate \"Secure Digital Host Controller Interface support for NPCM\"\n--\ndrivers/mmc/host/Kconfig-490-\ndrivers/mmc/host/Kconfig:491:config MMC_MESON_GX\ndrivers/mmc/host/Kconfig-492-\ttristate \"Amlogic S905/GX*/AXG SD/MMC Host Controller support\"\n--\ndrivers/mmc/host/Kconfig-501-\ndrivers/mmc/host/Kconfig:502:config MMC_MESON_MX_SDHC\ndrivers/mmc/host/Kconfig-503-\ttristate \"Amlogic Meson SDHC Host Controller support\"\n--\ndrivers/mmc/host/Kconfig-515-\ndrivers/mmc/host/Kconfig:516:config MMC_MESON_MX_SDIO\ndrivers/mmc/host/Kconfig-517-\ttristate \"Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support\"\n--\ndrivers/mmc/host/Kconfig-528-\ndrivers/mmc/host/Kconfig:529:config MMC_MOXART\ndrivers/mmc/host/Kconfig-530-\ttristate \"MOXART SD/MMC Host Controller support\"\n--\ndrivers/mmc/host/Kconfig-537-\ndrivers/mmc/host/Kconfig:538:config MMC_SDHCI_ST\ndrivers/mmc/host/Kconfig-539-\ttristate \"SDHCI support on STMicroelectronics SoC\"\n\n"
} |
| 57/2 | 2026/10/27 00:01 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 95033 output: 257 thoughts: 7279 Thoughts: **Analysis of the MT76 SDIO Patch: Unreachable Code in Virtualized Environments** Okay, here's my breakdown of this patch and why I'm concluding that it's not worth fuzzing. I've gone over the code and the context, and here's my thinking. My initial thought was, "Hey, MT7663U (USB driver) is involved, and Syzkaller can definitely hit USB gadgets." But, diving in, it's clear this is primarily an SDIO-focused patch, despite the shared code. There are no software emulated SDIO slave/card mechanisms. The core change centers around adding RX enhance mode support for SDIO and fixing SDIO hardware-specific issues, primarily for the MT7663S driver. The modifications touch `mt76.h`, `mt7615/init.c`, `mt7615/sdio.c`, `sdio.c`, and `sdio_txrx.c`. I need to ensure this is understood and considered during review. The crucial point is that SDIO is *physical* hardware. QEMU and GCE, our standard fuzzing environments, don't emulate SDIO cards. There's no virtual SDIO gadget or device framework in the Linux kernel like there is for USB, net, or tun/tap. Any SDIO driver will require a physical SDIO host controller and a physical SDIO card. This puts the patch squarely into the "structurally unreachable hardware" category, as per the triage instructions. Even though `mt7615_load_patch` in `mt7615/mcu.c` is shared across PCIe, SDIO, and USB, the USB path can't reach the modified code. In any standard environment (like syzkaller), the `firmware_request_nowarn` for `mediatek/mt7663pr2h.bin` will fail. That's because we don't include those proprietary MediaTek firmware blobs in syzkaller. The driver will return immediately before reaching the modified retry loop. Syzkaller depends on the ability to fail at various stages, and if a known failure prevents the modified code from being hit, it must not be fuzzed, per the rules. Also, PCIe, represented by MT7615E, falls under "vendor-specific PCIe" which requires a physical ASIC. That path is also not accessible. So, although the `mt7615_load_patch` function *exists* in the USB driver, that shared code is fundamentally unreachable in a standard fuzzing setup due to the missing firmware and the SDIO focus of the patch. The core of this patch series is fundamentally tied to SDIO hardware, and SDIO hardware is not emulated. Therefore, the modified code can never be executed, and this patch isn't worth fuzzing. |
| 58/2 | 2026/10/27 00:02 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch adds SDIO RX enhance mode support and addresses MT7663 SDIO quirks in the MediaTek mt76 wireless driver. The modifications are located in the SDIO subsystem (drivers/net/wireless/mediatek/mt76/sdio.c, sdio_txrx.c, and mt7615/sdio.c), SDIO-specific capability checks in mt7615/init.c, and a semaphore retry loop in mt7615/mcu.c. SDIO devices require physical SDIO hardware and are structurally unreachable in standard virtualized environments (QEMU/GCE), as QEMU does not emulate SDIO cards and Linux lacks a software SDIO gadget framework. The shared MCU helper (mt7615_load_patch) is only called on physical PCIe hardware (not emulated in QEMU) or on USB (where probing aborts at firmware_request_nowarn due to missing proprietary firmware blobs before reaching the modified loop). Therefore, all modified code is structurally unreachable for fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds SDIO RX enhance mode support and addresses MT7663 SDIO quirks in the MediaTek mt76 wireless driver. The modifications are located in the SDIO subsystem (drivers/net/wireless/mediatek/mt76/sdio.c, sdio_txrx.c, and mt7615/sdio.c), SDIO-specific capability checks in mt7615/init.c, and a semaphore retry loop in mt7615/mcu.c. SDIO devices require physical SDIO hardware and are structurally unreachable in standard virtualized environments (QEMU/GCE), as QEMU does not emulate SDIO cards and Linux lacks a software SDIO gadget framework. The shared MCU helper (mt7615_load_patch) is only called on physical PCIe hardware (not emulated in QEMU) or on USB (where probing aborts at firmware_request_nowarn due to missing proprietary firmware blobs before reaching the modified loop). Therefore, all modified code is structurally unreachable for fuzzing.",
"WorthFuzzing": false
} |
| 59/1 | 2026/10/27 00:02 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|