| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/10/03 11:55 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies the thermal zone registration and readout logic in the MediaTek MT7996 wireless network driver. MT7996 is a PCIe-based Wi-Fi device driver that requires physical MediaTek hardware (MT7996/MT7992/MT7990) not emulated in standard virtualized environments (QEMU/GCE). Consequently, the modified code paths are structurally unreachable during fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/10/03 11:55 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 27e9e090ab122b8343b4a998c4898fd08c6e1d15\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sat Oct 3 11:55:57 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c\nindex fb635a0925840..007ac129ddc03 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c\n@@ -234,17 +234,42 @@ static const struct thermal_cooling_device_ops mt7996_thermal_ops = {\n \t.set_cur_state = mt7996_thermal_set_cur_throttle_state,\n };\n \n+static int mt7996_thermal_get_temp(struct thermal_zone_device *tz, int *temp)\n+{\n+\tstruct mt7996_phy *phy = thermal_zone_device_priv(tz);\n+\tint val;\n+\n+\tmutex_lock(\u0026phy-\u003edev-\u003emt76.mutex);\n+\tval = mt7996_mcu_get_temperature(phy);\n+\tmutex_unlock(\u0026phy-\u003edev-\u003emt76.mutex);\n+\tif (val \u003c 0)\n+\t\treturn val;\n+\n+\t*temp = val * 1000;\n+\treturn 0;\n+}\n+\n+static const struct thermal_zone_device_ops mt7996_tz_ops = {\n+\t.get_temp = mt7996_thermal_get_temp,\n+};\n+\n static void mt7996_unregister_thermal(struct mt7996_phy *phy)\n {\n \tstruct wiphy *wiphy = phy-\u003emt76-\u003ehw-\u003ewiphy;\n \tchar name[sizeof(\"cooling_deviceXXX\")];\n \n+\tif (phy-\u003etzone) {\n+\t\tthermal_of_zone_unregister(phy-\u003etzone);\n+\t\tphy-\u003etzone = NULL;\n+\t}\n+\n \tif (!phy-\u003ecdev)\n \t\treturn;\n \n \tsnprintf(name, sizeof(name), \"cooling_device%d\", phy-\u003emt76-\u003eband_idx);\n \tsysfs_remove_link(\u0026wiphy-\u003edev.kobj, name);\n \tthermal_cooling_device_unregister(phy-\u003ecdev);\n+\tphy-\u003ecdev = NULL;\n }\n \n static int mt7996_thermal_init(struct mt7996_phy *phy)\n@@ -275,14 +300,27 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)\n \tphy-\u003ethrottle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;\n \tphy-\u003ethrottle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;\n \n+\tphy-\u003etzone = thermal_of_zone_register(phy-\u003edev-\u003emt76.dev,\n+\t\t\t\t\t phy-\u003emt76-\u003eband_idx, phy,\n+\t\t\t\t\t \u0026mt7996_tz_ops);\n+\tif (IS_ERR(phy-\u003etzone)) {\n+\t\tif (PTR_ERR(phy-\u003etzone) != -ENODEV)\n+\t\t\tdev_warn(phy-\u003edev-\u003emt76.dev,\n+\t\t\t\t \"failed to register thermal zone %d: %ld\\n\",\n+\t\t\t\t phy-\u003emt76-\u003eband_idx, PTR_ERR(phy-\u003etzone));\n+\t\tphy-\u003etzone = NULL;\n+\t}\n+\n \tif (!IS_REACHABLE(CONFIG_HWMON))\n \t\treturn 0;\n \n \thwmon = devm_hwmon_device_register_with_groups(\u0026wiphy-\u003edev, name, phy,\n \t\t\t\t\t\t mt7996_hwmon_groups);\n \n-\tif (IS_ERR(hwmon))\n+\tif (IS_ERR(hwmon)) {\n+\t\tmt7996_unregister_thermal(phy);\n \t\treturn PTR_ERR(hwmon);\n+\t}\n \n \treturn 0;\n }\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h\nindex 2a0cdb56f822e..39fa25a562e5e 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h\n+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h\n@@ -372,6 +372,7 @@ struct mt7996_phy {\n \n \tstruct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];\n \n+\tstruct thermal_zone_device *tzone;\n \tstruct thermal_cooling_device *cdev;\n \tu8 cdev_state;\n \tu8 throttle_state;\n"
} |
| 2/1 | 2026/10/03 11:55 | agent | patch-evaluator |
0mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the thermal zone registration and readout logic in the MediaTek MT7996 wireless network driver. MT7996 is a PCIe-based Wi-Fi device driver that requires physical MediaTek hardware (MT7996/MT7992/MT7990) not emulated in standard virtualized environments (QEMU/GCE). Consequently, the modified code paths are structurally unreachable during 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 27e9e090ab122b8343b4a998c4898fd08c6e1d15
Author: syz-cluster <triage@syzkaller.com>
Date: Sat Oct 3 11:55:57 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index fb635a0925840..007ac129ddc03 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -234,17 +234,42 @@ static const struct thermal_cooling_device_ops mt7996_thermal_ops = {
.set_cur_state = mt7996_thermal_set_cur_throttle_state,
};
+static int mt7996_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+ struct mt7996_phy *phy = thermal_zone_device_priv(tz);
+ int val;
+
+ mutex_lock(&phy->dev->mt76.mutex);
+ val = mt7996_mcu_get_temperature(phy);
+ mutex_unlock(&phy->dev->mt76.mutex);
+ if (val < 0)
+ return val;
+
+ *temp = val * 1000;
+ return 0;
+}
+
+static const struct thermal_zone_device_ops mt7996_tz_ops = {
+ .get_temp = mt7996_thermal_get_temp,
+};
+
static void mt7996_unregister_thermal(struct mt7996_phy *phy)
{
struct wiphy *wiphy = phy->mt76->hw->wiphy;
char name[sizeof("cooling_deviceXXX")];
+ if (phy->tzone) {
+ thermal_of_zone_unregister(phy->tzone);
+ phy->tzone = NULL;
+ }
+
if (!phy->cdev)
return;
snprintf(name, sizeof(name), "cooling_device%d", phy->mt76->band_idx);
sysfs_remove_link(&wiphy->dev.kobj, name);
thermal_cooling_device_unregister(phy->cdev);
+ phy->cdev = NULL;
}
static int mt7996_thermal_init(struct mt7996_phy *phy)
@@ -275,14 +300,27 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;
phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;
+ phy->tzone = thermal_of_zone_register(phy->dev->mt76.dev,
+ phy->mt76->band_idx, phy,
+ &mt7996_tz_ops);
+ if (IS_ERR(phy->tzone)) {
+ if (PTR_ERR(phy->tzone) != -ENODEV)
+ dev_warn(phy->dev->mt76.dev,
+ "failed to register thermal zone %d: %ld\n",
+ phy->mt76->band_idx, PTR_ERR(phy->tzone));
+ phy->tzone = NULL;
+ }
+
if (!IS_REACHABLE(CONFIG_HWMON))
return 0;
hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
mt7996_hwmon_groups);
- if (IS_ERR(hwmon))
+ if (IS_ERR(hwmon)) {
+ mt7996_unregister_thermal(phy);
return PTR_ERR(hwmon);
+ }
return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index 2a0cdb56f822e..39fa25a562e5e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -372,6 +372,7 @@ struct mt7996_phy {
struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];
+ struct thermal_zone_device *tzone;
struct thermal_cooling_device *cdev;
u8 cdev_state;
u8 throttle_state;
|
| 3/2 | 2026/10/03 11:55 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 3986 output: 36 thoughts: 146 Thoughts: **Analyzing the Patch for the MT7996 Driver** Okay, let's dive into this. The patch impacts `drivers/net/wireless/mediatek/mt76/mt7996/init.c` and `drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h`. My immediate question is, what exactly is `mt7996`? I need to quickly establish its context. Is this a PCIe device, an SoC integrated wireless solution, or something else entirely? I should also quickly ascertain its typical deployment environment - are we talking about a standard desktop virtualization scenario, or something more specialized? This will guide my initial assessment of the potential impact. I'll start by determining the bus type for `mt7996`, since that often determines the level of abstraction and potential integration complexities. To quickly understand the overall structure, I'll use `grepper` or a similar directory indexing tool to get a high-level view of the `drivers/net/wireless/mediatek/mt76/mt7996/` directory. This should give me a good overview of the driver's components and related files. |
| 4/2 | 2026/10/03 11:56 | tool | codesearch-dir-index |
0mArgs:{
"Dir": "drivers/net/wireless/mediatek/mt76/mt7996"
}Results: {
"Files": [
"coredump.c",
"coredump.h",
"debugfs.c",
"dma.c",
"eeprom.c",
"eeprom.h",
"init.c",
"mac.c",
"mac.h",
"main.c",
"mcu.c",
"mcu.h",
"mmio.c",
"mt7996.h",
"npu.c",
"pci.c",
"regs.h"
],
"Subdirs": null
} |
| 5/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 4556 output: 37 thoughts: 49 Thoughts: Okay, let's dive into this. Here's how I'd approach this task, walking through my thought process: **Investigating MT7996 Bus Support** Alright, I'm starting with a very specific question: what buses does this "mt7996" system or driver support? I need to get a handle on the architecture. My first instinct is to navigate the directory and look for the relevant files. I'm seeing `pci.c` and `mmio.c`. Based on my experience, those are highly suggestive of PCI and Memory-Mapped I/O support. Excellent. That gives me a working hypothesis. Now, I want to confirm this and see if there are any other bus types that I should be aware of. I need to check the `Kconfig` files; that's the canonical place to find what's enabled, conditionalized, and specifically set for a particular target. That's the next logical step. I'll get the definitive answer in the configuration files. |
| 6/2 | 2026/10/03 11:56 | tool | grepper |
0mArgs:{
"Expression": "MT7996",
"PathPrefix": "drivers/net/wireless/mediatek/mt76"
}Results: {
"Output": "\nFull output is too long, showing 200 out of 1582 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/mediatek/mt76/Makefile=50=obj-$(CONFIG_MT7921_COMMON) += mt7921/\ndrivers/net/wireless/mediatek/mt76/Makefile:51:obj-$(CONFIG_MT7996E) += mt7996/\ndrivers/net/wireless/mediatek/mt76/Makefile-52-obj-$(CONFIG_MT7925_COMMON) += mt7925/\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig:2:config MT7996E\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig:3:\ttristate \"MediaTek MT7996 (PCIe) support\"\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig-4-\tselect MT76_CONNAC_LIB\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig-9-\thelp\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig:10:\t This adds support for MT7996-based PCIe wireless devices,\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig-11-\t which support concurrent tri-band operation at 6GHz, 5GHz,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig-15-\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig:16:config MT7996_NPU\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig:17:\tbool \"MT7996 (PCIe) NPU support\"\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig:18:\tdepends on MT7996E\ndrivers/net/wireless/mediatek/mt76/mt7996/Kconfig-19-\tdepends on NET_AIROHA_NPU=y || MT76_CORE=NET_AIROHA_NPU\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile-2-\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile:3:obj-$(CONFIG_MT7996E) += mt7996e.o\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile-4-\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile=5=mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \\\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile-7-\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile:8:mt7996e-$(CONFIG_MT7996_NPU) += npu.o\ndrivers/net/wireless/mediatek/mt76/mt7996/Makefile-9-mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/coredump.c=48=mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u32 *num)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/coredump.c-50-\tswitch (mt76_chip(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7996/coredump.c:51:\tcase MT7996_DEVICE_ID:\ndrivers/net/wireless/mediatek/mt76/mt7996/coredump.c:52:\tcase MT7996_DEVICE_ID_2:\ndrivers/net/wireless/mediatek/mt76/mt7996/coredump.c-53-\t\t*num = ARRAY_SIZE(mt7996_mem_regions);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c=46=static void mt7996_dma_config(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-59-\t/* rx queue */\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:60:\tRXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, MT7996_RXQ_MCU_WM);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-61-\t/* for mt7990, RX ring 1 is for SDO instead */\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:62:\tRXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7996_RXQ_MCU_WA);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:63:\tRXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0, MT7996_RXQ_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-64-\tif (mt7996_has_wa(dev))\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-65-\t\tRXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:66:\t\t\t MT7996_RXQ_MCU_WA_MAIN);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-67-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-69-\tcase MT7992_DEVICE_ID:\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:70:\t\tRXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA0, MT_INT_RX_DONE_WA_EXT, MT7996_RXQ_MCU_WA_EXT);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:71:\t\tRXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1, MT7996_RXQ_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-72-\t\tbreak;\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-73-\tcase MT7990_DEVICE_ID:\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:74:\t\tRXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1, MT7996_RXQ_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-75-\t\tRXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-80-\t\tbreak;\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:81:\tcase MT7996_DEVICE_ID:\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-82-\tdefault:\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-83-\t\t/* mt7996 band2 */\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:84:\t\tRXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:85:\t\tRXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-86-\t\tbreak;\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-91-\t\tRXQ_CONFIG(MT_RXQ_RRO_BAND0, WFDMA0, MT_INT_RX_DONE_RRO_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:92:\t\t\t MT7996_RXQ_RRO_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-93-\t\tif (dev-\u003emt76.hwrro_mode == MT76_HWRRO_V3)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-95-\t\t\t\t MT_INT_RX_DONE_MSDU_PG_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:96:\t\t\t\t MT7996_RXQ_MSDU_PG_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-97-\t\tif (is_mt7996(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-98-\t\t\tRXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:99:\t\t\t\t MT_INT_RX_TXFREE_MAIN, MT7996_RXQ_TXFREE0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-100-\t\t\t/* band1 */\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-102-\t\t\t\t MT_INT_RX_DONE_MSDU_PG_BAND1,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:103:\t\t\t\t MT7996_RXQ_MSDU_PG_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-104-\t\t\t/* band2 */\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-106-\t\t\t\t MT_INT_RX_DONE_RRO_BAND2,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:107:\t\t\t\t MT7996_RXQ_RRO_BAND2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-108-\t\t\tRXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-109-\t\t\t\t MT_INT_RX_DONE_MSDU_PG_BAND2,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:110:\t\t\t\t MT7996_RXQ_MSDU_PG_BAND2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-111-\t\t\tRXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:112:\t\t\t\t MT_INT_RX_TXFREE_TRI, MT7996_RXQ_TXFREE2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-113-\t\t} else {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-115-\t\t\t\t MT_INT_RX_DONE_RRO_BAND1,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:116:\t\t\t\t MT7996_RXQ_RRO_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-117-\t\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-121-\t\t\t\t MT_INT_RX_DONE_RRO_IND,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:122:\t\t\t\t MT7996_RXQ_RRO_IND);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-123-\t\telse\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-125-\t\t\t\t MT_INT_RX_DONE_RRO_RXDMAD_C,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:126:\t\t\t\t MT7996_RXQ_RRO_RXDMAD_C);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-127-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-133-\t\t\t\tTXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND2,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:134:\t\t\t\t\t MT7996_TXQ_BAND2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-135-\t\t\t\tTXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:136:\t\t\t\t\t MT7996_TXQ_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-137-\t\t\t\tTXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND1,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:138:\t\t\t\t\t MT7996_TXQ_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-139-\t\t\t} else {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-141-\t\t\t\tTXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:142:\t\t\t\t\t MT7996_TXQ_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-143-\t\t\t\tTXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:144:\t\t\t\t\t MT7996_TXQ_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-145-\t\t\t\tTXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:146:\t\t\t\t\t MT7996_TXQ_BAND2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-147-\t\t\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-150-\t\t\tTXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:151:\t\t\t\t MT7996_TXQ_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-152-\t\t\tTXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND1,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:153:\t\t\t\t MT7996_TXQ_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-154-\t\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-158-\t\t\tTXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:159:\t\t\t\t MT7996_TXQ_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-160-\t\t\tTXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND2,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:161:\t\t\t\t MT7996_TXQ_BAND2);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-162-\t\t} else {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-164-\t\t\tTXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:165:\t\t\t\t MT7996_TXQ_BAND0);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-166-\t\t\tTXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:167:\t\t\t\t MT7996_TXQ_BAND1);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-168-\t\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-171-\t/* mcu tx queue */\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:172:\tMCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7996_TXQ_FWDL);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:173:\tMCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, MT7996_TXQ_MCU_WM);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-174-\tif (mt7996_has_wa(dev))\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-175-\t\tMCUQ_CONFIG(MT_MCUQ_WA, WFDMA0, MT_INT_TX_DONE_MCU_WA,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:176:\t\t\t MT7996_TXQ_MCU_WA);\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-177-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c=521=int mt7996_dma_rro_init(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-535-\t\t\t\t MT_RXQ_ID(MT_RXQ_RRO_RXDMAD_C),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:536:\t\t\t\t MT7996_RX_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:537:\t\t\t\t MT7996_RX_BUF_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-538-\t\t\t\t MT_RXQ_RRO_AP_RING_BASE);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-561-\t\t\t MT_RXQ_ID(MT_RXQ_RRO_IND),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:562:\t\t\t MT7996_RX_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-563-\t\t\t 0, MT_RXQ_RRO_IND_RING_BASE);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-574-\tsize = is_mt7996(mdev) \u0026\u0026 mt76_npu_device_active(mdev)\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:575:\t ? MT7996_NPU_RX_RING_SIZE / 4 : MT7996_RX_RING_SIZE;\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-576-\tret = mt76_queue_alloc(dev, \u0026mdev-\u003eq_rx[MT_RXQ_MSDU_PAGE_BAND0],\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-577-\t\t\t MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:578:\t\t\t size, MT7996_RX_MSDU_PAGE_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-579-\t\t\t MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-591-\t\tsize = is_mt7996(mdev) \u0026\u0026 mt76_npu_device_active(mdev)\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:592:\t\t ? MT7996_NPU_RX_RING_SIZE / 2 : MT7996_RX_RING_SIZE;\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-593-\t\tret = mt76_queue_alloc(dev, \u0026mdev-\u003eq_rx[MT_RXQ_MSDU_PAGE_BAND1],\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-594-\t\t\t\t MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:595:\t\t\t\t size, MT7996_RX_MSDU_PAGE_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-596-\t\t\t\t MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-609-\t\tsize = is_mt7996(mdev) \u0026\u0026 mt76_npu_device_active(mdev)\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:610:\t\t ? MT7996_NPU_RX_RING_SIZE : MT7996_RX_RING_SIZE;\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-611-\t\tret = mt76_queue_alloc(dev, \u0026mdev-\u003eq_rx[MT_RXQ_MSDU_PAGE_BAND2],\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-612-\t\t\t\t MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:613:\t\t\t\t size, MT7996_RX_MSDU_PAGE_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-614-\t\t\t\t MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c=664=int mt7996_dma_init(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-683-\t\tret = mt7996_init_tx_queues(\u0026dev-\u003ephy, MT_TXQ_ID(0),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:684:\t\t\t\t\t MT7996_NPU_TX_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-685-\t\t\t\t\t MT_TXQ_RING_BASE(0) + hif1_ofs,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-689-\t\t\t\t\t MT_TXQ_ID(dev-\u003emphy.band_idx),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:690:\t\t\t\t\t MT7996_TX_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-691-\t\t\t\t\t MT_TXQ_RING_BASE(0), wed);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-697-\t\t\t\t MT_MCUQ_ID(MT_MCUQ_WM),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:698:\t\t\t\t MT7996_TX_MCU_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-699-\t\t\t\t MT_MCUQ_RING_BASE(MT_MCUQ_WM));\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-706-\t\t\t\t\t MT_MCUQ_ID(MT_MCUQ_WA),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:707:\t\t\t\t\t MT7996_TX_MCU_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-708-\t\t\t\t\t MT_MCUQ_RING_BASE(MT_MCUQ_WA));\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-715-\t\t\t\t MT_MCUQ_ID(MT_MCUQ_FWDL),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:716:\t\t\t\t MT7996_TX_FWDL_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-717-\t\t\t\t MT_MCUQ_RING_BASE(MT_MCUQ_FWDL));\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-723-\t\t\t MT_RXQ_ID(MT_RXQ_MCU),\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:724:\t\t\t MT7996_RX_MCU_RING_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c:725:\t\t\t MT7996_RX_MCU_BUF_SIZE,\ndrivers/net/wireless/mediatek/mt76/mt7996/dma.c-726-\t\t\t MT_RXQ_RING_BASE(MT_RXQ_MCU));\n--\n\n"
} |
| 7/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 12528 output: 49 thoughts: 49 Thoughts: Okay, let's break this down. **Investigating the `CONFIG_MT7996E` Kernel Configuration** Alright, I see this kernel configuration option, `CONFIG_MT7996E`, which suggests MediaTek MT7996 PCIe support. My immediate next step, as always, is to dive into the code. Specifically, I need to understand what this device *is* from the kernel's perspective, so I'm going to head straight to `pci.c`. I need to figure out the exact nature of this thing; is it a network card, a storage controller, or something else entirely? The `pci.c` file is the central repository for PCI device handling, and that's where I'll get a real understanding. |
| 8/2 | 2026/10/03 11:56 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/mediatek/mt76/mt7996/pci.c",
"FirstLine": 1,
"LineCount": 50
}Results: {
"Contents": " 1:\t// SPDX-License-Identifier: BSD-3-Clause-Clear\n 2:\t/*\n 3:\t * Copyright (C) 2022 MediaTek Inc.\n 4:\t */\n 5:\t\n 6:\t#include \u003clinux/kernel.h\u003e\n 7:\t#include \u003clinux/module.h\u003e\n 8:\t#include \u003clinux/pci.h\u003e\n 9:\t\n 10:\t#include \"mt7996.h\"\n 11:\t#include \"mac.h\"\n 12:\t#include \"../trace.h\"\n 13:\t\n 14:\tstatic LIST_HEAD(hif_list);\n 15:\tstatic DEFINE_SPINLOCK(hif_lock);\n 16:\tstatic u32 hif_idx;\n 17:\t\n 18:\tstatic const struct pci_device_id mt7996_pci_device_table[] = {\n 19:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7996_DEVICE_ID) },\n 20:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7992_DEVICE_ID) },\n 21:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7990_DEVICE_ID) },\n 22:\t\t{ },\n 23:\t};\n 24:\t\n 25:\tstatic const struct pci_device_id mt7996_hif_device_table[] = {\n 26:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7996_DEVICE_ID_2) },\n 27:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7992_DEVICE_ID_2) },\n 28:\t\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7990_DEVICE_ID_2) },\n 29:\t\t{ },\n 30:\t};\n 31:\t\n 32:\tstatic struct mt7996_hif *mt7996_pci_get_hif2(u32 idx)\n 33:\t{\n 34:\t\tstruct mt7996_hif *hif;\n 35:\t\tu32 val;\n 36:\t\n 37:\t\tspin_lock_bh(\u0026hif_lock);\n 38:\t\n 39:\t\tlist_for_each_entry(hif, \u0026hif_list, list) {\n 40:\t\t\tval = readl(hif-\u003eregs + MT_PCIE_RECOG_ID);\n 41:\t\t\tval \u0026= MT_PCIE_RECOG_ID_MASK;\n 42:\t\t\tif (val != idx)\n 43:\t\t\t\tcontinue;\n 44:\t\n 45:\t\t\tget_device(hif-\u003edev);\n 46:\t\t\tgoto out;\n 47:\t\t}\n 48:\t\thif = NULL;\n 49:\t\n 50:\tout:\n"
} |
| 9/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13570 output: 39 thoughts: 278 Thoughts: **My Assessment of MT7996 Reachability in Virtualized Environments** Okay, so I need to figure out if I can actually interact with this MT7996 chip in a standard virtualized setup, like QEMU or Google Compute Engine. I need to be sure before I invest time down this path. Wait, section 2 of the documentation... it's saying certain hardware is inherently unreachable. Specifically, things like vendor-specific PCIe switches, specialized network interface cards, and GPU drivers – things that depend on the physical ASIC or a specific PCIe card that QEMU doesn't emulate. Right, that makes sense. So, *this* got me thinking... what about vendor-specific wireless cards? Ah, MT7996 is a MediaTek WiFi 7 PCIe card. Is QEMU actually emulating MediaTek's MT7996, MT7992 or MT7990 chips? Hold on... no, that's it, QEMU doesn't emulate it! Okay, new angle. Can I get around this by using USB emulation? Is there a USB variant or some means to connect it over USB? I need to check if the MT7996 even has a USB driver. The plan is to look through the drivers and see if there is any support. Let's start with searching the relevant driver directory – that would be `drivers/net/wireless/mediatek/mt76`. Let's grep for mt7996 there! |
| 10/2 | 2026/10/03 11:56 | tool | grepper |
0mError:no matches Args: {
"Expression": "usb",
"PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7996"
}Results: {
"error": "no matches"
} |
| 11/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14221 output: 39 thoughts: 62 Thoughts: Okay, here's my summary, tailored to my expert perspective: **Investigating Thermal Initialization in the MT7996 Wireless Driver** Right, so I'm looking into the MT7996 wireless driver, and the first thing I did was search the `drivers/net/wireless/mediatek/mt76/mt7996` directory for any mention of "usb". Nothing there, which is what I expected given my understanding of the architecture. Now, I need to understand how the thermal management is handled for this chipset. My next step is to determine how `mt7996_thermal_init` is called. I'll need to see if other drivers might be leveraging this initialization function, or if other files within the `mt7996` directory are using it. Knowing this, I can start to understand the complete thermal setup. |
| 12/2 | 2026/10/03 11:56 | tool | grepper |
0mArgs:{
"Expression": "mt7996_thermal",
"PathPrefix": "drivers/net/wireless/mediatek/mt76"
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7996/init.c=84=static const struct wiphy_iftype_ext_capab iftypes_ext_capa[] = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-105-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:106:static ssize_t mt7996_thermal_temp_show(struct device *dev,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-107-\t\t\t\t\tstruct device_attribute *attr,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-131-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:132:static ssize_t mt7996_thermal_temp_store(struct device *dev,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-133-\t\t\t\t\t struct device_attribute *attr,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-167-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:168:static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7996_thermal_temp, 0);\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:169:static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7996_thermal_temp, 1);\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:170:static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7996_thermal_temp, 2);\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:171:static SENSOR_DEVICE_ATTR_RO(throttle1, mt7996_thermal_temp, 3);\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-172-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c=182=static int\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:183:mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-184-\t\t\t\t unsigned long *state)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c=191=static int\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:192:mt7996_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-193-\t\t\t\t unsigned long *state)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c=202=static int\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:203:mt7996_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-204-\t\t\t\t unsigned long state)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-230-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:231:static const struct thermal_cooling_device_ops mt7996_thermal_ops = {\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:232:\t.get_max_state = mt7996_thermal_get_max_throttle_state,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:233:\t.get_cur_state = mt7996_thermal_get_cur_throttle_state,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:234:\t.set_cur_state = mt7996_thermal_set_cur_throttle_state,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-235-};\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-236-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:237:static int mt7996_thermal_get_temp(struct thermal_zone_device *tz, int *temp)\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-238-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c=252=static const struct thermal_zone_device_ops mt7996_tz_ops = {\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:253:\t.get_temp = mt7996_thermal_get_temp,\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-254-};\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c=256=static void mt7996_unregister_thermal(struct mt7996_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-274-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:275:static int mt7996_thermal_init(struct mt7996_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-276-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-289-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:290:\tcdev = thermal_cooling_device_register(name, phy, \u0026mt7996_thermal_ops);\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-291-\tif (!IS_ERR(cdev)) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c=1781=int mt7996_register_device(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-1825-\tmt7996_for_each_phy(dev, phy)\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:1826:\t\tmt7996_thermal_init(phy);\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-1827-\n"
} |
| 13/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 16400 output: 41 thoughts: 50 Thoughts: Here's my thought process, as if I were considering this code: **Analyzing the mt7996 Thermal Initialization** Okay, so `mt7996_thermal_init` is called, based on the code's comment, specifically within `mt7996_register_device()`. That's the only place it's supposed to be called. That's a strong hint for debugging or analysis. I need to understand the lifecycle. Now, where *is* `mt7996_register_device()` itself called? I need to track down the call chain to truly understand when and how this thermal initialization happens. Time for a quick grep through the codebase to find all instances of `mt7996_register_device()`. That's the next logical step. I need to see the context in which that function is used. |
| 14/2 | 2026/10/03 11:56 | tool | grepper |
0mArgs:{
"Expression": "mt7996_register_device",
"PathPrefix": "drivers/net/wireless/mediatek/mt76"
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7996/init.c=1766=void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-1780-\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c:1781:int mt7996_register_device(struct mt7996_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7996/init.c-1782-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h=679=u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif_link *link);\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h:680:int mt7996_register_device(struct mt7996_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h-681-void mt7996_unregister_device(struct mt7996_dev *dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c=99=static int mt7996_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c-194-\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c:195:\tret = mt7996_register_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c-196-\tif (ret)\n"
} |
| 15/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 17203 output: 42 thoughts: 139 Thoughts: Here's my thought process, as if I were analyzing this code: **Deep Dive into mt7996_register_device Callers** Okay, so `mt7996_register_device` is only called from `mt7996_pci_probe`. That's the initial assertion, and it's something I need to verify thoroughly. I'm going to quickly confirm this assumption, and then I'm going to dig deeper into the context of that single call. No point running around in circles here. Right, so that function lives in `pci.c`, which makes sense because we are talking about a PCI device. Let's see... `mt7996_pci_probe` itself is a PCI driver *probe* function. Now let's just make sure, let's look through `pci.c` surrounding that probe function. It's a PCI probe, so let's make sure there aren't any other subtleties going on here. |
| 16/2 | 2026/10/03 11:56 | tool | grepper |
0mArgs:{
"Expression": "mt7996_pci_driver",
"PathPrefix": "drivers/net/wireless/mediatek/mt76"
}Results: {
"Output": "drivers/net/wireless/mediatek/mt76/mt7996/mmio.c=885=static int __init mt7996_init(void)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c-892-\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c:893:\tret = pci_register_driver(\u0026mt7996_pci_driver);\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c-894-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c=900=static void __exit mt7996_exit(void)\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c-901-{\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c:902:\tpci_unregister_driver(\u0026mt7996_pci_driver);\ndrivers/net/wireless/mediatek/mt76/mt7996/mmio.c-903-\tpci_unregister_driver(\u0026mt7996_hif_driver);\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h=670=extern const struct ieee80211_ops mt7996_ops;\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h:671:extern struct pci_driver mt7996_pci_driver;\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h-672-extern struct pci_driver mt7996_hif_driver;\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c=244=struct pci_driver mt7996_hif_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c-250-\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c:251:struct pci_driver mt7996_pci_driver = {\ndrivers/net/wireless/mediatek/mt76/mt7996/pci.c-252-\t.name\t\t= KBUILD_MODNAME,\n"
} |
| 17/2 | 2026/10/03 11:56 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 18259 output: 123 thoughts: 975 Thoughts: **MT7996 Thermal Driver Analysis for Fuzzing Eligibility** Okay, so I've got this `mt7996` driver, which from what I see, is a purely PCIe-based thing. It's tied to MediaTek's PCI device IDs, specifically the `MT7996`, `MT7992`, and `MT7990` IDs. That immediately flags something. Does QEMU emulate this hardware? Nope. I already know QEMU doesn't do a thing with these specific MediaTek PCIe cards. Now, let's go back and work through the negative criteria checklist. Specifically, I'm looking for "structurally unreachable hardware," meaning vendor-specific PCIe stuff that requires a real ASIC/PCIe card, which isn't emulated in standard QEMU. That's exactly what this is. This is a MediaTek WiFi chip and therefore is not emulated. So, is there any chance of tricking it into activating through some virtual bus or software emulation? Could something like `mac80211_hwsim` get it going? Nah, that's a separate driver and wouldn't bind to the `mt7996` driver. The driver is very explicit about it's hardware requirements and binds only to those MediaTek PCI devices. There's nothing in standard QEMU that provides that. The kernel's `thermal_of_zone_register` wouldn't help either because that requires the hardware to be present for the module to probe. `mt7996_pci_probe` won't ever be called, so the initialization or registration of any thermal management code won't happen. Alright, time to apply the "REACHABILITY IS THE PRIMARY GATE" principle from the Core Triage Philosophy. Fuzzing can only find bugs in code that *can* actually run in standard virtualized environments. Since this is PCIe and not emulated, this code is structurally unreachable. Doesn't matter if it has assertions or complex logic. I'm going to have to say `WorthFuzzing` is false here. So the reasoning becomes straightforward. This patch is modifying thermal management routines in the MediaTek MT7996 wireless driver (`mt7996_thermal_init`, `mt7996_thermal_get_temp`, `mt7996_unregister_thermal`). The MT7996 driver depends on vendor-specific MediaTek PCIe Wi-Fi 7 devices. These devices are *not* emulated in any standard virtualized fuzzing setups (QEMU, GCE, etc.). That makes this code structurally unreachable. Therefore, it's not a good candidate for fuzzing. |
| 18/2 | 2026/10/03 11:56 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the thermal zone registration and readout logic in the MediaTek MT7996 wireless network driver. MT7996 is a PCIe-based Wi-Fi device driver that requires physical MediaTek hardware (MT7996/MT7992/MT7990) not emulated in standard virtualized environments (QEMU/GCE). Consequently, the modified code paths are structurally unreachable during fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the thermal zone registration and readout logic in the MediaTek MT7996 wireless network driver. MT7996 is a PCIe-based Wi-Fi device driver that requires physical MediaTek hardware (MT7996/MT7992/MT7990) not emulated in standard virtualized environments (QEMU/GCE). Consequently, the modified code paths are structurally unreachable during fuzzing.",
"WorthFuzzing": false
} |
| 19/1 | 2026/10/03 11:56 | 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) |
|---|