AI Trajectory


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

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies the MediaTek MT7915 PCIe Wi-Fi driver (mt7915) to fix a thermal zone unregistration issue. This is a vendor-specific PCIe driver that requires physical hardware to initialize (e.g., passing driver ownership checks, firmware loading, and MCU communication). Since this hardware is not emulated in standard QEMU, the modified code paths in `mt7915_thermal_init` and `mt7915_unregister_thermal` are impossible to reach in virtualized fuzzing environments.",
  "WorthFuzzing": false
}

1/1 2026/08/10 14:35 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 0de402001ee6ce5b39bacc8e86aeb9fd0fb661ec\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Mon Aug 10 14:35:08 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c\nindex ca46a203aa48b..5fe70dc822ebb 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c\n@@ -200,6 +200,9 @@ static void mt7915_unregister_thermal(struct mt7915_phy *phy)\n {\n \tstruct wiphy *wiphy = phy-\u003emt76-\u003ehw-\u003ewiphy;\n \n+\tif (phy-\u003etzone)\n+\t\tdevm_thermal_of_zone_unregister(phy-\u003edev-\u003emt76.dev, phy-\u003etzone);\n+\n \tif (!phy-\u003ecdev)\n \t\treturn;\n \n@@ -213,6 +216,7 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)\n \tstruct thermal_cooling_device *cdev;\n \tstruct device *hwmon;\n \tconst char *name;\n+\tint ret;\n \n \tname = devm_kasprintf(\u0026wiphy-\u003edev, GFP_KERNEL, \"mt7915_%s\",\n \t\t\t      wiphy_name(wiphy));\n@@ -238,8 +242,8 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)\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: %ld\\n\",\n-\t\t\t\t PTR_ERR(phy-\u003etzone));\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@@ -248,7 +252,11 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)\n \n \thwmon = devm_hwmon_device_register_with_groups(\u0026wiphy-\u003edev, name, phy,\n \t\t\t\t\t\t       mt7915_hwmon_groups);\n-\treturn PTR_ERR_OR_ZERO(hwmon);\n+\tret = PTR_ERR_OR_ZERO(hwmon);\n+\tif (ret)\n+\t\tmt7915_unregister_thermal(phy);\n+\n+\treturn ret;\n }\n \n static void mt7915_led_set_config(struct led_classdev *led_cdev,\n"
}

2/1 2026/08/10 14:35 agent patch-evaluator
2m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the MediaTek MT7915 PCIe Wi-Fi driver (mt7915) to fix a thermal zone unregistration issue. This is a vendor-specific PCIe driver that requires physical hardware to initialize (e.g., passing driver ownership checks, firmware loading, and MCU communication). Since this hardware is not emulated in standard QEMU, the modified code paths in `mt7915_thermal_init` and `mt7915_unregister_thermal` are impossible to reach in virtualized fuzzing environments.",
  "WorthFuzzing": false
}

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

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

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

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

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


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

Prompt:
For your convenience, here is the diff of the changes:
commit 0de402001ee6ce5b39bacc8e86aeb9fd0fb661ec
Author: syz-cluster <triage@syzkaller.com>
Date:   Mon Aug 10 14:35:08 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index ca46a203aa48b..5fe70dc822ebb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -200,6 +200,9 @@ static void mt7915_unregister_thermal(struct mt7915_phy *phy)
 {
 	struct wiphy *wiphy = phy->mt76->hw->wiphy;
 
+	if (phy->tzone)
+		devm_thermal_of_zone_unregister(phy->dev->mt76.dev, phy->tzone);
+
 	if (!phy->cdev)
 		return;
 
@@ -213,6 +216,7 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
 	struct thermal_cooling_device *cdev;
 	struct device *hwmon;
 	const char *name;
+	int ret;
 
 	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7915_%s",
 			      wiphy_name(wiphy));
@@ -238,8 +242,8 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
 	if (IS_ERR(phy->tzone)) {
 		if (PTR_ERR(phy->tzone) != -ENODEV)
 			dev_warn(phy->dev->mt76.dev,
-				 "failed to register thermal zone: %ld\n",
-				 PTR_ERR(phy->tzone));
+				 "failed to register thermal zone %d: %ld\n",
+				 phy->mt76->band_idx, PTR_ERR(phy->tzone));
 		phy->tzone = NULL;
 	}
 
@@ -248,7 +252,11 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
 
 	hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
 						       mt7915_hwmon_groups);
-	return PTR_ERR_OR_ZERO(hwmon);
+	ret = PTR_ERR_OR_ZERO(hwmon);
+	if (ret)
+		mt7915_unregister_thermal(phy);
+
+	return ret;
 }
 
 static void mt7915_led_set_config(struct led_classdev *led_cdev,

3/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 2495
							output: 44
							thoughts: 269
						

Thoughts:
**Analyzing a Wi-Fi Driver Patch**

Okay, so I'm looking at this patch for `drivers/net/wireless/mediatek/mt76/mt7915/init.c`. It's pretty straightforward, it's modifying the thermal management, which is always interesting. Specifically, it's updating the `mt7915_unregister_thermal` function to unregister the thermal zone (`phy->tzone`) using `devm_thermal_of_zone_unregister` if that zone exists. That's good practice. And then, in `mt7915_thermal_init`, if `devm_hwmon_device_register_with_groups` fails, it now calls `mt7915_unregister_thermal(phy)`. Makes sense, cleanup is crucial on initialization failures. Oh, and it's also tweaking a warning message, probably for better clarity.

But wait a second... `mt7915`... that's a MediaTek Wi-Fi driver, isn't it? Right, it's for those MT7915, MT7986, MT7916, and MT7981 chipsets. I seem to recall it being a PCIe driver. Let me just confirm that. Yes, it's a PCIe driver. That throws up a bit of a flag for fuzzing considerations. PCIe Wi-Fi drivers, especially the vendor-specific ones like this, aren't usually the easiest to fuzz directly in something like QEMU. They often rely on specific hardware interactions that are tough to emulate. Unless they have some dedicated emulation support, or happen to be USB/SDIO drivers which are a bit more amenable to emulation, fuzzing PCIe drivers is a challenge. So, I need to check how exactly it communicates with the device, the nature of the interface will determine a more suitable method.



4/2 2026/08/10 14:35 tool grepper
0m Args:
{
  "Expression": "mt7915",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 5731 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile-2-\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile:3:obj-$(CONFIG_MT7915E) += mt7915e.o\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile-4-\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile:5:mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \\\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile-6-\t     debugfs.o mmio.o\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile-7-\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile:8:mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile:9:mt7915e-$(CONFIG_MT798X_WMAC) += soc.o\ndrivers/net/wireless/mediatek/mt76/mt7915/Makefile:10:mt7915e-$(CONFIG_DEV_COREDUMP) += coredump.o\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c=12=MODULE_PARM_DESC(coredump_memdump, \"Optional ability to dump firmware memory\");\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-13-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:14:static const struct mt7915_mem_region mt7915_mem_regions[] = {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-15-\t{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-21-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:22:static const struct mt7915_mem_region mt7916_mem_regions[] = {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-23-\t{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-54-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:55:static const struct mt7915_mem_region mt798x_mem_regions[] = {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-56-\t{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-87-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:88:const struct mt7915_mem_region*\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:89:mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-90-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-92-\tcase 0x7915:\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:93:\t\t*num = ARRAY_SIZE(mt7915_mem_regions);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:94:\t\treturn \u0026mt7915_mem_regions[0];\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-95-\tcase 0x7981:\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-106-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:107:static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-108-{\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:109:\tconst struct mt7915_mem_region *mem_region;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-110-\tsize_t size = 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-113-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:114:\tmem_region = mt7915_coredump_get_mem_layout(dev, \u0026num);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-115-\tif (!mem_region)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-123-\t/* reserve space for the headers */\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:124:\tsize += num * sizeof(struct mt7915_mem_hdr);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-125-\t/* make sure it is aligned 4 bytes for debug message print out */\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-130-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:131:struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-132-{\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:133:\tstruct mt7915_crash_data *crash_data = dev-\u003ecoredump.crash_data;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-134-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c=143=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:144:mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-145-\t\t\t bool *exception)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-150-\tstate = (u32)mt76_get_field(dev, MT_FW_ASSERT_STAT, GENMASK(7, 0));\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:151:\tcount = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-152-\t\t(u32)mt76_get_field(dev, MT_FW_EXCEPT_COUNT, GENMASK(15, 8)) :\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c=166=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:167:mt7915_coredump_fw_trace(struct mt7915_dev *dev, struct mt7915_coredump *dump,\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-168-\t\t\t bool exception)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-174-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:175:\tn = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-176-\t    (u32)mt76_get_field(dev, base, GENMASK(7, 0)) :\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-180-\tirq = mt76_rr(dev, base + 0x8);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:181:\tn = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-182-\t    FIELD_GET(GENMASK(7, 0), irq) : FIELD_GET(GENMASK(23, 16), irq);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-185-\tsch = mt76_rr(dev, MT_FW_SCHED_INFO);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:186:\tn = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-187-\t    FIELD_GET(GENMASK(7, 0), sch) : FIELD_GET(GENMASK(15, 8), sch);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-193-\t\t/* sched trace */\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:194:\t\tn = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-195-\t\t    FIELD_GET(GENMASK(15, 8), sch) : FIELD_GET(GENMASK(7, 0), sch);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-201-\t\tfor (y = dump-\u003esched_info_idx, i = 0; i \u003c n; i++, y++) {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:202:\t\t\tmt7915_memcpy_fromio(dev, dump-\u003esched, base + 0xc + y * 12,\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-203-\t\t\t\t\t     sizeof(dump-\u003esched));\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-207-\t\t/* irq trace */\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:208:\t\tn = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-209-\t\t    FIELD_GET(GENMASK(15, 8), irq) : FIELD_GET(GENMASK(7, 0), irq);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-215-\t\tfor (y = dump-\u003eirq_info_idx, i = 0; i \u003c n; i++, y++) {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:216:\t\t\tmt7915_memcpy_fromio(dev, dump-\u003eirq, base + 0x4 + y * 16,\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-217-\t\t\t\t\t     sizeof(dump-\u003eirq));\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c=223=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:224:mt7915_coredump_fw_stack(struct mt7915_dev *dev, struct mt7915_coredump *dump,\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-225-\t\t\t bool exception)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c=244=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:245:mt7915_coredump_fw_task(struct mt7915_dev *dev, struct mt7915_coredump *dump)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-246-{\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:247:\tu32 offs = is_mt7915(\u0026dev-\u003emt76) ? 0xe0 : 0x170;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-248-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c=268=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:269:mt7915_coredump_fw_context(struct mt7915_dev *dev, struct mt7915_coredump *dump)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-270-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-279-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:280:\t\tidx = is_mt7915(\u0026dev-\u003emt76) ?\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-281-\t\t      (u32)mt76_get_field(dev, MT_FW_CIRQ_IDX, GENMASK(31, 16)) :\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-301-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:302:static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-303-{\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:304:\tstruct mt7915_crash_data *crash_data = dev-\u003ecoredump.crash_data;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:305:\tstruct mt7915_coredump *dump;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:306:\tstruct mt7915_coredump_mem *dump_mem;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-307-\tsize_t len, sofar = 0, hdr_len = sizeof(*dump);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-326-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:327:\tdump = (struct mt7915_coredump *)(buf);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-328-\tdump-\u003elen = len;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-340-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:341:\tmt7915_coredump_fw_state(dev, dump, \u0026exception);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:342:\tmt7915_coredump_fw_trace(dev, dump, exception);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:343:\tmt7915_coredump_fw_task(dev, dump);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:344:\tmt7915_coredump_fw_context(dev, dump);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:345:\tmt7915_coredump_fw_stack(dev, dump, exception);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-346-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-347-\t/* gather memory content */\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:348:\tdump_mem = (struct mt7915_coredump_mem *)(buf + sofar);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-349-\tdump_mem-\u003elen = crash_data-\u003ememdump_buf_len;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-358-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:359:int mt7915_coredump_submit(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-360-{\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:361:\tstruct mt7915_coredump *dump;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-362-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:363:\tdump = mt7915_coredump_build(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-364-\tif (!dump) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-373-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:374:int mt7915_coredump_register(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-375-{\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:376:\tstruct mt7915_crash_data *crash_data;\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-377-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-384-\tif (coredump_memdump) {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:385:\t\tcrash_data-\u003ememdump_buf_len = mt7915_coredump_get_mem_size(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-386-\t\tif (!crash_data-\u003ememdump_buf_len)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-399-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c:400:void mt7915_coredump_unregister(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.c-401-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-6-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:7:#include \"mt7915.h\"\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-8-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h=9=struct trace {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-13-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:14:struct mt7915_coredump {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-15-\tchar magic[16];\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-79-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:80:struct mt7915_coredump_mem {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-81-\tu32 len;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-84-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:85:struct mt7915_mem_hdr {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-86-\tu32 start;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-90-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:91:struct mt7915_mem_region {\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-92-\tu32 start;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-99-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:100:const struct mt7915_mem_region *\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:101:mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:102:struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:103:int mt7915_coredump_submit(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:104:int mt7915_coredump_register(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:105:void mt7915_coredump_unregister(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-106-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-108-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:109:static inline const struct mt7915_mem_region *\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:110:mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-111-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-114-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:115:static inline int mt7915_coredump_submit(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-116-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-119-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:120:static inline struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-121-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-124-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:125:static inline int mt7915_coredump_register(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-126-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-129-\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h:130:static inline void mt7915_coredump_unregister(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/coredump.h-131-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-4-#include \u003clinux/relay.h\u003e\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:5:#include \"mt7915.h\"\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-6-#include \"eeprom.h\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=21=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:22:mt7915_implicit_txbf_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-23-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:24:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-25-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-30-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:31:\treturn mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-32-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=34=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:35:mt7915_implicit_txbf_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-36-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:37:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-38-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-43-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:44:DEFINE_DEBUGFS_ATTRIBUTE(fops_implicit_txbf, mt7915_implicit_txbf_get,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:45:\t\t\t mt7915_implicit_txbf_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-46-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=48=static ssize_t\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:49:mt7915_sys_recovery_set(struct file *file, const char __user *user_buf,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-50-\t\t\tsize_t count, loff_t *ppos)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-51-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:52:\tstruct mt7915_phy *phy = file-\u003eprivate_data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:53:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-54-\tbool band = phy-\u003emt76-\u003eband_idx;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-74-\tcase SER_QUERY:\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:75:\t\tret = mt7915_mcu_set_ser(dev, 0, 0, band);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-76-\t\tbreak;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-82-\tcase SER_SET_RECOVER_L3_BF:\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:83:\t\tret = mt7915_mcu_set_ser(dev, SER_ENABLE, BIT(val), band);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-84-\t\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-86-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:87:\t\tret = mt7915_mcu_set_ser(dev, SER_RECOVER, val, band);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-88-\t\tbreak;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-92-\t\tmt76_set(dev, MT_WFDMA0_MCU_HOST_INT_ENA, MT_MCU_CMD_WDT_MASK);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:93:\t\tret = mt7915_mcu_set_ser(dev, 1, 3, band);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-94-\t\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-97-\t\tdev-\u003erecovery.state |= MT_MCU_CMD_WDT_MASK;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:98:\t\tmt7915_reset(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-99-\t\tbreak;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=113=static ssize_t\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:114:mt7915_sys_recovery_get(struct file *file, char __user *user_buf,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-115-\t\t\tsize_t count, loff_t *ppos)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-116-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:117:\tstruct mt7915_phy *phy = file-\u003eprivate_data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:118:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-119-\tchar *buff;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-192-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:193:static const struct file_operations mt7915_sys_recovery_ops = {\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:194:\t.write = mt7915_sys_recovery_set,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:195:\t.read = mt7915_sys_recovery_get,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-196-\t.open = simple_open,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=200=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:201:mt7915_radar_trigger(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-202-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-204-#define RADAR_BACKGROUND\t2\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:205:\tstruct mt7915_phy *phy = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:206:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-207-\tint rdd_idx;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-216-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:217:\trdd_idx = mt7915_get_rdd_idx(phy, val == RADAR_BACKGROUND);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-218-\tif (rdd_idx \u003c 0) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=227=DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:228:\t\t\t mt7915_radar_trigger, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-229-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=230=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:231:mt7915_muru_debug_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-232-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:233:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-234-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-235-\tdev-\u003emuru_debug = val;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:236:\tmt7915_mcu_muru_debug_set(dev, dev-\u003emuru_debug);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-237-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=241=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:242:mt7915_muru_debug_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-243-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:244:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-245-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-250-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:251:DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_debug, mt7915_muru_debug_get,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:252:\t\t\t mt7915_muru_debug_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-253-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:254:static int mt7915_muru_stats_show(struct seq_file *file, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-255-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:256:\tstruct mt7915_phy *phy = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:257:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-258-\tstatic const char * const dl_non_he_type[] = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-280-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:281:\tret = mt7915_mcu_muru_debug_get(phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-282-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-439-}\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:440:DEFINE_SHOW_ATTRIBUTE(mt7915_muru_stats);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-441-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=442=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:443:mt7915_rdd_monitor(struct seq_file *s, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-444-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:445:\tstruct mt7915_dev *dev = dev_get_drvdata(s-\u003eprivate);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-446-\tstruct cfg80211_chan_def *chandef = \u0026dev-\u003erdd2_chandef;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-451-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:452:\tif (!mt7915_eeprom_has_background_radar(dev)) {\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-453-\t\tseq_puts(s, \"no background radar capability\\n\");\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=494=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:495:mt7915_fw_debug_wm_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-496-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:497:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-498-\tenum {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-518-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:519:\tret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, val);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-520-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-528-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:529:\t\tret = mt7915_mcu_fw_dbg_ctrl(dev, debug, val);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-530-\t\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=548=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:549:mt7915_fw_debug_wm_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-550-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:551:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-552-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-557-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:558:DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wm, mt7915_fw_debug_wm_get,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:559:\t\t\t mt7915_fw_debug_wm_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-560-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=561=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:562:mt7915_fw_debug_wa_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-563-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:564:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-565-\tint ret;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-568-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:569:\tret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev-\u003efw.debug_wa);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-570-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-572-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:573:\tret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-574-\t\t\t\tMCU_WA_PARAM_PDMA_RX, !!dev-\u003efw.debug_wa, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=582=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:583:mt7915_fw_debug_wa_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-584-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:585:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-586-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-591-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:592:DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wa, mt7915_fw_debug_wa_get,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:593:\t\t\t mt7915_fw_debug_wa_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-594-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=619=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:620:mt7915_fw_debug_bin_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-621-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-625-\t};\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:626:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-627-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-637-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:638:\treturn mt7915_fw_debug_wm_set(dev, dev-\u003efw.debug_wm);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-639-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=641=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:642:mt7915_fw_debug_bin_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-643-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:644:\tstruct mt7915_dev *dev = data;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-645-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-650-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:651:DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_bin, mt7915_fw_debug_bin_get,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:652:\t\t\t mt7915_fw_debug_bin_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-653-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=654=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:655:mt7915_fw_util_wm_show(struct seq_file *file, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-656-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:657:\tstruct mt7915_dev *dev = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-658-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-672-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:673:DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wm);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-674-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=675=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:676:mt7915_fw_util_wa_show(struct seq_file *file, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-677-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:678:\tstruct mt7915_dev *dev = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-679-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-682-\tif (dev-\u003efw.debug_wa)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:683:\t\treturn mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(QUERY),\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-684-\t\t\t\t\t MCU_WA_PARAM_CPU_UTIL, 0, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-688-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:689:DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-690-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=691=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:692:mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-693-\t\t\t   struct seq_file *file)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-694-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:695:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-696-\tbool ext_phy = phy != \u0026dev-\u003ephy;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=722=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:723:mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-724-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=769=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:770:mt7915_tx_stats_show(struct seq_file *file, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-771-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:772:\tstruct mt7915_phy *phy = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:773:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-774-\tstruct mt76_mib_stats *mib = \u0026phy-\u003emib;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-778-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:779:\tmt7915_ampdu_stat_read_phy(phy, file);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:780:\tmt7915_mac_update_stats(phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:781:\tmt7915_txbf_stat_read_phy(phy, file);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-782-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-799-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:800:DEFINE_SHOW_ATTRIBUTE(mt7915_tx_stats);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-801-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=802=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:803:mt7915_hw_queue_read(struct seq_file *s, u32 size,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-804-\t\t     const struct hw_queue_map *map)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-805-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:806:\tstruct mt7915_phy *phy = s-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:807:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-808-\tu32 i, val;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=833=static void\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:834:mt7915_sta_hw_queue_read(void *data, struct ieee80211_sta *sta)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-835-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:836:\tstruct mt7915_sta *msta = (struct mt7915_sta *)sta-\u003edrv_priv;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:837:\tstruct mt7915_dev *dev = msta-\u003evif-\u003ephy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-838-\tstruct seq_file *s = data;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=861=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:862:mt7915_hw_queues_show(struct seq_file *file, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-863-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:864:\tstruct mt7915_phy *phy = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:865:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-866-\tstatic const struct hw_queue_map ple_queue_map[] = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-914-\tseq_puts(file, \"PLE non-empty queue info:\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:915:\tmt7915_hw_queue_read(file, ARRAY_SIZE(ple_queue_map),\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-916-\t\t\t     \u0026ple_queue_map[0]);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-919-\tieee80211_iterate_stations_atomic(phy-\u003emt76-\u003ehw,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:920:\t\t\t\t\t  mt7915_sta_hw_queue_read, file);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-921-\t/* pse queue */\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-922-\tseq_puts(file, \"PSE non-empty queue info:\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:923:\tmt7915_hw_queue_read(file, ARRAY_SIZE(pse_queue_map),\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-924-\t\t\t     \u0026pse_queue_map[0]);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-928-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:929:DEFINE_SHOW_ATTRIBUTE(mt7915_hw_queues);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-930-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=931=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:932:mt7915_xmit_queues_show(struct seq_file *file, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-933-{\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:934:\tstruct mt7915_phy *phy = file-\u003eprivate;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:935:\tstruct mt7915_dev *dev = phy-\u003edev;\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-936-\tstruct {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-961-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:962:DEFINE_SHOW_ATTRIBUTE(mt7915_xmit_queues);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-963-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:964:#define mt7915_txpower_puts(rate)\t\t\t\t\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-965-({\t\t\t\t\t\t\t\t\t\t\\\n\n"
}

5/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 20014
							output: 48
							thoughts: 768
						

Thoughts:
**Analyzing the Patch for Worthiness**

Okay, so I'm looking at this patch, and the first thing I notice is that it's clearly related to the thermal management within the `mt7915` PCIe driver.  The output indicates that it's part of the `mt7915e-y` module, so it is a PCIe driver. The patch seems to be addressing an error handling path, specifically related to thermal zone registration and unregistration.  It looks like there was a potential resource leak if the thermal zone registration failed, and this patch aims to clean up properly in that scenario.

Now, my initial thought goes to fuzzing.  Could this be a potential area for fuzzing? I see that it's a MediaTek Wi-Fi driver, so it is a vendor-specific driver.  Then the question is can this driver be emulated in standard QEMU? Let's consult the guidelines:  "Return WorthFuzzing=false if the patch only contains: - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU."

Since `mt7915` is a vendor-specific PCIe Wi-Fi driver, and, to my knowledge, requires actual hardware I think I will need to exclude it from fuzzing, unless I can find some software emulation.  I'll double check to see if there is any mention of software emulation, but I'm leaning towards not fuzzing this one.



6/2 2026/08/10 14:35 tool grepper
0m Args:
{
  "Expression": "mt7915",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/pci.c"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/pci.c-10-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:11:#include \"mt7915.h\"\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-12-#include \"mac.h\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c=17=static u32 hif_idx;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-18-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:19:static const struct pci_device_id mt7915_pci_device_table[] = {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-20-\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7915) },\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-24-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:25:static const struct pci_device_id mt7915_hif_device_table[] = {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-26-\t{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7916) },\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-30-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:31:static struct mt7915_hif *mt7915_pci_get_hif2(u32 idx)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-32-{\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:33:\tstruct mt7915_hif *hif;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-34-\tu32 val;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-55-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:56:static void mt7915_put_hif2(struct mt7915_hif *hif)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-57-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-63-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:64:static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-65-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-80-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:81:\treturn mt7915_pci_get_hif2(hif_idx);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-82-}\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-83-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:84:static int mt7915_pci_hif2_probe(struct pci_dev *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-85-{\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:86:\tstruct mt7915_hif *hif;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-87-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-102-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:103:static int mt7915_pci_probe(struct pci_dev *pdev,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-104-\t\t\t    const struct pci_device_id *id)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-105-{\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:106:\tstruct mt7915_hif *hif2 = NULL;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:107:\tstruct mt7915_dev *dev;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-108-\tstruct mt76_dev *mdev;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-128-\tif (id-\u003edevice == 0x7916 || id-\u003edevice == 0x790a)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:129:\t\treturn mt7915_pci_hif2_probe(pdev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-130-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:131:\tdev = mt7915_mmio_probe(\u0026pdev-\u003edev, pcim_iomap_table(pdev)[0],\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-132-\t\t\t\tid-\u003edevice);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-136-\tmdev = \u0026dev-\u003emt76;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:137:\tmt7915_wfsys_reset(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-138-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:139:\tret = mt7915_mmio_wed_init(dev, pdev, true, \u0026irq);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-140-\tif (ret \u003c 0)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-143-\tif (!ret) {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:144:\t\thif2 = mt7915_pci_init_hif2(pdev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-145-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-147-\t\tif (ret \u003c 0) {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:148:\t\t\tmt7915_put_hif2(hif2);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-149-\t\t\tgoto free_device;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-154-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:155:\tret = devm_request_irq(mdev-\u003edev, irq, mt7915_irq_handler,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-156-\t\t\t       IRQF_SHARED, KBUILD_MODNAME, dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-157-\tif (ret) {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:158:\t\tmt7915_put_hif2(hif2);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-159-\t\tgoto free_wed_or_irq_vector;\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-169-\t\t/* master switch of PCIe tnterrupt enable */\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:170:\t\tif (is_mt7915(mdev))\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-171-\t\t\tmt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-175-\t\tret = devm_request_irq(mdev-\u003edev, dev-\u003ehif2-\u003eirq,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:176:\t\t\t\t       mt7915_irq_handler, IRQF_SHARED,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-177-\t\t\t\t       KBUILD_MODNAME \"-hif\", dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-181-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:182:\tret = mt7915_register_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-183-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-205-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:206:static void mt7915_hif_remove(struct pci_dev *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-207-{\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:208:\tstruct mt7915_hif *hif = pci_get_drvdata(pdev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-209-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-212-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:213:static void mt7915_pci_remove(struct pci_dev *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-214-{\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-215-\tstruct mt76_dev *mdev;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:216:\tstruct mt7915_dev *dev;\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-217-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-218-\tmdev = pci_get_drvdata(pdev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:219:\tdev = container_of(mdev, struct mt7915_dev, mt76);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:220:\tmt7915_put_hif2(dev-\u003ehif2);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:221:\tmt7915_unregister_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-222-}\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-223-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:224:struct pci_driver mt7915_hif_driver = {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-225-\t.name\t\t= KBUILD_MODNAME \"_hif\",\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:226:\t.id_table\t= mt7915_hif_device_table,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:227:\t.probe\t\t= mt7915_pci_probe,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:228:\t.remove\t\t= mt7915_hif_remove,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-229-};\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-230-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:231:struct pci_driver mt7915_pci_driver = {\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-232-\t.name\t\t= KBUILD_MODNAME,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:233:\t.id_table\t= mt7915_pci_device_table,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:234:\t.probe\t\t= mt7915_pci_probe,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:235:\t.remove\t\t= mt7915_pci_remove,\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-236-};\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-237-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:238:MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:239:MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-240-MODULE_FIRMWARE(MT7915_FIRMWARE_WA);\n"
}

7/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25296
							output: 48
							thoughts: 304
						

Thoughts:
**Analyzing the Virtualization of the mt7915 Wi-Fi Driver**

Okay, so the prompt is about the `mt7915` driver, and from the sound of it, the challenge is getting it to function in a virtualized environment. My initial thought is, this is a PCIe driver, right? Purely PCI, and that immediately rings alarm bells, because if it's dependent on a physical PCIe card, like those vendor-specific drivers for PCIe switches, SmartNICs, or GPUs (things like `mlxsw`, `pds_core`, `qed`, `ionic`, or `amdgpu`), standard QEMU won't be able to emulate it directly.

Wait, `mt7915` is a Wi-Fi driver, so it's a MediaTek PCIe Wi-Fi driver. And it’s not QEMU that emulates this. The question then becomes, is there any software emulation of it? Like, is there something similar to `mac80211_hwsim`? Ah, right, that's just a software simulator for `mac80211`, not a hardware emulator for the `mt7915`. So, given my understanding, the code paths within `mt7915` are likely unreachable in virtualized setups like Google Compute Engine or QEMU, at least not without some clever workarounds.

But, hold on, there might be a workaround. What if we could somehow probe the driver using a fake PCI device? Syzkaller has `syz_pci_device_add`, which can inject PCI config space, but that’s not true hardware emulation. In most cases, these drivers fail early during initialization, especially when they try to read or write to MMIO registers or wait for firmware.

So, the next step is to examine the driver initialization process. Let's see if the function `mt7915_thermal_init` is called during probe. This could be a good point to start figuring out if there's any chance of tricking it.



8/2 2026/08/10 14:35 tool grepper
0m Args:
{
  "Expression": "mt7915_thermal_init",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/init.c=199=static void mt7915_unregister_thermal(struct mt7915_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-212-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:213:static int mt7915_thermal_init(struct mt7915_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-214-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=730=mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-761-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:762:\tret = mt7915_thermal_init(phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-763-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=1258=int mt7915_register_device(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1296-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1297:\tret = mt7915_thermal_init(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1298-\tif (ret)\n"
}

9/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26594
							output: 48
							thoughts: 119
						

Thoughts:
Okay, here's my understanding, framed as my internal thought process:

**Diving into the MediaTek Wi-Fi Driver Initialization**

Alright, let's dissect this MediaTek PCIe Wi-Fi driver initialization sequence. From what I see, `mt7915_thermal_init` is the crucial function, and it's called from `mt7915_register_device` and `mt7915_register_ext_phy`. Now, `mt7915_register_device` itself is only called from `mt7915_pci_probe`. Considering this is a MediaTek PCIe Wi-Fi driver, I'm pretty certain we're dealing with a physical hardware dependency right from the start. We're going to need actual hardware present and functioning to even get past the early MMIO setup and firmware loading stages. The probing can't happen in a virtual environment. I'm going to quickly check the code to confirm if the firmware loading occurs before `mt7915_register_device` is called. That will be my first area to focus on.



10/2 2026/08/10 14:35 tool grepper
0m Args:
{
  "Expression": "mt7915_register_device",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/init.c=1247=static void mt7915_stop_hardware(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1257-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1258:int mt7915_register_device(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1259-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h=453=u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h-454-\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h:455:int mt7915_register_device(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h-456-void mt7915_unregister_device(struct mt7915_dev *dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c=103=static int mt7915_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-181-\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c:182:\tret = mt7915_register_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/pci.c-183-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c=1220=static int mt798x_wmac_probe(struct platform_device *pdev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1263-\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c:1264:\tret = mt7915_register_device(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1265-\tif (ret)\n"
}

11/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27703
							output: 49
							thoughts: 45
						

Thoughts:
**Digging Deeper into the MT7915 Registration**

Okay, hold on a minute. I just saw that `mt7915_register_device` function called from `mt798x_wmac_probe` in `soc.c`. That's interesting, I need to understand that connection more thoroughly. My initial focus was on the function's individual behavior, but now I'm seeing it's integrated with a bigger picture through that `soc.c` file. Right, let’s go check that specific `soc.c` file to see the context of that call and how the probe interacts with the registration process. Time to understand the broader implications here.



12/2 2026/08/10 14:35 tool grepper
0m Args:
{
  "Expression": "mt798x_wmac_probe",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/soc.c=1190=static int mt798x_wmac_init(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1219-\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c:1220:static int mt798x_wmac_probe(struct platform_device *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1221-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c=1295=struct platform_driver mt798x_wmac_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1299-\t},\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c:1300:\t.probe = mt798x_wmac_probe,\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1301-\t.remove = mt798x_wmac_remove,\n"
}

13/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28288
							output: 52
							thoughts: 102
						

Thoughts:
**Analyzing the mt798x_wmac_probe Function**

Okay, so `mt798x_wmac_probe` is the probe function for the `mt798x_wmac_driver` – that's the starting point. My mind immediately jumps to fuzzing opportunities. Can this platform driver, like many others, be a target for fuzzing? Syzkaller *should* be able to handle it if it can be brought up through device tree or some similar initialization method, and a quick check confirms that. However, I know from experience that vendor-specific Wi-Fi platform drivers often present a challenge. They tend to have those tight dependencies on specific hardware registers and the right firmware to actually initialize and work correctly.

Right, time to dig in. Let's see exactly what `mt798x_wmac_probe` is doing and what its key actions are. I need to understand what it expects and how it interacts with the hardware before I can assess the feasibility of effective fuzzing.



14/2 2026/08/10 14:35 tool grepper
0m Args:
{
  "Expression": "mt798x_wmac_probe",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/soc.c"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/soc.c=1190=static int mt798x_wmac_init(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1219-\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c:1220:static int mt798x_wmac_probe(struct platform_device *pdev)\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1221-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c=1295=struct platform_driver mt798x_wmac_driver = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1299-\t},\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c:1300:\t.probe = mt798x_wmac_probe,\ndrivers/net/wireless/mediatek/mt76/mt7915/soc.c-1301-\t.remove = mt798x_wmac_remove,\n"
}

15/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 29003
							output: 52
							thoughts: 16
						

Thoughts:
Okay, let's dive into `mt798x_wmac_probe`. I'm going to approach this with my usual methodical process. First, I want to get a high-level understanding. What's the main function's purpose? I'm betting it's the core probe function for a MediaTek Wi-Fi chip, given the name. Okay, let's scan the function's definition. Right, it looks like it's responsible for the initial device setup when a new MT798x-series wireless MAC device is discovered or loaded. It will probably handle resource allocation, hardware initialization, and driver registration with the kernel. I expect it to also perform some kind of detection or configuration based on the specific hardware variant. I'll be looking for things like memory mapping, IRQ setup, and perhaps some firmware loading. I want to check how error handling is implemented. Is it robust? Does it provide adequate error messages for debugging? I'll also pay close attention to the data structures it uses, especially anything related to the device context or configuration, and how these are initialized and passed around. I need to understand how the chip interacts with the PCI or SDIO bus. Let's see if there are any obvious race conditions. Finally, after this initial scan, I'll go through the code step-by-step, making note of any interesting or potentially problematic sections, thinking of the bigger picture of the wireless driver stack. This should get me started.



16/2 2026/08/10 14:35 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/soc.c",
  "FirstLine": 1215,
  "LineCount": 100
}

Results:
{
  "Contents": "1215:\t\n1216:\t\tdev-\u003erstc = devm_reset_control_get(pdev, \"consys\");\n1217:\t\treturn PTR_ERR_OR_ZERO(dev-\u003erstc);\n1218:\t}\n1219:\t\n1220:\tstatic int mt798x_wmac_probe(struct platform_device *pdev)\n1221:\t{\n1222:\t\tvoid __iomem *mem_base;\n1223:\t\tstruct mt7915_dev *dev;\n1224:\t\tstruct mt76_dev *mdev;\n1225:\t\tint irq, ret;\n1226:\t\tu32 chip_id;\n1227:\t\n1228:\t\tchip_id = (uintptr_t)of_device_get_match_data(\u0026pdev-\u003edev);\n1229:\t\n1230:\t\tmem_base = devm_platform_ioremap_resource(pdev, 0);\n1231:\t\tif (IS_ERR(mem_base)) {\n1232:\t\t\tdev_err(\u0026pdev-\u003edev, \"Failed to get memory resource\\n\");\n1233:\t\t\treturn PTR_ERR(mem_base);\n1234:\t\t}\n1235:\t\n1236:\t\tdev = mt7915_mmio_probe(\u0026pdev-\u003edev, mem_base, chip_id);\n1237:\t\tif (IS_ERR(dev))\n1238:\t\t\treturn PTR_ERR(dev);\n1239:\t\n1240:\t\tmdev = \u0026dev-\u003emt76;\n1241:\t\tret = mt7915_mmio_wed_init(dev, pdev, false, \u0026irq);\n1242:\t\tif (ret \u003c 0)\n1243:\t\t\tgoto free_device;\n1244:\t\n1245:\t\tif (!ret) {\n1246:\t\t\tirq = platform_get_irq(pdev, 0);\n1247:\t\t\tif (irq \u003c 0) {\n1248:\t\t\t\tret = irq;\n1249:\t\t\t\tgoto free_device;\n1250:\t\t\t}\n1251:\t\t}\n1252:\t\n1253:\t\tret = devm_request_irq(mdev-\u003edev, irq, mt7915_irq_handler,\n1254:\t\t\t\t       IRQF_SHARED, KBUILD_MODNAME, dev);\n1255:\t\tif (ret)\n1256:\t\t\tgoto free_device;\n1257:\t\n1258:\t\tret = mt798x_wmac_init(dev);\n1259:\t\tif (ret)\n1260:\t\t\tgoto free_irq;\n1261:\t\n1262:\t\tmt7915_wfsys_reset(dev);\n1263:\t\n1264:\t\tret = mt7915_register_device(dev);\n1265:\t\tif (ret)\n1266:\t\t\tgoto free_irq;\n1267:\t\n1268:\t\treturn 0;\n1269:\t\n1270:\tfree_irq:\n1271:\t\tdevm_free_irq(mdev-\u003edev, irq, dev);\n1272:\tfree_device:\n1273:\t\tif (mtk_wed_device_active(\u0026mdev-\u003emmio.wed))\n1274:\t\t\tmtk_wed_device_detach(\u0026mdev-\u003emmio.wed);\n1275:\t\tmt76_free_device(mdev);\n1276:\t\n1277:\t\treturn ret;\n1278:\t}\n1279:\t\n1280:\tstatic void mt798x_wmac_remove(struct platform_device *pdev)\n1281:\t{\n1282:\t\tstruct mt7915_dev *dev = platform_get_drvdata(pdev);\n1283:\t\n1284:\t\tmt7915_unregister_device(dev);\n1285:\t}\n1286:\t\n1287:\tstatic const struct of_device_id mt798x_wmac_of_match[] = {\n1288:\t\t{ .compatible = \"mediatek,mt7981-wmac\", .data = (u32 *)0x7981 },\n1289:\t\t{ .compatible = \"mediatek,mt7986-wmac\", .data = (u32 *)0x7986 },\n1290:\t\t{},\n1291:\t};\n1292:\t\n1293:\tMODULE_DEVICE_TABLE(of, mt798x_wmac_of_match);\n1294:\t\n1295:\tstruct platform_driver mt798x_wmac_driver = {\n1296:\t\t.driver = {\n1297:\t\t\t.name = \"mt798x-wmac\",\n1298:\t\t\t.of_match_table = mt798x_wmac_of_match,\n1299:\t\t},\n1300:\t\t.probe = mt798x_wmac_probe,\n1301:\t\t.remove = mt798x_wmac_remove,\n1302:\t};\n1303:\t\n1304:\tMODULE_FIRMWARE(MT7986_FIRMWARE_WA);\n1305:\tMODULE_FIRMWARE(MT7986_FIRMWARE_WM);\n1306:\tMODULE_FIRMWARE(MT7986_FIRMWARE_WM_MT7975);\n1307:\tMODULE_FIRMWARE(MT7986_ROM_PATCH);\n1308:\tMODULE_FIRMWARE(MT7986_ROM_PATCH_MT7975);\n1309:\t\n1310:\tMODULE_FIRMWARE(MT7981_FIRMWARE_WA);\n1311:\tMODULE_FIRMWARE(MT7981_FIRMWARE_WM);\n1312:\tMODULE_FIRMWARE(MT7981_ROM_PATCH);\n"
}

17/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 30994
							output: 52
							thoughts: 74
						

Thoughts:
**Diving into the Wi-Fi Driver Initialization**

Okay, so I'm looking at this platform driver, and it's pretty clear it relies on device tree instantiation – specifically for the `mediatek,mt7981-wmac` or `mediatek,mt7986-wmac` configurations. That makes sense, standard practice for modern embedded systems. What's more interesting is that it then calls `mt7915_register_device(dev)`. This function call is key here. I need to understand what that registration entails. My immediate thought is to check `mt7915_register_device` in `init.c`. That's where the initialization logic should be, right? Let's go take a look at the code and see what it does.



18/2 2026/08/10 14:35 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/init.c",
  "FirstLine": 1258,
  "LineCount": 100
}

Results:
{
  "Contents": "1258:\tint mt7915_register_device(struct mt7915_dev *dev)\n1259:\t{\n1260:\t\tstruct mt7915_phy *phy2;\n1261:\t\tint ret;\n1262:\t\n1263:\t\tdev-\u003ephy.dev = dev;\n1264:\t\tdev-\u003ephy.mt76 = \u0026dev-\u003emt76.phy;\n1265:\t\tdev-\u003emt76.phy.priv = \u0026dev-\u003ephy;\n1266:\t\tINIT_WORK(\u0026dev-\u003erc_work, mt7915_mac_sta_rc_work);\n1267:\t\tINIT_DELAYED_WORK(\u0026dev-\u003emphy.mac_work, mt7915_mac_work);\n1268:\t\tINIT_LIST_HEAD(\u0026dev-\u003esta_rc_list);\n1269:\t\tINIT_LIST_HEAD(\u0026dev-\u003etwt_list);\n1270:\t\n1271:\t\tinit_waitqueue_head(\u0026dev-\u003ereset_wait);\n1272:\t\tINIT_WORK(\u0026dev-\u003ereset_work, mt7915_mac_reset_work);\n1273:\t\tINIT_WORK(\u0026dev-\u003edump_work, mt7915_mac_dump_work);\n1274:\t\tmutex_init(\u0026dev-\u003edump_mutex);\n1275:\t\n1276:\t\tdev-\u003edbdc_support = mt7915_band_config(dev);\n1277:\t\n1278:\t\tphy2 = mt7915_alloc_ext_phy(dev);\n1279:\t\tif (IS_ERR(phy2))\n1280:\t\t\treturn PTR_ERR(phy2);\n1281:\t\n1282:\t\tret = mt7915_init_hardware(dev, phy2);\n1283:\t\tif (ret)\n1284:\t\t\tgoto free_phy2;\n1285:\t\n1286:\t\tmt7915_init_wiphy(\u0026dev-\u003ephy);\n1287:\t\n1288:\t#ifdef CONFIG_NL80211_TESTMODE\n1289:\t\tdev-\u003emt76.test_ops = \u0026mt7915_testmode_ops;\n1290:\t#endif\n1291:\t\n1292:\t\tret = mt76_register_device(\u0026dev-\u003emt76, true, mt76_rates,\n1293:\t\t\t\t\t   ARRAY_SIZE(mt76_rates));\n1294:\t\tif (ret)\n1295:\t\t\tgoto stop_hw;\n1296:\t\n1297:\t\tret = mt7915_thermal_init(\u0026dev-\u003ephy);\n1298:\t\tif (ret)\n1299:\t\t\tgoto unreg_dev;\n1300:\t\n1301:\t\tif (phy2) {\n1302:\t\t\tret = mt7915_register_ext_phy(dev, phy2);\n1303:\t\t\tif (ret)\n1304:\t\t\t\tgoto unreg_thermal;\n1305:\t\t}\n1306:\t\n1307:\t\tieee80211_queue_work(mt76_hw(dev), \u0026dev-\u003einit_work);\n1308:\t\n1309:\t\tdev-\u003erecovery.hw_init_done = true;\n1310:\t\n1311:\t\tret = mt7915_init_debugfs(\u0026dev-\u003ephy);\n1312:\t\tif (ret)\n1313:\t\t\tgoto unreg_ext_phy;\n1314:\t\n1315:\t\tret = mt7915_coredump_register(dev);\n1316:\t\tif (ret)\n1317:\t\t\tgoto unreg_ext_phy;\n1318:\t\n1319:\t\treturn 0;\n1320:\t\n1321:\tunreg_ext_phy:\n1322:\t\tif (phy2) {\n1323:\t\t\tmt7915_unregister_ext_phy(dev);\n1324:\t\t\tphy2 = NULL;\n1325:\t\t}\n1326:\tunreg_thermal:\n1327:\t\tmt7915_unregister_thermal(\u0026dev-\u003ephy);\n1328:\tunreg_dev:\n1329:\t\tmt76_unregister_device(\u0026dev-\u003emt76);\n1330:\tstop_hw:\n1331:\t\tmt7915_stop_hardware(dev);\n1332:\tfree_phy2:\n1333:\t\tif (phy2)\n1334:\t\t\tieee80211_free_hw(phy2-\u003emt76-\u003ehw);\n1335:\t\treturn ret;\n1336:\t}\n1337:\t\n1338:\tvoid mt7915_unregister_device(struct mt7915_dev *dev)\n1339:\t{\n1340:\t\tcancel_work_sync(\u0026dev-\u003edump_work);\n1341:\t\tcancel_work_sync(\u0026dev-\u003ereset_work);\n1342:\t\tcancel_work_sync(\u0026dev-\u003erc_work);\n1343:\t\tmt7915_unregister_ext_phy(dev);\n1344:\t\tmt7915_coredump_unregister(dev);\n1345:\t\tmt7915_unregister_thermal(\u0026dev-\u003ephy);\n1346:\t\tmt76_unregister_device(\u0026dev-\u003emt76);\n1347:\t\tmt7915_stop_hardware(dev);\n1348:\t\n1349:\t\tmt76_free_device(\u0026dev-\u003emt76);\n1350:\t}\n"
}

19/2 2026/08/10 14:35 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 32778
							output: 51
							thoughts: 48
						

Thoughts:
Here's my take on the process, focusing on the key actions:

**Diving into the MT7915 Hardware Initialization**

Okay, so `mt7915_register_device` has kicked off, and as I expected, it's called `mt7915_init_hardware` with the device and phy2 as arguments. My next immediate action is to understand what's happening within that function. I need to get a clear picture of how this initialization is being handled. I need to understand what steps it is taking with the hardware! Time to dig in and examine the inner workings of `mt7915_init_hardware`!



20/2 2026/08/10 14:36 tool grepper
0m Args:
{
  "Expression": "mt7915_init_hardware",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/init.c"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/init.c=865=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:866:mt7915_init_hardware(struct mt7915_dev *dev, struct mt7915_phy *phy2)\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-867-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=1258=int mt7915_register_device(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1281-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1282:\tret = mt7915_init_hardware(dev, phy2);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1283-\tif (ret)\n"
}

21/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 33316
							output: 51
							thoughts: 15
						

Thoughts:
Okay, let's dive into `mt7915_init_hardware`. I need to get a clear picture of what this function does, step-by-step, at a high level. Since I'm familiar with this architecture, I know it likely involves things like register writes to initialize the radio, PHY configuration, possibly DMA setup, and interrupt enabling. The goal here is to establish the fundamental hardware state for the MT7915 chipset to operate. I'll need to pay close attention to the order of operations; dependencies are crucial, especially with complex hardware like this. Are there any particular sections that seem immediately relevant to power management or security? That might offer insights into later performance characteristics. I'll watch for how the code sets up the clock sources too, because that's always a critical aspect, and can be subtle in its implications on later behavior. Understanding the hardware's reset state is also important so I will pay attention to that. I expect there might be checks for hardware revisions or capabilities; I need to recognize if it has a way to deal with different chip versions. I'll be looking for configuration of any associated co-processors as well; those are so common with this kind of system-on-chip. Finally, I'll need to track any return values or status flags, because these will likely communicate the success or failure of various initialization stages. Understanding these return values will be key to fault tolerance further down the line. I'll start reading, with these aspects in mind.



22/2 2026/08/10 14:36 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/init.c",
  "FirstLine": 865,
  "LineCount": 100
}

Results:
{
  "Contents": " 865:\tstatic int\n 866:\tmt7915_init_hardware(struct mt7915_dev *dev, struct mt7915_phy *phy2)\n 867:\t{\n 868:\t\tint ret, idx;\n 869:\t\n 870:\t\tmt76_wr(dev, MT_INT_MASK_CSR, 0);\n 871:\t\tmt76_wr(dev, MT_INT_SOURCE_CSR, ~0);\n 872:\t\n 873:\t\tINIT_WORK(\u0026dev-\u003einit_work, mt7915_init_work);\n 874:\t\n 875:\t\tret = mt7915_dma_init(dev, phy2);\n 876:\t\tif (ret)\n 877:\t\t\treturn ret;\n 878:\t\n 879:\t\tset_bit(MT76_STATE_INITIALIZED, \u0026dev-\u003emphy.state);\n 880:\t\n 881:\t\tret = mt7915_mcu_init(dev);\n 882:\t\tif (ret)\n 883:\t\t\treturn ret;\n 884:\t\n 885:\t\tret = mt7915_eeprom_init(dev);\n 886:\t\tif (ret \u003c 0)\n 887:\t\t\treturn ret;\n 888:\t\n 889:\t\tif (dev-\u003ecal) {\n 890:\t\t\tret = mt7915_mcu_apply_group_cal(dev);\n 891:\t\t\tif (ret)\n 892:\t\t\t\treturn ret;\n 893:\t\t}\n 894:\t\n 895:\t\t/* Beacon and mgmt frames should occupy wcid 0 */\n 896:\t\tidx = mt76_wcid_alloc(dev-\u003emt76.wcid_mask, MT7915_WTBL_STA);\n 897:\t\tif (idx)\n 898:\t\t\treturn -ENOSPC;\n 899:\t\n 900:\t\tdev-\u003emt76.global_wcid.idx = idx;\n 901:\t\tdev-\u003emt76.global_wcid.hw_key_idx = -1;\n 902:\t\tdev-\u003emt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;\n 903:\t\trcu_assign_pointer(dev-\u003emt76.wcid[idx], \u0026dev-\u003emt76.global_wcid);\n 904:\t\n 905:\t\treturn 0;\n 906:\t}\n 907:\t\n 908:\tvoid mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)\n 909:\t{\n 910:\t\tint sts;\n 911:\t\tu32 *cap;\n 912:\t\n 913:\t\tif (!phy-\u003emt76-\u003ecap.has_5ghz)\n 914:\t\t\treturn;\n 915:\t\n 916:\t\tsts = hweight8(phy-\u003emt76-\u003echainmask);\n 917:\t\tcap = \u0026phy-\u003emt76-\u003esband_5g.sband.vht_cap.cap;\n 918:\t\n 919:\t\t*cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |\n 920:\t\t\tIEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |\n 921:\t\t\tFIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,\n 922:\t\t\t\t   sts - 1);\n 923:\t\n 924:\t\t*cap \u0026= ~(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK |\n 925:\t\t\t  IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |\n 926:\t\t\t  IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);\n 927:\t\n 928:\t\tif (sts \u003c 2)\n 929:\t\t\treturn;\n 930:\t\n 931:\t\t*cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |\n 932:\t\t\tIEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |\n 933:\t\t\tFIELD_PREP(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,\n 934:\t\t\t\t   sts - 1);\n 935:\t}\n 936:\t\n 937:\tstatic void\n 938:\tmt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,\n 939:\t\t\t\t       struct ieee80211_sta_he_cap *he_cap, int vif)\n 940:\t{\n 941:\t\tstruct mt7915_dev *dev = phy-\u003edev;\n 942:\t\tstruct ieee80211_he_cap_elem *elem = \u0026he_cap-\u003ehe_cap_elem;\n 943:\t\tint sts = hweight8(phy-\u003emt76-\u003echainmask);\n 944:\t\tu8 c, sts_160 = sts;\n 945:\t\n 946:\t\t/* Can do 1/2 of STS in 160Mhz mode for mt7915 */\n 947:\t\tif (is_mt7915(\u0026dev-\u003emt76)) {\n 948:\t\t\tif (!dev-\u003edbdc_support)\n 949:\t\t\t\tsts_160 /= 2;\n 950:\t\t\telse\n 951:\t\t\t\tsts_160 = 0;\n 952:\t\t}\n 953:\t\n 954:\t#ifdef CONFIG_MAC80211_MESH\n 955:\t\tif (vif == NL80211_IFTYPE_MESH_POINT)\n 956:\t\t\treturn;\n 957:\t#endif\n 958:\t\n 959:\t\telem-\u003ephy_cap_info[3] \u0026= ~IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;\n 960:\t\telem-\u003ephy_cap_info[4] \u0026= ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;\n 961:\t\n 962:\t\tc = IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;\n 963:\t\tif (sts_160)\n 964:\t\t\tc |= IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;\n"
}

23/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 35506
							output: 49
							thoughts: 205
						

Thoughts:
**Analyzing the Initialization Flow**

Okay, let's break this down. From what I'm seeing, `mt7915_init_hardware` is the critical entry point, and it calls `mt7915_mcu_init` with the device context.  That's where the firmware loading and MCU initialization happen.  Makes sense, that's usually the first hardware step.

Now, if `mt7915_mcu_init` fails – because, say, the firmware isn't present or the hardware doesn't respond as expected – we're going to get a failure at that point. This, logically, will propagate up to a failure in `mt7915_register_device`. And here's the kicker: `mt7915_thermal_init` is called *after* `mt7915_init_hardware` within `mt7915_register_device`. So, any failure in the hardware initialization stage (like the firmware failing to load) *definitely* prevents us from even reaching the thermal initialization. That makes perfect sense; you can't manage thermal characteristics if the device isn't properly initialized.

Specifically, in QEMU, without the underlying hardware, `mt7915_mcu_init` is *guaranteed* to fail. No hardware, no firmware response. We need to verify this assumption by examining `mt7915_mcu_init` function itself.



24/2 2026/08/10 14:36 tool grepper
0m Args:
{
  "Expression": "mt7915_mcu_init",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/init.c=866=mt7915_init_hardware(struct mt7915_dev *dev, struct mt7915_phy *phy2)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-880-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:881:\tret = mt7915_mcu_init(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-882-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c=1290=mt7915_mac_restart(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1376-\t/* load firmware */\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c:1377:\tret = mt7915_mcu_init_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mac.c-1378-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2322=static int\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2323:mt7915_mcu_init_rx_airtime(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2324-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2387=static int mt7915_mcu_set_red(struct mt7915_dev *dev, bool enabled)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2409-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2410:int mt7915_mcu_init_firmware(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2411-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2457-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2458:\tret = mt7915_mcu_init_rx_airtime(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2459-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2464-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2465:int mt7915_mcu_init(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2466-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2476-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2477:\treturn mt7915_mcu_init_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2478-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h=473=int mt7915_run(struct ieee80211_hw *hw);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h:474:int mt7915_mcu_init(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h:475:int mt7915_mcu_init_firmware(struct mt7915_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h-476-int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,\n"
}

25/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 37302
							output: 53
							thoughts: 51
						

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

**Diving into the MT7915 MCU Initialization**

Okay, so `mt7915_mcu_init` is the entry point, naturally. And, as expected, it's immediately calling `mt7915_mcu_init_firmware(dev)`. That's where the real magic likely happens, the firmware loading and initial setup of the MCU, I presume. My next step is clearly to dive deeper into `mt7915_mcu_init_firmware`. I need to understand how the firmware is handled in order to get a clear picture of this initialization sequence. Let's see what that function is doing.



26/2 2026/08/10 14:36 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c",
  "FirstLine": 2410,
  "LineCount": 100
}

Results:
{
  "Contents": "2410:\tint mt7915_mcu_init_firmware(struct mt7915_dev *dev)\n2411:\t{\n2412:\t\tint ret;\n2413:\t\n2414:\t\t/* force firmware operation mode into normal state,\n2415:\t\t * which should be set before firmware download stage.\n2416:\t\t */\n2417:\t\tmt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);\n2418:\t\n2419:\t\tret = mt7915_driver_own(dev, 0);\n2420:\t\tif (ret)\n2421:\t\t\treturn ret;\n2422:\t\t/* set driver own for band1 when two hif exist */\n2423:\t\tif (dev-\u003ehif2) {\n2424:\t\t\tret = mt7915_driver_own(dev, 1);\n2425:\t\t\tif (ret)\n2426:\t\t\t\treturn ret;\n2427:\t\t}\n2428:\t\n2429:\t\tret = mt7915_load_firmware(dev);\n2430:\t\tif (ret)\n2431:\t\t\treturn ret;\n2432:\t\n2433:\t\tset_bit(MT76_STATE_MCU_RUNNING, \u0026dev-\u003emphy.state);\n2434:\t\tret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);\n2435:\t\tif (ret)\n2436:\t\t\treturn ret;\n2437:\t\n2438:\t\tret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, 0);\n2439:\t\tif (ret)\n2440:\t\t\treturn ret;\n2441:\t\n2442:\t\tmt76_connac_mcu_del_wtbl_all(\u0026dev-\u003emt76);\n2443:\t\n2444:\t\tif ((mtk_wed_device_active(\u0026dev-\u003emt76.mmio.wed) \u0026\u0026\n2445:\t\t     is_mt7915(\u0026dev-\u003emt76)) ||\n2446:\t\t    !mtk_wed_get_rx_capa(\u0026dev-\u003emt76.mmio.wed))\n2447:\t\t\tmt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0);\n2448:\t\n2449:\t\tret = mt7915_mcu_set_mwds(dev, 1);\n2450:\t\tif (ret)\n2451:\t\t\treturn ret;\n2452:\t\n2453:\t\tret = mt7915_mcu_set_muru_ctrl(dev, MURU_SET_PLATFORM_TYPE,\n2454:\t\t\t\t\t       MURU_PLATFORM_TYPE_PERF_LEVEL_2);\n2455:\t\tif (ret)\n2456:\t\t\treturn ret;\n2457:\t\n2458:\t\tret = mt7915_mcu_init_rx_airtime(dev);\n2459:\t\tif (ret)\n2460:\t\t\treturn ret;\n2461:\t\n2462:\t\treturn mt7915_mcu_set_red(dev, mtk_wed_device_active(\u0026dev-\u003emt76.mmio.wed));\n2463:\t}\n2464:\t\n2465:\tint mt7915_mcu_init(struct mt7915_dev *dev)\n2466:\t{\n2467:\t\tstatic const struct mt76_mcu_ops mt7915_mcu_ops = {\n2468:\t\t\t.max_retry = 1,\n2469:\t\t\t.headroom = sizeof(struct mt76_connac2_mcu_txd),\n2470:\t\t\t.mcu_skb_prepare_msg = mt76_connac2_mcu_fill_message,\n2471:\t\t\t.mcu_skb_send_msg = mt7915_mcu_send_message,\n2472:\t\t\t.mcu_parse_response = mt7915_mcu_parse_response,\n2473:\t\t};\n2474:\t\n2475:\t\tdev-\u003emt76.mcu_ops = \u0026mt7915_mcu_ops;\n2476:\t\n2477:\t\treturn mt7915_mcu_init_firmware(dev);\n2478:\t}\n2479:\t\n2480:\tvoid mt7915_mcu_exit(struct mt7915_dev *dev)\n2481:\t{\n2482:\t\tmt76_connac_mcu_restart(\u0026dev-\u003emt76);\n2483:\t\tif (mt7915_firmware_state(dev, false)) {\n2484:\t\t\tdev_err(dev-\u003emt76.dev, \"Failed to exit mcu\\n\");\n2485:\t\t\tgoto out;\n2486:\t\t}\n2487:\t\n2488:\t\tmt76_wr(dev, MT_TOP_LPCR_HOST_BAND(0), MT_TOP_LPCR_HOST_FW_OWN);\n2489:\t\tif (dev-\u003ehif2)\n2490:\t\t\tmt76_wr(dev, MT_TOP_LPCR_HOST_BAND(1),\n2491:\t\t\t\tMT_TOP_LPCR_HOST_FW_OWN);\n2492:\tout:\n2493:\t\tskb_queue_purge(\u0026dev-\u003emt76.mcu.res_q);\n2494:\t}\n2495:\t\n2496:\tstatic int\n2497:\tmt7915_mcu_set_rx_hdr_trans_blacklist(struct mt7915_dev *dev, int band)\n2498:\t{\n2499:\t\tstruct {\n2500:\t\t\tu8 operation;\n2501:\t\t\tu8 count;\n2502:\t\t\tu8 _rsv[2];\n2503:\t\t\tu8 index;\n2504:\t\t\tu8 enable;\n2505:\t\t\t__le16 etype;\n2506:\t\t} req = {\n2507:\t\t\t.operation = 1,\n2508:\t\t\t.count = 1,\n2509:\t\t\t.enable = 1,\n"
}

27/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 39278
							output: 48
							thoughts: 61
						

Thoughts:
Okay, let's break this down.

**Diving into the Driver Initialization**

My initial observation is that `mt7915_mcu_init_firmware` is calling `mt7915_driver_own(dev, 0)`. That's interesting, and my immediate instinct is to figure out why. This looks like a standard hardware check for ownership, probably to ensure there isn't another driver or process already controlling this piece of hardware. I need to understand what this `mt7915_driver_own` function is really doing; my suspicion is some kind of register polling mechanism, but I'll need to confirm that. Let's dig into `mt7915_driver_own` itself and see what's really happening.



28/2 2026/08/10 14:36 tool grepper
0m Args:
{
  "Expression": "mt7915_driver_own",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2057=int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2111-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2112:static int mt7915_driver_own(struct mt7915_dev *dev, u8 band)\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2113-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2410=int mt7915_mcu_init_firmware(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2418-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2419:\tret = mt7915_driver_own(dev, 0);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2420-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2423-\tif (dev-\u003ehif2) {\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2424:\t\tret = mt7915_driver_own(dev, 1);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2425-\t\tif (ret)\n"
}

29/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 40056
							output: 52
							thoughts: 15
						

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

**Diving into the MT7915 Driver Ownership**

Alright, I'm digging into `mt7915_driver_own`. This immediately tells me we're looking at a critical section within the MediaTek MT7915 Wi-Fi driver, likely dealing with resource allocation, access control, and potentially memory management related to the hardware itself. The "own" suggests we are exploring how the driver takes ownership of hardware resources and what protections are in place to prevent conflicts or race conditions.

I’m expecting to see structures related to the hardware interface, interrupt handling, and likely some sort of lock or semaphore mechanism to manage concurrent access. The "own" might refer to the driver's ownership of things like DMA channels, registers, and memory buffers used for transmitting and receiving data. I'll be looking for comments that explain the rationale behind these ownership schemes and any potential issues or error scenarios it handles.

I'm also anticipating that this section is crucial for maintaining the integrity of the wireless interface, preventing crashes, and ensuring robust performance. I'm thinking about things like how it handles multiple access points, station concurrency, or perhaps how it deals with power-saving states of the Wi-Fi chip. Any references to DMA configuration and buffer management are going to be particularly interesting. I'll also be focusing on any use of atomic operations or mutexes and consider the implications of their usage for performance. I’m also going to be looking at how any of this relates to firmware loading and execution, since the MT7915 likely has firmware on-chip.

Let's see what's actually in there. I'm ready to get down to the details.



30/2 2026/08/10 14:36 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c",
  "FirstLine": 2112,
  "LineCount": 20
}

Results:
{
  "Contents": "2112:\tstatic int mt7915_driver_own(struct mt7915_dev *dev, u8 band)\n2113:\t{\n2114:\t\tmt76_wr(dev, MT_TOP_LPCR_HOST_BAND(band), MT_TOP_LPCR_HOST_DRV_OWN);\n2115:\t\tif (!mt76_poll_msec(dev, MT_TOP_LPCR_HOST_BAND(band),\n2116:\t\t\t\t    MT_TOP_LPCR_HOST_FW_OWN_STAT, 0, 500)) {\n2117:\t\t\tdev_err(dev-\u003emt76.dev, \"Timeout for driver own\\n\");\n2118:\t\t\treturn -EIO;\n2119:\t\t}\n2120:\t\n2121:\t\t/* clear irq when the driver own success */\n2122:\t\tmt76_wr(dev, MT_TOP_LPCR_HOST_BAND_IRQ_STAT(band),\n2123:\t\t\tMT_TOP_LPCR_HOST_BAND_STAT);\n2124:\t\n2125:\t\treturn 0;\n2126:\t}\n2127:\t\n2128:\tstatic int\n2129:\tmt7915_firmware_state(struct mt7915_dev *dev, bool wa)\n2130:\t{\n2131:\t\tu32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,\n"
}

31/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 40900
							output: 53
							thoughts: 263
						

Thoughts:
**Analyzing a Potential QEMU Crash Scenario**

Okay, so I'm looking at this `mt7915_driver_own` function and I see it's polling a hardware register. In QEMU, without any real hardware, that poll is just going to timeout and immediately return an `-EIO` error. Right, makes sense. And because of that initial failure, `mt7915_mcu_init_firmware`, `mt7915_mcu_init`, and then `mt7915_init_hardware` all return `-EIO` in a cascade effect. Ultimately, this leads to `mt7915_register_device` failing before it even gets to call `mt7915_thermal_init`. So, it's pretty clear that `mt7915_thermal_init` is never even going to be reached when running in QEMU under normal circumstances.

But... hang on a minute. What if syzkaller is being used? Specifically, what if it's using `syz_pci_device_add`? That can map fake MMIO memory. Now, that's where things get interesting. Because `mt76_poll_msec` is reading from that potentially fake MMIO memory. If the fake memory is just zero-initialized, that means `MT_TOP_LPCR_HOST_FW_OWN_STAT`, which I'm pretty sure is a bitmask, *could* be zero. And if it's zero, `mt76_poll_msec` could actually succeed! This could potentially lead to a scenario where the initialization continues even though it should have failed, and that could trigger a crash down the line. I'm going to have to check what `MT_TOP_LPCR_HOST_FW_OWN_STAT` actually holds. This warrants a closer look.



32/2 2026/08/10 14:36 tool grepper
0m Args:
{
  "Expression": "MT_TOP_LPCR_HOST_FW_OWN_STAT",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2112=static int mt7915_driver_own(struct mt7915_dev *dev, u8 band)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2115-\tif (!mt76_poll_msec(dev, MT_TOP_LPCR_HOST_BAND(band),\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2116:\t\t\t    MT_TOP_LPCR_HOST_FW_OWN_STAT, 0, 500)) {\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2117-\t\tdev_err(dev-\u003emt76.dev, \"Timeout for driver own\\n\");\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/regs.h=50=enum offs_rev {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/regs.h-1101-#define MT_TOP_LPCR_HOST_DRV_OWN\tBIT(1)\ndrivers/net/wireless/mediatek/mt76/mt7915/regs.h:1102:#define MT_TOP_LPCR_HOST_FW_OWN_STAT\tBIT(2)\ndrivers/net/wireless/mediatek/mt76/mt7915/regs.h-1103-\n"
}

33/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 42021
							output: 49
							thoughts: 157
						

Thoughts:
**Analyzing the Driver's Initialization Logic**

Okay, so I'm looking at this initialization process for the mt7915 driver, and something immediately jumps out. If this "fake MMIO memory" is initialized to zero, then the `MT_TOP_LPCR_HOST_FW_OWN_STAT` bit, which is bit 2, will also be zero. This is crucial because `mt76_poll_msec` is being used, which is essentially checking a condition using a read-modify-compare operation. Specifically, it tests whether the result of `(readl(addr) & mask) == val`. In our case, the `mask` is that `MT_TOP_LPCR_HOST_FW_OWN_STAT` bit, and the desired `val` is zero.

Therefore, if this fake MMIO is zero, then we're performing a bitwise AND between zero and bit 2, which will inevitably result in zero. Consequently, the check `(0 & BIT(2)) == 0` is true! It *always* succeeds. This could mean `mt7915_driver_own` might think it's successfully claimed ownership when in reality, something is fundamentally wrong in the initialization sequence. That's a huge potential vulnerability! I need to dig deeper into the implication of this. The next logical step is to check what happens in `mt7915_load_firmware(dev)`. Let's see if that also assumes everything is fine...



34/2 2026/08/10 14:36 tool grepper
0m Args:
{
  "Expression": "mt7915_load_firmware",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2129=mt7915_firmware_state(struct mt7915_dev *dev, bool wa)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2141-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2142:static int mt7915_load_firmware(struct mt7915_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2143-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2410=int mt7915_mcu_init_firmware(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2428-\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2429:\tret = mt7915_load_firmware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2430-\tif (ret)\n"
}

35/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 42903
							output: 53
							thoughts: 16
						

Thoughts:
Okay, let's dive into this `mt7915_load_firmware` function. I see this a lot, especially with newer WiFi chipsets; firmware loading is always a critical piece. My initial thought is to quickly grasp the high-level architecture: is this a simple transfer, a more complex boot process, or something in between? What kind of memory access are we talking about?

Next, I'll be looking for the obvious: error handling. Firmware loading is notoriously sensitive. I want to see how robust the error checks are, what kind of retry mechanisms are in place (if any), and how it deals with common failure scenarios like checksum errors or communication timeouts. Are there detailed error codes? Are they meaningful?

Then, I'll pay close attention to any configuration parameters or initialization steps before the actual firmware download. Are there any hardware-specific register writes involved? Any initial power-up sequences I should be aware of? This is crucial for understanding the overall device state before the firmware takes over.

I'll be assessing the method of data transfer, is this DMA, or PIO? How is the communication protocol implemented? Is this a standard interface, or a proprietary one? Understanding the underlying data transfer mechanism will be critical for debugging potential issues.

Finally, I'll be checking for any security considerations. Are there any checks for signed firmware? Any anti-rollback mechanisms? Secure boot considerations? Firmware updates can be a prime attack vector. I'll need to see how they're handling that. Basically, I want to see if this is robust and secure, or if it's a potential vulnerability. I'm going to look for areas where I can introduce a fuzzing attack.



36/2 2026/08/10 14:36 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c",
  "FirstLine": 2142,
  "LineCount": 100
}

Results:
{
  "Contents": "2142:\tstatic int mt7915_load_firmware(struct mt7915_dev *dev)\n2143:\t{\n2144:\t\tint ret;\n2145:\t\n2146:\t\t/* Release Semaphore if taken by previous failed attempt */\n2147:\t\tret = mt76_connac_mcu_patch_sem_ctrl(\u0026dev-\u003emt76, false);\n2148:\t\tif (ret != PATCH_REL_SEM_SUCCESS) {\n2149:\t\t\tdev_err(dev-\u003emt76.dev, \"Could not release semaphore\\n\");\n2150:\t\t\t/* Continue anyways */\n2151:\t\t}\n2152:\t\n2153:\t\t/* Always restart MCU firmware */\n2154:\t\tmt76_connac_mcu_restart(\u0026dev-\u003emt76);\n2155:\t\n2156:\t\t/* Check if MCU is ready */\n2157:\t\tret = mt7915_firmware_state(dev, false);\n2158:\t\tif (ret) {\n2159:\t\t\tdev_err(dev-\u003emt76.dev, \"Firmware did not enter download state\\n\");\n2160:\t\t\treturn ret;\n2161:\t\t}\n2162:\t\n2163:\t\tret = mt76_connac2_load_patch(\u0026dev-\u003emt76, fw_name_var(dev, ROM_PATCH));\n2164:\t\tif (ret)\n2165:\t\t\treturn ret;\n2166:\t\n2167:\t\tret = mt76_connac2_load_ram(\u0026dev-\u003emt76, fw_name_var(dev, FIRMWARE_WM),\n2168:\t\t\t\t\t    fw_name(dev, FIRMWARE_WA));\n2169:\t\tif (ret)\n2170:\t\t\treturn ret;\n2171:\t\n2172:\t\tret = mt7915_firmware_state(dev, true);\n2173:\t\tif (ret)\n2174:\t\t\treturn ret;\n2175:\t\n2176:\t\tmt76_queue_tx_cleanup(dev, dev-\u003emt76.q_mcu[MT_MCUQ_FWDL], false);\n2177:\t\n2178:\t\tdev_dbg(dev-\u003emt76.dev, \"Firmware init done\\n\");\n2179:\t\n2180:\t\treturn 0;\n2181:\t}\n2182:\t\n2183:\tint mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl)\n2184:\t{\n2185:\t\tstruct {\n2186:\t\t\tu8 ctrl_val;\n2187:\t\t\tu8 pad[3];\n2188:\t\t} data = {\n2189:\t\t\t.ctrl_val = ctrl\n2190:\t\t};\n2191:\t\n2192:\t\tif (type == MCU_FW_LOG_WA)\n2193:\t\t\treturn mt76_mcu_send_msg(\u0026dev-\u003emt76, MCU_WA_EXT_CMD(FW_LOG_2_HOST),\n2194:\t\t\t\t\t\t \u0026data, sizeof(data), true);\n2195:\t\n2196:\t\treturn mt76_mcu_send_msg(\u0026dev-\u003emt76, MCU_EXT_CMD(FW_LOG_2_HOST), \u0026data,\n2197:\t\t\t\t\t sizeof(data), true);\n2198:\t}\n2199:\t\n2200:\tint mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level)\n2201:\t{\n2202:\t\tstruct {\n2203:\t\t\tu8 ver;\n2204:\t\t\tu8 pad;\n2205:\t\t\t__le16 len;\n2206:\t\t\tu8 level;\n2207:\t\t\tu8 rsv[3];\n2208:\t\t\t__le32 module_idx;\n2209:\t\t} data = {\n2210:\t\t\t.module_idx = cpu_to_le32(module),\n2211:\t\t\t.level = level,\n2212:\t\t};\n2213:\t\n2214:\t\treturn mt76_mcu_send_msg(\u0026dev-\u003emt76, MCU_EXT_CMD(FW_DBG_CTRL), \u0026data,\n2215:\t\t\t\t\t sizeof(data), false);\n2216:\t}\n2217:\t\n2218:\tint mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enabled)\n2219:\t{\n2220:\t\tstruct {\n2221:\t\t\t__le32 cmd;\n2222:\t\t\tu8 enable;\n2223:\t\t} data = {\n2224:\t\t\t.cmd = cpu_to_le32(MURU_SET_TXC_TX_STATS_EN),\n2225:\t\t\t.enable = enabled,\n2226:\t\t};\n2227:\t\n2228:\t\treturn mt76_mcu_send_msg(\u0026dev-\u003emt76, MCU_EXT_CMD(MURU_CTRL), \u0026data,\n2229:\t\t\t\t\tsizeof(data), false);\n2230:\t}\n2231:\t\n2232:\tint mt7915_mcu_muru_debug_get(struct mt7915_phy *phy)\n2233:\t{\n2234:\t\tstruct mt7915_dev *dev = phy-\u003edev;\n2235:\t\tstruct sk_buff *skb;\n2236:\t\tstruct mt7915_mcu_muru_stats *mu_stats;\n2237:\t\tint ret;\n2238:\t\n2239:\t\tstruct {\n2240:\t\t\t__le32 cmd;\n2241:\t\t\tu8 band_idx;\n"
}

37/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 44901
							output: 52
							thoughts: 47
						

Thoughts:
Here's my analysis of what's happening, keeping in mind my expertise:

**Firmware Loading Sequence Deep Dive**

Okay, so `mt7915_load_firmware` is the function responsible for getting the firmware onto the MT7915 device. I see that it kicks things off with a call to `mt7915_firmware_state(dev, false)`. Naturally, my first instinct is to understand what that `mt7915_firmware_state` function *does*. I need to see if it sets up any preconditions, initializes any hardware registers, or maybe even attempts a basic handshake with the device before the more involved loading process starts. The `false` argument is interesting too; it's likely indicating a particular state to be set during the initialization of the function. I would be curious to understand what that entails. This will definitely give me context to understand what's happening during the firmware load.



38/2 2026/08/10 14:36 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c",
  "FirstLine": 2128,
  "LineCount": 15
}

Results:
{
  "Contents": "2128:\tstatic int\n2129:\tmt7915_firmware_state(struct mt7915_dev *dev, bool wa)\n2130:\t{\n2131:\t\tu32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,\n2132:\t\t\t\t       wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);\n2133:\t\n2134:\t\tif (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,\n2135:\t\t\t\t    state, 1000)) {\n2136:\t\t\tdev_err(dev-\u003emt76.dev, \"Timeout for initializing firmware\\n\");\n2137:\t\t\treturn -EIO;\n2138:\t\t}\n2139:\t\treturn 0;\n2140:\t}\n2141:\t\n2142:\tstatic int mt7915_load_firmware(struct mt7915_dev *dev)\n"
}

39/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 45483
							output: 46
							thoughts: 113
						

Thoughts:
**Checking the Firmware Download State**

Okay, so I'm looking at how the `mt7915_firmware_state` function determines if the firmware has been downloaded. The code is periodically checking the `MT_TOP_MISC` register, specifically the `MT_TOP_MISC_FW_STATE` field within it. It's supposed to be comparing this value to a target `state`, and ideally, this would tell us if the download is complete.

However, there's a potential gotcha here. The code mentions that if the fake MMIO memory region is set to zero, then the `MT_TOP_MISC_FW_STATE` will also evaluate to zero. That makes sense, but we need to consider what the expected value, the target state, actually *is*. The code is explicitly comparing to `state`, which is defined using `FIELD_PREP`, specifically using `FW_STATE_FW_DOWNLOAD`. So, I need to verify that `FW_STATE_FW_DOWNLOAD` is what we *expect* to see during the firmware download process.



40/2 2026/08/10 14:36 tool grepper
0m Args:
{
  "Expression": "FW_STATE_FW_DOWNLOAD",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2129=mt7915_firmware_state(struct mt7915_dev *dev, bool wa)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2131-\tu32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2132:\t\t\t       wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2133-\n"
}

41/2 2026/08/10 14:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46074
							output: 46
							thoughts: 15
						

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

**Analyzing `FW_STATE_FW_DOWNLOAD`**

Alright, let's dive right in. My first thought is to zero in on the `FW_STATE_FW_DOWNLOAD` definition. I need to refresh my understanding of *precisely* what this state signifies within the firmware download process. I need to be sure I have a clear and accurate mental model. What assumptions are baked into this state? Are there any subtle nuances in its implementation that I might have overlooked during the initial review? Are there potential areas of vulnerability I can quickly identify through a definition review. I have to make sure my understanding matches the implementation. So, let's get into the details, and make sure my mind is working with this specific context correctly.



42/2 2026/08/10 14:37 tool grepper
0m Args:
{
  "Expression": "FW_STATE_FW_DOWNLOAD",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2129=mt7915_firmware_state(struct mt7915_dev *dev, bool wa)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2131-\tu32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2132:\t\t\t       wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2133-\n"
}

43/2 2026/08/10 14:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46506
							output: 40
							thoughts: 27
						

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

**Analyzing Firmware Download States**

Alright, time to dig in. I need to get a handle on how this firmware download process is behaving, specifically within the `mt76` and `mt7915` drivers. My immediate focus is on the `FW_STATE_FW_DOWNLOAD` state. I need to understand what's happening when that specific state is active. What triggers it? What actions does it dictate? What are the possible error conditions associated with this state, and how are they handled? It's all about ensuring the firmware updates are robust and reliable, so getting a solid grasp on that particular flag is crucial. Let's see what the code reveals.



44/2 2026/08/10 14:37 tool grepper
0m Args:
{
  "Expression": "FW_STATE_FW_DOWNLOAD",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1433=static int mt7615_load_firmware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1439-\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1440:\tif (val != FW_STATE_FW_DOWNLOAD) {\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1441-\t\tdev_err(dev-\u003emt76.dev, \"Firmware is not ready for download\\n\");\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1463=static int mt7622_load_firmware(struct mt7615_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1470-\tval = mt76_get_field(dev, MT_TOP_OFF_RSV, MT_TOP_OFF_RSV_FW_STATE);\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1471:\tif (val != FW_STATE_FW_DOWNLOAD) {\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1472-\t\tdev_err(dev-\u003emt76.dev, \"Firmware is not ready for download\\n\");\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h=1144=enum {\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h-1145-\tFW_STATE_INITIAL,\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h:1146:\tFW_STATE_FW_DOWNLOAD,\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h-1147-\tFW_STATE_NORMAL_OPERATION,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c=2129=mt7915_firmware_state(struct mt7915_dev *dev, bool wa)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2131-\tu32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2132:\t\t\t       wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);\ndrivers/net/wireless/mediatek/mt76/mt7915/mcu.c-2133-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c=3577=static int mt7996_load_firmware(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3582-\t/* make sure fw is download state */\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c:3583:\tif (mt7996_firmware_state(dev, FW_STATE_FW_DOWNLOAD)) {\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3584-\t\t/* restart firmware once */\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3585-\t\tmt7996_mcu_restart(\u0026dev-\u003emt76);\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c:3586:\t\tret = mt7996_firmware_state(dev, FW_STATE_FW_DOWNLOAD);\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3587-\t\tif (ret) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c=3772=void mt7996_mcu_exit(struct mt7996_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3774-\tmt7996_mcu_restart(\u0026dev-\u003emt76);\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c:3775:\tif (mt7996_firmware_state(dev, FW_STATE_FW_DOWNLOAD)) {\ndrivers/net/wireless/mediatek/mt76/mt7996/mcu.c-3776-\t\tdev_err(dev-\u003emt76.dev, \"Failed to exit mcu\\n\");\n"
}

45/2 2026/08/10 14:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 48030
							output: 48
							thoughts: 659
						

Thoughts:
**Analyzing the Unreachability of mt7915_thermal_init in QEMU**

Okay, let's break this down. My initial thought is that if `FW_STATE_FW_DOWNLOAD` is set to 1, then the `FIELD_PREP` macro will produce a non-zero value. However, the critical issue seems to be with the fake MMIO memory in QEMU. If that memory is initialized to 0, the `mt76_poll_msec` function will inevitably timeout because it's looking for a non-zero state.

This timeout leads to a cascading series of failures: `mt7915_firmware_state` returns `-EIO`, followed by `mt7915_load_firmware`, `mt7915_mcu_init_firmware`, `mt7915_mcu_init`, `mt7915_init_hardware`, and finally `mt7915_register_device` all failing. The failure in `mt7915_register_device` is the key – it prevents the call to `mt7915_thermal_init`. Thus, I can confidently state that `mt7915_thermal_init` is unreachable in this scenario.

Now, let's consider the alternative: what if the fake MMIO *isn't* zero? Syzkaller's `syz_pci_device_add` doesn't give us dynamic control over MMIO reads. Sure, it can map memory, and we can *write* to it, but the driver *reads* from it. If the driver reads before any writes from Syzkaller occur, we're back to zero. Syzkaller can write values to the fake MMIO memory, but it doesn't know which address to write what to pass the polling. It's improbable that Syzkaller could manage to satisfy all the driver's hardware initialization checks, firmware state checks, and everything else, just by random writes.

Furthermore, `mt76_connac2_load_patch` and `mt76_connac2_load_ram` demand the presence of legitimate firmware files. While Syzkaller might have some dummy files, they are unlikely to be valid enough to respond to MCU commands, especially when considering all the states the firmware has to be.

After the firmware is loaded, `mt7915_firmware_state(dev, true)` checks for `FW_STATE_RDY` (which is 3). Assuming we somehow get past that, the driver starts sending MCU commands via `mt76_mcu_send_msg`, commands like `mt7915_mcu_fw_log_2_host`, `mt7915_mcu_set_mwds`, `mt7915_mcu_set_muru_ctrl`, and `mt7915_mcu_init_rx_airtime`, which all rely on DMA rings or MMIO for responses. With no real MCU present, this will undoubtedly timeout and fail, ensuring that `mt7915_mcu_init_firmware` fails again.

Therefore, whether the fake MMIO is initialized to 0 or something else, the final conclusion is still that `mt7915_thermal_init` is not reachable in QEMU.
Let me quickly check if `mt7915_thermal_init` is called anywhere else.



46/2 2026/08/10 14:37 tool grepper
0m Args:
{
  "Expression": "mt7915_thermal_init",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/init.c=199=static void mt7915_unregister_thermal(struct mt7915_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-212-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:213:static int mt7915_thermal_init(struct mt7915_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-214-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=730=mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-761-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:762:\tret = mt7915_thermal_init(phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-763-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=1258=int mt7915_register_device(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1296-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1297:\tret = mt7915_thermal_init(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1298-\tif (ret)\n"
}

47/2 2026/08/10 14:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49998
							output: 48
							thoughts: 74
						

Thoughts:
Okay, let me think this through.

**Analyzing the mt7915 Driver Initialization**

Right, so these `mt7915_register_ext_phy` and `mt7915_register_device` functions... the text indicates they're only called within `mt7915_register_ext_phy` and `mt7915_register_device`. They're both called during the device probe, and crucially, *after* `mt7915_init_hardware`. That tells me these aren't part of the initial hardware setup itself. They seem to be registering something, likely resources or capabilities, with the kernel after the hardware is initialized. The implication being they are probably part of a late-stage register operation. Since they're only called in probe and only after hardware initialization, they would be unreachable in QEMU because the device probe isn't running.

Hold on a second... what about `mt7915_unregister_thermal`? I have to consider its placement and timing in the lifecycle, otherwise there is no true assessment of the impact. The focus on "register" implies it might be related to "unregister", and its context in the probe or removal phases is also important to determine its reach in QEMU. That's a crucial piece of the puzzle I need to explore further.



48/2 2026/08/10 14:37 tool grepper
0m Args:
{
  "Expression": "mt7915_unregister_thermal",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7915/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7915/init.c=195=static const struct thermal_zone_device_ops mt7915_tz_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-198-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:199:static void mt7915_unregister_thermal(struct mt7915_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-200-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=213=static int mt7915_thermal_init(struct mt7915_phy *phy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-256-\tif (ret)\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:257:\t\tmt7915_unregister_thermal(phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-258-\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=1234=static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1241-\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1242:\tmt7915_unregister_thermal(phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1243-\tmt76_unregister_phy(mphy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=1258=int mt7915_register_device(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1326-unreg_thermal:\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1327:\tmt7915_unregister_thermal(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1328-unreg_dev:\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c=1338=void mt7915_unregister_device(struct mt7915_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1344-\tmt7915_coredump_unregister(dev);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c:1345:\tmt7915_unregister_thermal(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/mt7915/init.c-1346-\tmt76_unregister_device(\u0026dev-\u003emt76);\n"
}

49/2 2026/08/10 14:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 51259
							output: 146
							thoughts: 358
						

Thoughts:
**Analysis of the mt7915 Thermal Unregistration Paths**

Okay, let's break this down. My initial assessment is that the `mt7915_unregister_thermal` function is effectively unreachable under the conditions we're concerned about, particularly within a QEMU virtualized environment.

Here's my reasoning: it looks like `mt7915_unregister_thermal` gets called under several circumstances: error paths within `mt7915_thermal_init` and `mt7915_register_device`, and also from `mt7915_unregister_ext_phy` and `mt7915_unregister_device`. The issue is, `mt7915_register_device` can fail early. If this happens, the code flow likely jumps to a cleanup routine like `free_phy2` or `stop_hw`, which bypasses the call to `mt7915_unregister_thermal` entirely. Furthermore, `mt7915_unregister_device` is normally called from `mt7915_pci_remove` or `mt798x_wmac_remove`, but because of the initial failure of `mt7915_pci_probe`, `mt7915_pci_remove` is never executed. Consequently, this makes `mt7915_unregister_thermal` unreachable.

Since these modified code paths are impossible to reach in QEMU, which is the standard virtualization we're considering, I'm leaning toward setting `WorthFuzzing=false`.

Let's quickly check the requirements, just to make sure. Okay, the instructions state that we should return `WorthFuzzing=false` if the patch involves code within vendor-specific PCIe switch, SmartNIC, or GPU drivers that require physical PCIe hardware cards not emulated in standard QEMU. That's a perfect fit! `mt7915` is a vendor-specific PCIe Wi-Fi driver, and it relies on physical hardware that isn't emulated in QEMU. Given this and that the patch *only* modifies this driver, it's clear: `WorthFuzzing=false` is the right call here.



50/2 2026/08/10 14:37 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the MediaTek MT7915 PCIe Wi-Fi driver (mt7915) to fix a thermal zone unregistration issue. This is a vendor-specific PCIe driver that requires physical hardware to initialize (e.g., passing driver ownership checks, firmware loading, and MCU communication). Since this hardware is not emulated in standard QEMU, the modified code paths in `mt7915_thermal_init` and `mt7915_unregister_thermal` are impossible to reach in virtualized fuzzing environments.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the MediaTek MT7915 PCIe Wi-Fi driver (mt7915) to fix a thermal zone unregistration issue. This is a vendor-specific PCIe driver that requires physical hardware to initialize (e.g., passing driver ownership checks, firmware loading, and MCU communication). Since this hardware is not emulated in standard QEMU, the modified code paths in `mt7915_thermal_init` and `mt7915_unregister_thermal` are impossible to reach in virtualized fuzzing environments.",
  "WorthFuzzing": false
}

51/1 2026/08/10 14:37 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

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