| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/12 07:04 | flow | patch-triage |
2mArgs:null Results: {
"EnableConfigs": [
"WLAN_VENDOR_MORSEMICRO",
"MM81X_USB"
],
"FocusSymbols": [
"mm81x_fw_init",
"mm81x_fw_parse_ext_host_tbl"
],
"KMSANReasoning": "The patch fixes out-of-bounds reads and memory leaks during firmware parsing. The bounds checks prevent reading past the end of allocated buffers containing firmware data, which are out-of-bounds memory accesses rather than uninitialized memory uses. KASAN is fully capable of detecting these out-of-bounds reads, and kmemleak detects the fixed memory leaks. There is no risk of uninitialized memory being exposed to user space or used in control flow, so a dedicated KMSAN fuzzing session is not necessary.",
"NeedsKMSAN": false,
"Reasoning": "The patch fixes out-of-bounds reads and memory leaks in the firmware parsing logic of the Morse Micro mm81x driver. The driver can be tested via the USB interface using a dummy HCD or syzkaller's USB fuzzing capabilities. The firmware loading and parsing logic is reachable when the device is probed and the interface is brought up.",
"WorthFuzzing": true
} |
| 1/1 | 2026/08/12 07:04 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 00660705ed6fca873a029ee3c252fc3fb88a154b\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Aug 12 07:04:43 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/morsemicro/mm81x/fw.c b/drivers/net/wireless/morsemicro/mm81x/fw.c\nindex d6d2ad086c328..50fa9e4b5f803 100644\n--- a/drivers/net/wireless/morsemicro/mm81x/fw.c\n+++ b/drivers/net/wireless/morsemicro/mm81x/fw.c\n@@ -54,21 +54,29 @@ static int mm81x_fw_get_header(const u8 *data, Elf32_Ehdr *ehdr)\n \n static void mm81x_fw_parse_info(struct mm81x *mors, const u8 *data, int length)\n {\n-\tconst struct mm81x_fw_info_tlv *tlv =\n-\t\t(const struct mm81x_fw_info_tlv *)data;\n+\tconst u8 *end = data + length;\n+\tconst u8 *pos = data;\n+\n+\twhile (end - pos \u003e= (ptrdiff_t)sizeof(struct mm81x_fw_info_tlv)) {\n+\t\tconst struct mm81x_fw_info_tlv *tlv =\n+\t\t\t(const struct mm81x_fw_info_tlv *)pos;\n+\t\tu16 tlv_len = le16_to_cpu(tlv-\u003elength);\n+\n+\t\tpos = tlv-\u003eval;\n+\t\tif (tlv_len \u003e end - pos)\n+\t\t\tbreak;\n \n-\twhile ((u8 *)tlv \u003c (data + length)) {\n \t\tswitch (le16_to_cpu(tlv-\u003etype)) {\n \t\tcase MM81X_FW_INFO_TLV_BCF_ADDR:\n-\t\t\tmors-\u003ebcf_address = get_unaligned_le32(tlv-\u003eval);\n+\t\t\tif (tlv_len \u003e= sizeof(__le32))\n+\t\t\t\tmors-\u003ebcf_address =\n+\t\t\t\t\tget_unaligned_le32(tlv-\u003eval);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tbreak;\n \t\t}\n-\t\ttlv = (const struct mm81x_fw_info_tlv *)((u8 *)tlv +\n-\t\t\t\t\t\t\t le16_to_cpu(\n-\t\t\t\t\t\t\t\t tlv-\u003elength) +\n-\t\t\t\t\t\t\t sizeof(*tlv));\n+\n+\t\tpos += tlv_len;\n \t}\n }\n \n@@ -117,13 +125,15 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)\n \n \tif (mm81x_fw_get_header(fw-\u003edata, \u0026ehdr)) {\n \t\tdev_err(mors-\u003edev, \"Wrong file format\");\n-\t\treturn -EINVAL;\n+\t\tret = -EINVAL;\n+\t\tgoto out_free;\n \t}\n \n \tif (mm81x_fw_get_section_header(fw-\u003edata, \u0026ehdr, \u0026sh_strtab,\n \t\t\t\t\tehdr.e_shstrndx)) {\n \t\tdev_err(mors-\u003edev, \"Invalid firmware. Missing string table\");\n-\t\treturn -ENOENT;\n+\t\tret = -ENOENT;\n+\t\tgoto out_free;\n \t}\n \n \tsh_strs = (const char *)fw-\u003edata + sh_strtab.sh_offset;\n@@ -160,7 +170,7 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)\n \t\t\tmm81x_release_bus(mors);\n \t\t\tif (status) {\n \t\t\t\tret = -EIO;\n-\t\t\t\tbreak;\n+\t\t\t\tgoto out_free;\n \t\t\t}\n \t\t}\n \t}\n@@ -179,6 +189,7 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)\n \tif (ehdr.e_entry)\n \t\tret = mm81x_fw_set_boot_addr(mors, ehdr.e_entry);\n \n+out_free:\n \tdevm_kfree(mors-\u003edev, fw_buf);\n \treturn ret;\n }\n@@ -492,6 +503,13 @@ static int mm81x_fw_read_ext_host_table(struct mm81x *mors,\n \tif (ret)\n \t\tgoto exit;\n \n+\t/* The table describes its own length; it must fit what was read */\n+\tif (le32_to_cpu(host_tbl-\u003eext_host_tbl_length) \u003c sizeof(*host_tbl) ||\n+\t le32_to_cpu(host_tbl-\u003eext_host_tbl_length) \u003e ext_host_tbl_len) {\n+\t\tret = -EINVAL;\n+\t\tgoto exit;\n+\t}\n+\n \tmm81x_release_bus(mors);\n \t*ext_host_table = host_tbl;\n \treturn ret;\n@@ -559,34 +577,44 @@ int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)\n \tend = ((u8 *)ext_host_table) +\n \t le32_to_cpu(ext_host_table-\u003eext_host_tbl_length);\n \n-\twhile (head \u003c end) {\n+\twhile (end - head \u003e= (ptrdiff_t)sizeof(struct ext_host_tbl_tlv_hdr)) {\n \t\tstruct ext_host_tbl_tlv_hdr *hdr =\n \t\t\t(struct ext_host_tbl_tlv_hdr *)head;\n+\t\tu16 tlv_len = le16_to_cpu(hdr-\u003elength);\n+\n+\t\tif (tlv_len \u003c sizeof(*hdr) || tlv_len \u003e end - head)\n+\t\t\tbreak;\n \n \t\tswitch (le16_to_cpu(hdr-\u003etag)) {\n-\t\tcase MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES:\n-\t\t\tmm81x_fw_update_capabilities(\n-\t\t\t\tmors, (struct ext_host_tbl_s1g_caps *)hdr);\n+\t\tcase MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES: {\n+\t\t\tstruct ext_host_tbl_s1g_caps *caps = (void *)hdr;\n+\n+\t\t\tif (tlv_len \u003e= sizeof(*caps))\n+\t\t\t\tmm81x_fw_update_capabilities(mors, caps);\n \t\t\tbreak;\n+\t\t}\n+\t\tcase MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM: {\n+\t\t\tstruct ext_host_tbl_insert_skb_checksum *csum =\n+\t\t\t\t(void *)hdr;\n \n-\t\tcase MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM:\n-\t\t\tmm81x_fw_update_validate_skb_checksum(\n-\t\t\t\tmors,\n-\t\t\t\t(struct ext_host_tbl_insert_skb_checksum *)hdr);\n+\t\t\tif (tlv_len \u003e= sizeof(*csum))\n+\t\t\t\tmm81x_fw_update_validate_skb_checksum(mors,\n+\t\t\t\t\t\t\t\t csum);\n \t\t\tbreak;\n+\t\t}\n+\t\tcase MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE: {\n+\t\t\tstruct ext_host_tbl_yaps_table *yaps = (void *)hdr;\n \n-\t\tcase MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE:\n-\t\t\tmm81x_yaps_hw_read_table(\n-\t\t\t\tmors, \u0026((struct ext_host_tbl_yaps_table *)hdr)\n-\t\t\t\t\t -\u003eyaps_table);\n+\t\t\tif (tlv_len \u003e= sizeof(*yaps))\n+\t\t\t\tmm81x_yaps_hw_read_table(mors,\n+\t\t\t\t\t\t\t \u0026yaps-\u003eyaps_table);\n \t\t\tbreak;\n+\t\t}\n \t\tdefault:\n \t\t\tbreak;\n \t\t}\n \n-\t\thead += le16_to_cpu(hdr-\u003elength);\n-\t\tif (!hdr-\u003elength)\n-\t\t\tbreak;\n+\t\thead += tlv_len;\n \t}\n \n \tkfree(ext_host_table);\n"
} |
| 2/1 | 2026/08/12 07:04 | agent | patch-evaluator |
1mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"WLAN_VENDOR_MORSEMICRO",
"MM81X_USB"
],
"FocusSymbols": [
"mm81x_fw_init",
"mm81x_fw_parse_ext_host_tbl"
],
"Reasoning": "The patch fixes out-of-bounds reads and memory leaks in the firmware parsing logic of the Morse Micro mm81x driver. The driver can be tested via the USB interface using a dummy HCD or syzkaller's USB fuzzing capabilities. The firmware loading and parsing logic is reachable when the device is probed and the interface is brought up.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 00660705ed6fca873a029ee3c252fc3fb88a154b
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Aug 12 07:04:43 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/morsemicro/mm81x/fw.c b/drivers/net/wireless/morsemicro/mm81x/fw.c
index d6d2ad086c328..50fa9e4b5f803 100644
--- a/drivers/net/wireless/morsemicro/mm81x/fw.c
+++ b/drivers/net/wireless/morsemicro/mm81x/fw.c
@@ -54,21 +54,29 @@ static int mm81x_fw_get_header(const u8 *data, Elf32_Ehdr *ehdr)
static void mm81x_fw_parse_info(struct mm81x *mors, const u8 *data, int length)
{
- const struct mm81x_fw_info_tlv *tlv =
- (const struct mm81x_fw_info_tlv *)data;
+ const u8 *end = data + length;
+ const u8 *pos = data;
+
+ while (end - pos >= (ptrdiff_t)sizeof(struct mm81x_fw_info_tlv)) {
+ const struct mm81x_fw_info_tlv *tlv =
+ (const struct mm81x_fw_info_tlv *)pos;
+ u16 tlv_len = le16_to_cpu(tlv->length);
+
+ pos = tlv->val;
+ if (tlv_len > end - pos)
+ break;
- while ((u8 *)tlv < (data + length)) {
switch (le16_to_cpu(tlv->type)) {
case MM81X_FW_INFO_TLV_BCF_ADDR:
- mors->bcf_address = get_unaligned_le32(tlv->val);
+ if (tlv_len >= sizeof(__le32))
+ mors->bcf_address =
+ get_unaligned_le32(tlv->val);
break;
default:
break;
}
- tlv = (const struct mm81x_fw_info_tlv *)((u8 *)tlv +
- le16_to_cpu(
- tlv->length) +
- sizeof(*tlv));
+
+ pos += tlv_len;
}
}
@@ -117,13 +125,15 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)
if (mm81x_fw_get_header(fw->data, &ehdr)) {
dev_err(mors->dev, "Wrong file format");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_free;
}
if (mm81x_fw_get_section_header(fw->data, &ehdr, &sh_strtab,
ehdr.e_shstrndx)) {
dev_err(mors->dev, "Invalid firmware. Missing string table");
- return -ENOENT;
+ ret = -ENOENT;
+ goto out_free;
}
sh_strs = (const char *)fw->data + sh_strtab.sh_offset;
@@ -160,7 +170,7 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)
mm81x_release_bus(mors);
if (status) {
ret = -EIO;
- break;
+ goto out_free;
}
}
}
@@ -179,6 +189,7 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)
if (ehdr.e_entry)
ret = mm81x_fw_set_boot_addr(mors, ehdr.e_entry);
+out_free:
devm_kfree(mors->dev, fw_buf);
return ret;
}
@@ -492,6 +503,13 @@ static int mm81x_fw_read_ext_host_table(struct mm81x *mors,
if (ret)
goto exit;
+ /* The table describes its own length; it must fit what was read */
+ if (le32_to_cpu(host_tbl->ext_host_tbl_length) < sizeof(*host_tbl) ||
+ le32_to_cpu(host_tbl->ext_host_tbl_length) > ext_host_tbl_len) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
mm81x_release_bus(mors);
*ext_host_table = host_tbl;
return ret;
@@ -559,34 +577,44 @@ int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)
end = ((u8 *)ext_host_table) +
le32_to_cpu(ext_host_table->ext_host_tbl_length);
- while (head < end) {
+ while (end - head >= (ptrdiff_t)sizeof(struct ext_host_tbl_tlv_hdr)) {
struct ext_host_tbl_tlv_hdr *hdr =
(struct ext_host_tbl_tlv_hdr *)head;
+ u16 tlv_len = le16_to_cpu(hdr->length);
+
+ if (tlv_len < sizeof(*hdr) || tlv_len > end - head)
+ break;
switch (le16_to_cpu(hdr->tag)) {
- case MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES:
- mm81x_fw_update_capabilities(
- mors, (struct ext_host_tbl_s1g_caps *)hdr);
+ case MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES: {
+ struct ext_host_tbl_s1g_caps *caps = (void *)hdr;
+
+ if (tlv_len >= sizeof(*caps))
+ mm81x_fw_update_capabilities(mors, caps);
break;
+ }
+ case MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM: {
+ struct ext_host_tbl_insert_skb_checksum *csum =
+ (void *)hdr;
- case MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM:
- mm81x_fw_update_validate_skb_checksum(
- mors,
- (struct ext_host_tbl_insert_skb_checksum *)hdr);
+ if (tlv_len >= sizeof(*csum))
+ mm81x_fw_update_validate_skb_checksum(mors,
+ csum);
break;
+ }
+ case MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE: {
+ struct ext_host_tbl_yaps_table *yaps = (void *)hdr;
- case MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE:
- mm81x_yaps_hw_read_table(
- mors, &((struct ext_host_tbl_yaps_table *)hdr)
- ->yaps_table);
+ if (tlv_len >= sizeof(*yaps))
+ mm81x_yaps_hw_read_table(mors,
+ &yaps->yaps_table);
break;
+ }
default:
break;
}
- head += le16_to_cpu(hdr->length);
- if (!hdr->length)
- break;
+ head += tlv_len;
}
kfree(ext_host_table);
|
| 3/2 | 2026/08/12 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3869 output: 34 thoughts: 177 Thoughts: **Analyzing a WiFi Driver Patch for Vulnerabilities** Okay, so I'm looking at a patch that targets `drivers/net/wireless/morsemicro/mm81x/fw.c`. The description mentions a fix for out-of-bounds reads and memory leaks, which immediately piques my interest. It sounds like someone has been digging into the firmware parsing logic for the MM81x chipset and found some nasties. Specifically, they've added length checks in `mm81x_fw_parse_info`, `mm81x_fw_read_ext_host_table`, and `mm81x_fw_parse_ext_host_tbl` – good, defensive programming, exactly what's needed when dealing with potentially untrusted firmware data structures. They've also cleaned up a memory leak in `mm81x_fw_load_fw` by correctly handling the cleanup path. Smart use of `goto out_free` there, much cleaner than a direct return. My immediate follow-up thought is about the attack surface. Is this driver even reachable in a typical virtualized environment? The driver itself is, as the code reveals, `mm81x` from Morse Micro. I need to quickly determine the likelihood of exploitation. I'll need to check the Kconfig to see if the driver is commonly enabled in configurations relevant to virtualization, containers, or embedded systems where this kind of vulnerability would be most impactful. |
| 4/2 | 2026/08/12 07:04 | tool | grepper |
0mArgs:{
"Expression": "mm81x",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 4846 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/morsemicro/Kconfig=13=if WLAN_VENDOR_MORSEMICRO\ndrivers/net/wireless/morsemicro/Kconfig:14:source \"drivers/net/wireless/morsemicro/mm81x/Kconfig\"\ndrivers/net/wireless/morsemicro/Kconfig-15-endif # WLAN_VENDOR_MORSEMICRO\n--\ndrivers/net/wireless/morsemicro/Makefile-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/net/wireless/morsemicro/Makefile:2:obj-$(CONFIG_MM81X) += mm81x/\n--\ndrivers/net/wireless/morsemicro/mm81x/Makefile-2-\ndrivers/net/wireless/morsemicro/mm81x/Makefile:3:obj-$(CONFIG_MM81X) += mm81x_core.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile-4-\ndrivers/net/wireless/morsemicro/mm81x/Makefile:5:mm81x_core-y += core.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:6:mm81x_core-y += mac.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:7:mm81x_core-y += hw.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:8:mm81x_core-y += fw.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:9:mm81x_core-y += command.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:10:mm81x_core-y += ps.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:11:mm81x_core-y += skbq.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:12:mm81x_core-y += yaps_hw.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:13:mm81x_core-y += yaps.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:14:mm81x_core-y += rc.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:15:mm81x_core-y += mmrc.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile-16-\ndrivers/net/wireless/morsemicro/mm81x/Makefile:17:obj-$(CONFIG_MM81X_USB) += mm81x_usb.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:18:mm81x_usb-y += usb.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile-19-\ndrivers/net/wireless/morsemicro/mm81x/Makefile:20:obj-$(CONFIG_MM81X_SDIO) += mm81x_sdio.o\ndrivers/net/wireless/morsemicro/mm81x/Makefile:21:mm81x_sdio-y += sdio.o\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-11-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:12:enum mm81x_bus_type {\ndrivers/net/wireless/morsemicro/mm81x/bus.h-13-\tMM81X_BUS_TYPE_USB,\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-16-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:17:struct mm81x_bus_ops {\ndrivers/net/wireless/morsemicro/mm81x/bus.h:18:\tint (*dm_read)(struct mm81x *mors, u32 addr, u8 *data, int len);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:19:\tint (*dm_write)(struct mm81x *mors, u32 addr, const u8 *data, int len);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:20:\tint (*reg32_read)(struct mm81x *mors, u32 addr, u32 *data);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:21:\tint (*reg32_write)(struct mm81x *mors, u32 addr, u32 data);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:22:\tint (*digital_reset)(struct mm81x *mors);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:23:\tvoid (*set_bus_enable)(struct mm81x *mors, bool enable);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:24:\tvoid (*config_burst_mode)(struct mm81x *mors, bool enable_burst);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:25:\tvoid (*claim)(struct mm81x *mors);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:26:\tvoid (*set_irq)(struct mm81x *mors, bool enable);\ndrivers/net/wireless/morsemicro/mm81x/bus.h:27:\tvoid (*release)(struct mm81x *mors);\ndrivers/net/wireless/morsemicro/mm81x/bus.h-28-\tunsigned int bulk_alignment;\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-36-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:37:/* mm81x_dm_read - len must be rounded up to the nearest 4-byte boundary */\ndrivers/net/wireless/morsemicro/mm81x/bus.h:38:static inline int mm81x_dm_read(struct mm81x *mors, u32 addr, u8 *data, int len)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-39-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-42-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:43:static inline int mm81x_dm_write(struct mm81x *mors, u32 addr, const u8 *data,\ndrivers/net/wireless/morsemicro/mm81x/bus.h-44-\t\t\t\t int len)\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-48-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:49:static inline int mm81x_reg32_read(struct mm81x *mors, u32 addr, u32 *data)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-50-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-53-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:54:static inline int mm81x_reg32_write(struct mm81x *mors, u32 addr, u32 data)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-55-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-58-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:59:static inline int mm81x_bus_digital_reset(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-60-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-66-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:67:static inline void mm81x_set_bus_enable(struct mm81x *mors, bool enable)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-68-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-71-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:72:static inline void mm81x_bus_config_burst_mode(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/bus.h-73-\t\t\t\t\t bool enable_burst)\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-78-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:79:static inline void mm81x_claim_bus(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-80-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-83-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:84:static inline void mm81x_bus_set_irq(struct mm81x *mors, bool enable)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-85-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-88-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:89:static inline void mm81x_release_bus(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-90-{\n--\ndrivers/net/wireless/morsemicro/mm81x/bus.h-93-\ndrivers/net/wireless/morsemicro/mm81x/bus.h:94:static inline unsigned int mm81x_bus_get_alignment(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/bus.h-95-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c=27=struct host_cmd_resp_cb {\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-32-\ndrivers/net/wireless/morsemicro/mm81x/command.c:33:static int mm81x_cmd_tx(struct mm81x *mors, struct host_cmd_resp *resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-34-\t\t\tstruct host_cmd_req *req, u32 length, u32 timeout)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-41-\tstruct sk_buff *skb;\ndrivers/net/wireless/morsemicro/mm81x/command.c:42:\tstruct mm81x_skbq *cmd_q = mm81x_hif_get_tx_cmd_queue(mors);\ndrivers/net/wireless/morsemicro/mm81x/command.c-43-\tstruct host_cmd_resp_cb *resp_cb;\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-57-\ndrivers/net/wireless/morsemicro/mm81x/command.c:58:\tmm81x_ps_disable(mors);\ndrivers/net/wireless/morsemicro/mm81x/command.c-59-\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-62-\ndrivers/net/wireless/morsemicro/mm81x/command.c:63:\t\tskb = mm81x_skbq_alloc_skb(cmd_q, cmd_len);\ndrivers/net/wireless/morsemicro/mm81x/command.c-64-\t\tif (!skb) {\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-83-\t\ttimeout = timeout ? timeout : HOST_CMD_DEFAULT_TIMEOUT_MS;\ndrivers/net/wireless/morsemicro/mm81x/command.c:84:\t\tret = mm81x_skbq_skb_tx(cmd_q, \u0026skb, NULL,\ndrivers/net/wireless/morsemicro/mm81x/command.c-85-\t\t\t\t\tMM81X_SKB_CHAN_COMMAND);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-88-\t\tif (ret) {\ndrivers/net/wireless/morsemicro/mm81x/command.c:89:\t\t\tdev_err(mors-\u003edev, \"mm81x_skbq_tx fail: %d\", ret);\ndrivers/net/wireless/morsemicro/mm81x/command.c-90-\t\t\tbreak;\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-121-\t\tspin_lock_bh(\u0026cmd_q-\u003elock);\ndrivers/net/wireless/morsemicro/mm81x/command.c:122:\t\tmm81x_skbq_skb_finish(cmd_q, skb, NULL);\ndrivers/net/wireless/morsemicro/mm81x/command.c-123-\t\tspin_unlock_bh(\u0026cmd_q-\u003elock);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-128-\ndrivers/net/wireless/morsemicro/mm81x/command.c:129:\tmm81x_ps_enable(mors);\ndrivers/net/wireless/morsemicro/mm81x/command.c-130-\tmutex_unlock(\u0026mors-\u003ecmd_wait);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-145-\ndrivers/net/wireless/morsemicro/mm81x/command.c:146:int mm81x_cmd_resp_process(struct mm81x *mors, struct sk_buff *skb)\ndrivers/net/wireless/morsemicro/mm81x/command.c-147-{\ndrivers/net/wireless/morsemicro/mm81x/command.c-148-\tint length, ret = -ESRCH; /* No such process */\ndrivers/net/wireless/morsemicro/mm81x/command.c:149:\tstruct mm81x_skbq *cmd_q = mm81x_hif_get_tx_cmd_queue(mors);\ndrivers/net/wireless/morsemicro/mm81x/command.c-150-\tstruct host_cmd_resp *src_resp = (struct host_cmd_resp *)(skb-\u003edata);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-163-\tif (!HOST_CMD_IS_RESP(src_resp)) {\ndrivers/net/wireless/morsemicro/mm81x/command.c:164:\t\tret = mm81x_mac_event_recv(mors, skb);\ndrivers/net/wireless/morsemicro/mm81x/command.c-165-\t\tgoto exit_free;\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-169-\ndrivers/net/wireless/morsemicro/mm81x/command.c:170:\tcmd_skb = mm81x_skbq_tx_pending(cmd_q);\ndrivers/net/wireless/morsemicro/mm81x/command.c-171-\tif (cmd_skb) {\ndrivers/net/wireless/morsemicro/mm81x/command.c:172:\t\tmm81x_skbq_pull_hdr_post_tx(cmd_skb);\ndrivers/net/wireless/morsemicro/mm81x/command.c-173-\t\treq = (struct host_cmd_req *)cmd_skb-\u003edata;\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-231-\ndrivers/net/wireless/morsemicro/mm81x/command.c:232:int mm81x_cmd_sta_state(struct mm81x *mors, struct mm81x_vif *mors_vif, u16 aid,\ndrivers/net/wireless/morsemicro/mm81x/command.c-233-\t\t\tstruct ieee80211_sta *sta,\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-245-\ndrivers/net/wireless/morsemicro/mm81x/command.c:246:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-247-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-248-\ndrivers/net/wireless/morsemicro/mm81x/command.c:249:int mm81x_cmd_add_if(struct mm81x *mors, u16 *vif_id, const u8 *addr,\ndrivers/net/wireless/morsemicro/mm81x/command.c-250-\t\t enum nl80211_iftype type)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-270-\ndrivers/net/wireless/morsemicro/mm81x/command.c:271:\tret = mm81x_cmd_tx(mors, (struct host_cmd_resp *)\u0026resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-272-\t\t\t (struct host_cmd_req *)\u0026req, sizeof(resp), 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-278-\ndrivers/net/wireless/morsemicro/mm81x/command.c:279:int mm81x_cmd_get_capabilities(struct mm81x *mors, u16 vif_id,\ndrivers/net/wireless/morsemicro/mm81x/command.c:280:\t\t\t struct mm81x_fw_caps *capabilities)\ndrivers/net/wireless/morsemicro/mm81x/command.c-281-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-288-\ndrivers/net/wireless/morsemicro/mm81x/command.c:289:\tret = mm81x_cmd_tx(mors, (struct host_cmd_resp *)\u0026rsp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-290-\t\t\t (struct host_cmd_req *)\u0026req, sizeof(rsp), 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-294-\tcapabilities-\u003eampdu_mss = rsp.capabilities.ampdu_mss;\ndrivers/net/wireless/morsemicro/mm81x/command.c:295:\tcapabilities-\u003emm81x_mmss_offset = rsp.morse_mmss_offset;\ndrivers/net/wireless/morsemicro/mm81x/command.c-296-\tcapabilities-\u003ebeamformee_sts_capability =\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-307-\ndrivers/net/wireless/morsemicro/mm81x/command.c:308:int mm81x_cmd_get_max_txpower(struct mm81x *mors, s32 *out_power_mbm)\ndrivers/net/wireless/morsemicro/mm81x/command.c-309-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-315-\ndrivers/net/wireless/morsemicro/mm81x/command.c:316:\tret = mm81x_cmd_tx(mors, (struct host_cmd_resp *)\u0026resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-317-\t\t\t (struct host_cmd_req *)\u0026req, sizeof(resp), 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-323-\ndrivers/net/wireless/morsemicro/mm81x/command.c:324:int mm81x_cmd_hw_scan(struct mm81x *mors, struct mm81x_hw_scan_params *params,\ndrivers/net/wireless/morsemicro/mm81x/command.c-325-\t\t bool store)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-332-\ndrivers/net/wireless/morsemicro/mm81x/command.c:333:\tcmd_size = mm81x_hw_scan_h_get_cmd_size(params);\ndrivers/net/wireless/morsemicro/mm81x/command.c-334-\tcmd_size = ROUND_BYTES_TO_WORD(cmd_size);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-352-\t\treq-\u003edwell_time_ms = cpu_to_le32(params-\u003edwell_time_ms);\ndrivers/net/wireless/morsemicro/mm81x/command.c:353:\t\tbuf = mm81x_hw_scan_h_insert_tlvs(params, buf);\ndrivers/net/wireless/morsemicro/mm81x/command.c-354-\t}\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-358-\treq-\u003ehdr.len = cpu_to_le16((u16)((buf - (u8 *)req) - sizeof(req-\u003ehdr)));\ndrivers/net/wireless/morsemicro/mm81x/command.c:359:\tret = mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-360-\tkfree(req);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-364-\ndrivers/net/wireless/morsemicro/mm81x/command.c:365:int mm81x_cmd_set_txpower(struct mm81x *mors, s32 *out_power_mbm,\ndrivers/net/wireless/morsemicro/mm81x/command.c-366-\t\t\t int txpower_mbm)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-374-\ndrivers/net/wireless/morsemicro/mm81x/command.c:375:\tret = mm81x_cmd_tx(mors, (struct host_cmd_resp *)\u0026resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-376-\t\t\t (struct host_cmd_req *)\u0026req, sizeof(resp), 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-382-\ndrivers/net/wireless/morsemicro/mm81x/command.c:383:int mm81x_cmd_set_channel(struct mm81x *mors, u32 op_chan_freq_hz,\ndrivers/net/wireless/morsemicro/mm81x/command.c-384-\t\t\t u8 pri_1mhz_chan_idx, u8 op_bw_mhz, u8 pri_bw_mhz,\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-397-\ndrivers/net/wireless/morsemicro/mm81x/command.c:398:\tret = mm81x_cmd_tx(mors, (struct host_cmd_resp *)\u0026resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-399-\t\t\t (struct host_cmd_req *)\u0026req, sizeof(resp), 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-405-\ndrivers/net/wireless/morsemicro/mm81x/command.c:406:int mm81x_cmd_disable_key(struct mm81x *mors, struct mm81x_vif *mors_vif,\ndrivers/net/wireless/morsemicro/mm81x/command.c-407-\t\t\t u16 aid, struct ieee80211_key_conf *key)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-418-\ndrivers/net/wireless/morsemicro/mm81x/command.c:419:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-420-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-421-\ndrivers/net/wireless/morsemicro/mm81x/command.c:422:int mm81x_cmd_install_key(struct mm81x *mors, struct mm81x_vif *mors_vif,\ndrivers/net/wireless/morsemicro/mm81x/command.c-423-\t\t\t u16 aid, struct ieee80211_key_conf *key,\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-445-\ndrivers/net/wireless/morsemicro/mm81x/command.c:446:\tret = mm81x_cmd_tx(mors, (struct host_cmd_resp *)\u0026resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-447-\t\t\t (struct host_cmd_req *)\u0026req, sizeof(resp), 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-456-\ndrivers/net/wireless/morsemicro/mm81x/command.c:457:int mm81x_cmd_cfg_multicast_filter(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/command.c:458:\t\t\t\t struct mm81x_vif *mors_vif)\ndrivers/net/wireless/morsemicro/mm81x/command.c-459-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-474-\ndrivers/net/wireless/morsemicro/mm81x/command.c:475:\tret = mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-476-\tkfree(req);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-479-\ndrivers/net/wireless/morsemicro/mm81x/command.c:480:int mm81x_cmd_cfg_bss(struct mm81x *mors, u16 vif_id, u16 beacon_int,\ndrivers/net/wireless/morsemicro/mm81x/command.c-481-\t\t u16 dtim_period, u32 cssid)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-489-\ndrivers/net/wireless/morsemicro/mm81x/command.c:490:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-491-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-492-\ndrivers/net/wireless/morsemicro/mm81x/command.c:493:int mm81x_cmd_config_beacon_timer(struct mm81x *mors, void *mm81x_vif,\ndrivers/net/wireless/morsemicro/mm81x/command.c-494-\t\t\t\t bool enabled)\ndrivers/net/wireless/morsemicro/mm81x/command.c-495-{\ndrivers/net/wireless/morsemicro/mm81x/command.c:496:\tstruct mm81x_vif *vif = mm81x_vif;\ndrivers/net/wireless/morsemicro/mm81x/command.c-497-\tstruct host_cmd_req_bss_beacon_config req = {\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-502-\ndrivers/net/wireless/morsemicro/mm81x/command.c:503:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-504-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-505-\ndrivers/net/wireless/morsemicro/mm81x/command.c:506:int mm81x_cmd_set_ps(struct mm81x *mors, bool enabled)\ndrivers/net/wireless/morsemicro/mm81x/command.c-507-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-512-\ndrivers/net/wireless/morsemicro/mm81x/command.c:513:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0,\ndrivers/net/wireless/morsemicro/mm81x/command.c-514-\t\t\t HOST_CMD_POWERSAVE_TIMEOUT_MS);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-516-\ndrivers/net/wireless/morsemicro/mm81x/command.c:517:int mm81x_cmd_cfg_qos(struct mm81x *mors, struct mm81x_queue_params *params)\ndrivers/net/wireless/morsemicro/mm81x/command.c-518-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-528-\ndrivers/net/wireless/morsemicro/mm81x/command.c:529:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-530-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-531-\ndrivers/net/wireless/morsemicro/mm81x/command.c:532:int mm81x_cmd_rm_if(struct mm81x *mors, u16 vif_id)\ndrivers/net/wireless/morsemicro/mm81x/command.c-533-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-537-\ndrivers/net/wireless/morsemicro/mm81x/command.c:538:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-539-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-540-\ndrivers/net/wireless/morsemicro/mm81x/command.c:541:int mm81x_cmd_set_frag_threshold(struct mm81x *mors, u32 frag_threshold)\ndrivers/net/wireless/morsemicro/mm81x/command.c-542-{\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-549-\ndrivers/net/wireless/morsemicro/mm81x/command.c:550:\treturn mm81x_cmd_tx(mors, NULL, (struct host_cmd_req *)\u0026req, 0, 0);\ndrivers/net/wireless/morsemicro/mm81x/command.c-551-}\ndrivers/net/wireless/morsemicro/mm81x/command.c-552-\ndrivers/net/wireless/morsemicro/mm81x/command.c:553:int mm81x_cmd_get_disabled_channels(\ndrivers/net/wireless/morsemicro/mm81x/command.c:554:\tstruct mm81x *mors, struct host_cmd_resp_get_disabled_channels *resp,\ndrivers/net/wireless/morsemicro/mm81x/command.c-555-\tuint resp_len)\n--\ndrivers/net/wireless/morsemicro/mm81x/command.c-560-\ndrivers/net/wireless/morsemicro/mm81x/command.c:561:\treturn mm81x_cmd_tx(mors, (struct host_cmd_resp *)resp, \u0026req, resp_len,\ndrivers/net/wireless/morsemicro/mm81x/command.c-562-\t\t\t 0);\n--\ndrivers/net/wireless/morsemicro/mm81x/command.h-18-\ndrivers/net/wireless/morsemicro/mm81x/command.h:19:struct mm81x_queue_params;\ndrivers/net/wireless/morsemicro/mm81x/command.h-20-\ndrivers/net/wireless/morsemicro/mm81x/command.h:21:enum mm81x_cmd_return_code {\ndrivers/net/wireless/morsemicro/mm81x/command.h-22-\tMM81X_RET_SUCCESS = 0,\n--\ndrivers/net/wireless/morsemicro/mm81x/command.h=44=struct host_cmd_event {\n--\ndrivers/net/wireless/morsemicro/mm81x/command.h-48-\ndrivers/net/wireless/morsemicro/mm81x/command.h:49:int mm81x_cmd_resp_process(struct mm81x *mors, struct sk_buff *skb);\ndrivers/net/wireless/morsemicro/mm81x/command.h:50:int mm81x_cmd_add_if(struct mm81x *mors, u16 *vif_id, const u8 *addr,\ndrivers/net/wireless/morsemicro/mm81x/command.h-51-\t\t enum nl80211_iftype type);\ndrivers/net/wireless/morsemicro/mm81x/command.h:52:int mm81x_cmd_get_capabilities(struct mm81x *mors, u16 vif_id,\ndrivers/net/wireless/morsemicro/mm81x/command.h:53:\t\t\t struct mm81x_fw_caps *capabilities);\ndrivers/net/wireless/morsemicro/mm81x/command.h:54:int mm81x_cmd_cfg_qos(struct mm81x *mors, struct mm81x_queue_params *params);\ndrivers/net/wireless/morsemicro/mm81x/command.h:55:int mm81x_cmd_config_beacon_timer(struct mm81x *mors, void *mm81x_vif,\ndrivers/net/wireless/morsemicro/mm81x/command.h-56-\t\t\t\t bool enabled);\ndrivers/net/wireless/morsemicro/mm81x/command.h:57:int mm81x_cmd_cfg_bss(struct mm81x *mors, u16 vif_id, u16 beacon_int,\ndrivers/net/wireless/morsemicro/mm81x/command.h-58-\t\t u16 dtim_period, u32 cssid);\ndrivers/net/wireless/morsemicro/mm81x/command.h:59:int mm81x_cmd_set_channel(struct mm81x *mors, u32 op_chan_freq_hz,\ndrivers/net/wireless/morsemicro/mm81x/command.h-60-\t\t\t u8 pri_1mhz_chan_idx, u8 op_bw_mhz, u8 pri_bw_mhz,\ndrivers/net/wireless/morsemicro/mm81x/command.h-61-\t\t\t s32 *power_mbm);\ndrivers/net/wireless/morsemicro/mm81x/command.h:62:int mm81x_cmd_get_max_txpower(struct mm81x *mors, s32 *out_power_mbm);\ndrivers/net/wireless/morsemicro/mm81x/command.h:63:int mm81x_cmd_set_txpower(struct mm81x *mors, s32 *out_power_mbm,\ndrivers/net/wireless/morsemicro/mm81x/command.h-64-\t\t\t int txpower_mbm);\ndrivers/net/wireless/morsemicro/mm81x/command.h:65:int mm81x_cmd_hw_scan(struct mm81x *mors, struct mm81x_hw_scan_params *params,\ndrivers/net/wireless/morsemicro/mm81x/command.h-66-\t\t bool store);\ndrivers/net/wireless/morsemicro/mm81x/command.h:67:int mm81x_cmd_set_ps(struct mm81x *mors, bool enabled);\ndrivers/net/wireless/morsemicro/mm81x/command.h:68:int mm81x_cmd_cfg_multicast_filter(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/command.h:69:\t\t\t\t struct mm81x_vif *mors_vif);\ndrivers/net/wireless/morsemicro/mm81x/command.h:70:int mm81x_cmd_sta_state(struct mm81x *mors, struct mm81x_vif *mors_vif, u16 aid,\ndrivers/net/wireless/morsemicro/mm81x/command.h-71-\t\t\tstruct ieee80211_sta *sta,\ndrivers/net/wireless/morsemicro/mm81x/command.h-72-\t\t\tenum ieee80211_sta_state state);\ndrivers/net/wireless/morsemicro/mm81x/command.h:73:int mm81x_cmd_install_key(struct mm81x *mors, struct mm81x_vif *mors_vif,\ndrivers/net/wireless/morsemicro/mm81x/command.h-74-\t\t\t u16 aid, struct ieee80211_key_conf *key,\n--\ndrivers/net/wireless/morsemicro/mm81x/command.h-76-\t\t\t enum host_cmd_aes_key_len length);\ndrivers/net/wireless/morsemicro/mm81x/command.h:77:int mm81x_cmd_disable_key(struct mm81x *mors, struct mm81x_vif *mors_vif,\ndrivers/net/wireless/morsemicro/mm81x/command.h-78-\t\t\t u16 aid, struct ieee80211_key_conf *key);\ndrivers/net/wireless/morsemicro/mm81x/command.h:79:int mm81x_cmd_rm_if(struct mm81x *mors, u16 vif_id);\ndrivers/net/wireless/morsemicro/mm81x/command.h:80:int mm81x_cmd_set_frag_threshold(struct mm81x *mors, u32 frag_threshold);\ndrivers/net/wireless/morsemicro/mm81x/command.h:81:int mm81x_cmd_get_disabled_channels(\ndrivers/net/wireless/morsemicro/mm81x/command.h:82:\tstruct mm81x *mors, struct host_cmd_resp_get_disabled_channels *resp,\ndrivers/net/wireless/morsemicro/mm81x/command.h-83-\tuint resp_len);\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-10-\ndrivers/net/wireless/morsemicro/mm81x/core.c:11:static int mm81x_core_attach_regs(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-12-{\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-14-\ndrivers/net/wireless/morsemicro/mm81x/core.c:15:\tmm81x_claim_bus(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c:16:\tret = mm81x_reg32_read(mors, MM8108_REG_CHIP_ID, \u0026mors-\u003echip_id);\ndrivers/net/wireless/morsemicro/mm81x/core.c:17:\tmm81x_release_bus(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-18-\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-26-\t\tmors-\u003eregs = \u0026mm8108_regs;\ndrivers/net/wireless/morsemicro/mm81x/core.c:27:\t\tmors-\u003ehif.ops = \u0026mm81x_yaps_ops;\ndrivers/net/wireless/morsemicro/mm81x/core.c-28-\t\tbreak;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-35-\ndrivers/net/wireless/morsemicro/mm81x/core.c:36:static void mm81x_core_init_mac_addr(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-37-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:38:\tint ret = mm81x_hw_otp_get_mac_addr(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-39-\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-43-\ndrivers/net/wireless/morsemicro/mm81x/core.c:44:char *mm81x_core_get_fw_path(u32 chip_id, u32 fw_ver)\ndrivers/net/wireless/morsemicro/mm81x/core.c-45-{\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-58-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:59:EXPORT_SYMBOL_GPL(mm81x_core_get_fw_path);\ndrivers/net/wireless/morsemicro/mm81x/core.c-60-\ndrivers/net/wireless/morsemicro/mm81x/core.c:61:struct mm81x *mm81x_core_alloc(size_t priv_size, struct device *dev)\ndrivers/net/wireless/morsemicro/mm81x/core.c-62-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:63:\treturn mm81x_mac_alloc(priv_size, dev);\ndrivers/net/wireless/morsemicro/mm81x/core.c-64-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:65:EXPORT_SYMBOL_GPL(mm81x_core_alloc);\ndrivers/net/wireless/morsemicro/mm81x/core.c-66-\ndrivers/net/wireless/morsemicro/mm81x/core.c:67:int mm81x_core_init(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-68-{\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-73-\ndrivers/net/wireless/morsemicro/mm81x/core.c:74:\tmm81x_core_init_mac_addr(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-75-\ndrivers/net/wireless/morsemicro/mm81x/core.c:76:\tret = mm81x_core_attach_regs(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-77-\tif (ret)\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-89-\ndrivers/net/wireless/morsemicro/mm81x/core.c:90:\tret = mm81x_hif_init(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-91-\tif (ret)\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-105-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:106:EXPORT_SYMBOL_GPL(mm81x_core_init);\ndrivers/net/wireless/morsemicro/mm81x/core.c-107-\ndrivers/net/wireless/morsemicro/mm81x/core.c:108:int mm81x_core_register(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-109-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:110:\treturn mm81x_mac_register(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-111-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:112:EXPORT_SYMBOL_GPL(mm81x_core_register);\ndrivers/net/wireless/morsemicro/mm81x/core.c-113-\ndrivers/net/wireless/morsemicro/mm81x/core.c:114:void mm81x_core_unregister(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-115-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:116:\tmm81x_mac_unregister(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-117-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:118:EXPORT_SYMBOL_GPL(mm81x_core_unregister);\ndrivers/net/wireless/morsemicro/mm81x/core.c-119-\ndrivers/net/wireless/morsemicro/mm81x/core.c:120:void mm81x_core_deinit(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-121-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:122:\tmm81x_hif_finish(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-123-\tflush_workqueue(mors-\u003enet_wq);\n--\ndrivers/net/wireless/morsemicro/mm81x/core.c-127-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:128:EXPORT_SYMBOL_GPL(mm81x_core_deinit);\ndrivers/net/wireless/morsemicro/mm81x/core.c-129-\ndrivers/net/wireless/morsemicro/mm81x/core.c:130:void mm81x_core_free(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-131-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:132:\tmm81x_mac_free(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-133-}\ndrivers/net/wireless/morsemicro/mm81x/core.c:134:EXPORT_SYMBOL_GPL(mm81x_core_free);\ndrivers/net/wireless/morsemicro/mm81x/core.c-135-\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-54-\ndrivers/net/wireless/morsemicro/mm81x/core.h:55:struct mm81x_bus_ops;\ndrivers/net/wireless/morsemicro/mm81x/core.h:56:struct mm81x_hif_ops;\ndrivers/net/wireless/morsemicro/mm81x/core.h-57-\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-62-\ndrivers/net/wireless/morsemicro/mm81x/core.h:63:enum mm81x_caps_flags {\ndrivers/net/wireless/morsemicro/mm81x/core.h-64-\tMM81X_CAPS_FW_START = 0,\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-131-\ndrivers/net/wireless/morsemicro/mm81x/core.h:132:struct mm81x_fw_caps {\ndrivers/net/wireless/morsemicro/mm81x/core.h-133-\tu32 flags[FW_CAPABILITIES_FLAGS_WIDTH];\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-137-\tu8 maximum_ampdu_length_exponent;\ndrivers/net/wireless/morsemicro/mm81x/core.h:138:\tu8 mm81x_mmss_offset;\ndrivers/net/wireless/morsemicro/mm81x/core.h-139-};\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-141-#define MM81X_FW_SUPP(MM81X_CAPS, CAPABILITY) \\\ndrivers/net/wireless/morsemicro/mm81x/core.h:142:\tmm81x_caps_supported(MM81X_CAPS, MM81X_CAPS_##CAPABILITY)\ndrivers/net/wireless/morsemicro/mm81x/core.h-143-\ndrivers/net/wireless/morsemicro/mm81x/core.h:144:static inline bool mm81x_caps_supported(struct mm81x_fw_caps *caps,\ndrivers/net/wireless/morsemicro/mm81x/core.h:145:\t\t\t\t\tenum mm81x_caps_flags flag)\ndrivers/net/wireless/morsemicro/mm81x/core.h-146-{\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-151-\ndrivers/net/wireless/morsemicro/mm81x/core.h:152:struct mm81x_ps {\ndrivers/net/wireless/morsemicro/mm81x/core.h-153-\tu32 wakers;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-160-\ndrivers/net/wireless/morsemicro/mm81x/core.h:161:enum mm81x_page_aci {\ndrivers/net/wireless/morsemicro/mm81x/core.h-162-\tMM81X_ACI_BE = 0,\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-167-\ndrivers/net/wireless/morsemicro/mm81x/core.h:168:enum mm81x_qos_tid_up_index {\ndrivers/net/wireless/morsemicro/mm81x/core.h-169-\tMM81X_QOS_TID_UP_BK = 1,\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-181-\ndrivers/net/wireless/morsemicro/mm81x/core.h:182:struct mm81x_sw_version {\ndrivers/net/wireless/morsemicro/mm81x/core.h-183-\tu8 major;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-187-\ndrivers/net/wireless/morsemicro/mm81x/core.h:188:struct mm81x_sta {\ndrivers/net/wireless/morsemicro/mm81x/core.h-189-\tconst struct ieee80211_vif *vif;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-195-\tint max_bw_mhz;\ndrivers/net/wireless/morsemicro/mm81x/core.h:196:\tstruct mm81x_rc_sta rc;\ndrivers/net/wireless/morsemicro/mm81x/core.h-197-\tstruct mmrc_rate last_sta_tx_rate;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-201-\ndrivers/net/wireless/morsemicro/mm81x/core.h:202:struct mm81x_vif {\ndrivers/net/wireless/morsemicro/mm81x/core.h:203:\tstruct mm81x *mors;\ndrivers/net/wireless/morsemicro/mm81x/core.h-204-\tu16 id;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-216-\ndrivers/net/wireless/morsemicro/mm81x/core.h:217:struct mm81x_stale_tx_status {\ndrivers/net/wireless/morsemicro/mm81x/core.h-218-\t/* Stale Tx lock */\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h=223=struct mcast_filter {\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-232-\ndrivers/net/wireless/morsemicro/mm81x/core.h:233:enum mm81x_hw_scan_op {\ndrivers/net/wireless/morsemicro/mm81x/core.h-234-\tMM81X_HW_SCAN_OP_START,\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-237-\ndrivers/net/wireless/morsemicro/mm81x/core.h:238:struct mm81x_hw_scan_params {\ndrivers/net/wireless/morsemicro/mm81x/core.h-239-\tstruct ieee80211_hw *hw;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-245-\tu32 dwell_on_home_ms;\ndrivers/net/wireless/morsemicro/mm81x/core.h:246:\tenum mm81x_hw_scan_op operation;\ndrivers/net/wireless/morsemicro/mm81x/core.h-247-\tbool store;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-261-\ndrivers/net/wireless/morsemicro/mm81x/core.h:262:enum mm81x_hw_scan_state {\ndrivers/net/wireless/morsemicro/mm81x/core.h-263-\tHW_SCAN_STATE_IDLE,\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-267-\ndrivers/net/wireless/morsemicro/mm81x/core.h:268:struct mm81x_hw_scan {\ndrivers/net/wireless/morsemicro/mm81x/core.h:269:\tenum mm81x_hw_scan_state state;\ndrivers/net/wireless/morsemicro/mm81x/core.h-270-\tstruct completion scan_done;\ndrivers/net/wireless/morsemicro/mm81x/core.h:271:\tstruct mm81x_hw_scan_params *params;\ndrivers/net/wireless/morsemicro/mm81x/core.h-272-\tstruct delayed_work timeout;\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-275-\ndrivers/net/wireless/morsemicro/mm81x/core.h:276:enum mm81x_hif_event_flags {\ndrivers/net/wireless/morsemicro/mm81x/core.h-277-\tMM81X_HIF_EVT_RX_PEND,\n--\ndrivers/net/wireless/morsemicro/mm81x/core.h-288-\ndrivers/net/wireless/morsemicro/mm81x/core.h:289:enum mm81x_state_flags {\ndrivers/net/wireless/morsemicro/mm81x/core.h-290-\tMM81X_STATE_CHIP_UNRESPONSIVE,\n--\n\n"
} |
| 5/2 | 2026/08/12 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19165 output: 40 thoughts: 200 Thoughts: **Analyzing the MM81X Driver and Fuzzing Potential** Okay, so I see this patch targets the MM81X driver, which is only built if `CONFIG_MM81X` is enabled, which is a key starting point. It appears the driver has both USB and SDIO variants – specifically, if `CONFIG_MM81X_USB` or `CONFIG_MM81X_SDIO` are configured. Excellent. This immediately opens up different fuzzing avenues. For USB, the options are pretty clear. I can leverage either the dummy HCD (USB Gadget) or the power of syzkaller's USB fuzzing capabilities. That's a solid path to explore, especially given the established tools. SDIO is also potentially interesting, but it relies on an SDIO emulator. While it's probably feasible, the USB route seems more directly accessible and less reliant on external setup. The specific modification is in `drivers/net/wireless/morsemicro/mm81x/fw.c`. Ah, firmware parsing logic. This is promising! Firmware loading is usually a good target for fuzzing. Firmware is loaded using `request_firmware` or directly from the filesystem. Syzkaller's support for mocking `request_firmware` makes that even more attractive. My immediate next step is to examine the functions `mm81x_fw_load_fw` and `mm81x_fw_parse_ext_host_tbl`. Those are the prime suspects, given the context. These functions will be the focal point to identify potential vulnerabilities within the firmware loading and parsing process. I'll need to dissect the logic within those functions to determine how syzkaller can be used to generate effective fuzzing inputs. |
| 6/2 | 2026/08/12 07:04 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_load_fw",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=99=static int mm81x_fw_set_boot_addr(struct mm81x *mors, uint32_t addr)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-109-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:110:static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)\ndrivers/net/wireless/morsemicro/mm81x/fw.c-111-{\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c=627=static int __mm81x_fw_flash(struct mm81x *mors, const struct firmware *fw,\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-643-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:644:\tret = mm81x_fw_load_fw(mors, fw);\ndrivers/net/wireless/morsemicro/mm81x/fw.c-645-\tif (ret)\n"
} |
| 7/2 | 2026/08/12 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20096 output: 39 thoughts: 26 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Analyzing Firmware Flashpoint** Right, so the firmware loading process kicks off in `__mm81x_fw_flash`. Seems like a sensible naming convention. Now, the key is to understand the calling context. Gotta trace back through the code and figure out the entry point and the execution flow leading up to that function call. Need to see where the firmware image is coming from (external storage, network, etc.) and what triggers the flash operation. Understanding the preconditions before `__mm81x_fw_flash` is crucial for debugging any issues or optimizing the loading process itself. Time to fire up the debugger and start digging into the call stack. |
| 8/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "__mm81x_fw_flash",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=564=int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-626-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:627:static int __mm81x_fw_flash(struct mm81x *mors, const struct firmware *fw,\ndrivers/net/wireless/morsemicro/mm81x/fw.c-628-\t\t\t const struct firmware *bcf, bool reset)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c=666=static int mm81x_fw_flash(struct mm81x *mors, const struct firmware *fw,\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-672-\twhile (retries--) {\ndrivers/net/wireless/morsemicro/mm81x/fw.c:673:\t\tret = __mm81x_fw_flash(mors, fw, bcf, reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.c-674-\t\tif (!ret)\n"
} |
| 9/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20651 output: 38 thoughts: 12 Thoughts: Okay, here's my summary, presented as a stream of thought: **mm81x_fw_flash: A Deep Dive** Alright, let's see... `mm81x_fw_flash`. Hmm, that name triggers something. It immediately suggests a firmware flashing utility, likely for a specific hardware platform – the "mm81x" part is the giveaway. I'd wager it's a proprietary or vendor-specific tool. Now, the questions start popping: Is this a bootloader? A general-purpose firmware updater? Does it operate via JTAG, UART, USB, or something else entirely? What security features are in place? Does it support rollback mechanisms? What about error handling? And, critically, the target devices... are we talking embedded systems, network appliances, or something else? Understanding the hardware context is crucial. I need to know the architecture, memory map, and any hardware-specific quirks. This is all assuming I want to flash new firmware onto the device. What are the possibilities around this type of flashing software. |
| 10/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_flash",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=564=int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-626-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:627:static int __mm81x_fw_flash(struct mm81x *mors, const struct firmware *fw,\ndrivers/net/wireless/morsemicro/mm81x/fw.c-628-\t\t\t const struct firmware *bcf, bool reset)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-665-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:666:static int mm81x_fw_flash(struct mm81x *mors, const struct firmware *fw,\ndrivers/net/wireless/morsemicro/mm81x/fw.c-667-\t\t\t const struct firmware *bcf, bool reset)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-672-\twhile (retries--) {\ndrivers/net/wireless/morsemicro/mm81x/fw.c:673:\t\tret = __mm81x_fw_flash(mors, fw, bcf, reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.c-674-\t\tif (!ret)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c=719=int mm81x_fw_init(struct mm81x *mors, bool reset)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-760-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:761:\tret = mm81x_fw_flash(mors, fw, bcf, reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.c-762-\tif (ret) {\n"
} |
| 11/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 21468 output: 38 thoughts: 12 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Initial Firmware Deep Dive - mm81x_fw_init** Alright, so we're looking at firmware initialization. Specifically, that `mm81x_fw_init` function. Right off the bat, I'm thinking, "Okay, what's *this* doing?" This is where the rubber meets the road, the very first steps in bringing up this particular hardware. We're talking low-level stuff here, I presume. Are we talking about registering the device, configuring clocks, setting up interrupt vectors, memory allocation, or all of the above? What's the context, what's the broader architecture? Is this a driver-specific initialization, or something more global that might influence other functions? Any hardware-specific considerations in this initialization sequence? Does this require any specific flags/options from the userspace application that is calling it? I'm already mentally sketching the call graph and dependencies. I want to see how this function interacts with the hardware, the firmware image itself, and possibly any bootloader or earlier initialization stages. The goal of this process would have to be to make sure everything is in place to begin actual communication and data processing using the device. Gotta dig in and see the details of this one, the nuances of that initialization function. |
| 12/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_init",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=689=static int mm81x_fw_request(struct mm81x *mors, const struct firmware **fw)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-718-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:719:int mm81x_fw_init(struct mm81x *mors, bool reset)\ndrivers/net/wireless/morsemicro/mm81x/fw.c-720-{\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h=134=struct ext_host_tbl {\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h-139-\ndrivers/net/wireless/morsemicro/mm81x/fw.h:140:int mm81x_fw_init(struct mm81x *mors, bool reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.h-141-int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors);\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2107=static int mm81x_mac_restart(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2139-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2140:\tret = mm81x_fw_init(mors, true);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2141-\tif (ret \u003c 0) {\n"
} |
| 13/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 22271 output: 38 thoughts: 26 Thoughts: Here's my thought process, summarized as you requested: **mm81x_fw_init Investigation** Okay, so I'm digging into this `mm81x_fw_init` function. The code says it's called by `mm81x_mac_restart`. That's a good starting point, but I need to be thorough. My immediate question is: where *else* is this function being invoked? Is `mm81x_mac_restart` the only calling function, or is there the possibility of other code paths or drivers or modules that also call `mm81x_fw_init`? I need to track down all the call sites to get a complete picture of its usage and any potential dependencies or edge cases. A solid grasp of every call site will allow me to accurately describe how the function behaves in the system. |
| 14/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_mac_restart",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=2071=static u32 mm81x_get_expected_throughput(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2090-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2091:static void mm81x_mac_restart_cleanup_iter(void *data, u8 *mac,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2092-\t\t\t\t\t struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2097-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2098:static void mm81x_mac_restart_cleanup(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2099-{\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2101-\t\t\t\t\t IEEE80211_IFACE_ITER_NORMAL,\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2102:\t\t\t\t\t mm81x_mac_restart_cleanup_iter,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2103-\t\t\t\t\t NULL);\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2106-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2107:static int mm81x_mac_restart(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2108-{\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2137-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2138:\tmm81x_mac_restart_cleanup(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2139-\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2170=static int mm81x_mac_ops_add_interface(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2180-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2181:\t\tret = mm81x_mac_restart(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2182-\t\tif (ret) {\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2261=static void mm81x_reg_notifier(struct wiphy *wiphy,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2272-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2273:\tret = mm81x_mac_restart(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2274-\tif (ret)\n"
} |
| 15/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23397 output: 38 thoughts: 56 Thoughts: Here's my take on the thought process, as requested: **Digging into the MM81X Driver Architecture** Okay, so I'm tracing the control flow here in the MM81X driver, and it's looking like `mm81x_mac_restart` is a key function. I'm seeing it called from both `mm81x_mac_ops_add_interface` and also the `mm81x_reg_notifier` function. That gives me a good starting point, showing me where the restart action is triggered. This implies that interface addition and some form of registration (likely related to hardware events or reconfiguration) are the events that necessitate a MAC restart. Now I'm pausing... I need to clarify something. Is the firmware initialization, `mm81x_fw_init`, called within the probe function? It's critical for me to understand the boot-up sequence of the hardware so I need to check the probe function, `mm81x_probe`, to make sure that `mm81x_fw_init` is called. If so, and how, that will determine the state of the hardware before a restart is triggered. The timing and sequence are going to be critical for debugging any potential issues in the interface setup or hardware registration paths. |
| 16/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_init",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=689=static int mm81x_fw_request(struct mm81x *mors, const struct firmware **fw)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-718-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:719:int mm81x_fw_init(struct mm81x *mors, bool reset)\ndrivers/net/wireless/morsemicro/mm81x/fw.c-720-{\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h=134=struct ext_host_tbl {\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h-139-\ndrivers/net/wireless/morsemicro/mm81x/fw.h:140:int mm81x_fw_init(struct mm81x *mors, bool reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.h-141-int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors);\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2107=static int mm81x_mac_restart(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2139-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2140:\tret = mm81x_fw_init(mors, true);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2141-\tif (ret \u003c 0) {\n"
} |
| 17/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 24230 output: 38 thoughts: 44 Thoughts: Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person: **Initial Investigation into Driver Initialization Flow** Hang on a minute… I'm starting to think I missed something fundamental here. I was under the impression that `mm81x_fw_init` was part of the standard probe sequence. But looking at the broader picture, that doesn't seem to be the case. My first instinct would be to check that `mm81x_fw_init` is called in other scenarios. Given that it's not in the `probe` function, I need to understand where the firmware initialization *does* occur. I should probably be looking at `mm81x_core_init` next. That's the logical place to start – it's often the root of the core driver initialization, right? Or perhaps the MAC registration function, `mm81x_mac_register`? It's possible the firmware is being handled within that context, especially if the MAC is tightly coupled with the firmware loading. I need to trace this more carefully to see where that function is actually getting called, and what it does. |
| 18/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_mac_register",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/core.c=108=int mm81x_core_register(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/core.c-109-{\ndrivers/net/wireless/morsemicro/mm81x/core.c:110:\treturn mm81x_mac_register(mors);\ndrivers/net/wireless/morsemicro/mm81x/core.c-111-}\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2355=static void mm81x_mac_stale_tx_status_timer_init(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2360-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2361:int mm81x_mac_register(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2362-{\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.h=51=struct mm81x *mm81x_mac_alloc(size_t priv_size, struct device *dev);\ndrivers/net/wireless/morsemicro/mm81x/mac.h:52:int mm81x_mac_register(struct mm81x *mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.h-53-void mm81x_mac_free(struct mm81x *mors);\n"
} |
| 19/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 24990 output: 46 thoughts: 14 Thoughts: Okay, let's dive into this. Here's my take on those thoughts, as if they're my own: **Analyzing `mm81x_mac_register`** Alright, let's take a look at `mm81x_mac_register`. Immediately, I'm thinking about the context. What is this function doing? The name suggests it's likely dealing with registering a Media Access Controller (MAC) device, and the "mm81x" prefix is almost certainly an indicator of the specific hardware or driver it relates to. This probably means there's some device-specific initialization or configuration involved. I'd want to know: * **What are we registering?** Is this a physical MAC, a virtual interface, or something more complex? * **What kind of data structure is involved?** `mm81x_` implies some company or specific hardware, so what's the data structure type for the MAC being used? Is it a standard structure, or proprietary? How do we interface with this structure. * **What is the register map?** `register` implies some address. Are we mapping memory in kernel-space, or some other operation? Do we need to define the register base address? * **What driver model is being used?** Is it a standard network driver framework or something custom? Is it using Netlink, sysfs, or another interface? What are the standard calls being made? * **Are there any mutexes/locks in use?** I'm immediately looking for concurrency protection; MAC devices are often shared resources, so it's critical to ensure proper locking. Race conditions are nasty. * **Error handling?** How does the function handle failures? Does it return error codes, log messages, or something else? Is it a robust check? I'm mentally preparing to trace through the code, looking for initialization sequences, potentially interrupt registration (if it's a hardware MAC), and the actual mechanism of tying the MAC device into the network stack. I'll need to understand how this function fits into the bigger picture of the driver. Let's see how it works! |
| 20/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_init",
"PathPrefix": "drivers/net/wireless/morsemicro/mm81x/mac.c"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=2107=static int mm81x_mac_restart(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2139-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2140:\tret = mm81x_fw_init(mors, true);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2141-\tif (ret \u003c 0) {\n"
} |
| 21/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 25671 output: 46 thoughts: 50 Thoughts: Okay, let me think this through. **Investigating mm81x Firmware Initialization** Right, so I'm digging into this `mm81x` driver code again. It's clear that `mm81x_fw_init` is invoked within `mm81x_mac_restart`. That's the first connection I've identified. Now, the next logical question is whether `mm81x_mac_restart` itself is called within `mm81x_mac_register`. Knowing this relationship is crucial for understanding the complete initialization and restart sequence. It's a key piece of the puzzle to determine the overall state machine and how these functions interact during device bringup or error recovery. |
| 22/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_mac_restart",
"PathPrefix": "drivers/net/wireless/morsemicro/mm81x/mac.c"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/mac.c=2071=static u32 mm81x_get_expected_throughput(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2090-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2091:static void mm81x_mac_restart_cleanup_iter(void *data, u8 *mac,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2092-\t\t\t\t\t struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2097-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2098:static void mm81x_mac_restart_cleanup(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2099-{\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2101-\t\t\t\t\t IEEE80211_IFACE_ITER_NORMAL,\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2102:\t\t\t\t\t mm81x_mac_restart_cleanup_iter,\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2103-\t\t\t\t\t NULL);\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2106-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2107:static int mm81x_mac_restart(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2108-{\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2137-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2138:\tmm81x_mac_restart_cleanup(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2139-\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2170=static int mm81x_mac_ops_add_interface(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2180-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2181:\t\tret = mm81x_mac_restart(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2182-\t\tif (ret) {\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2261=static void mm81x_reg_notifier(struct wiphy *wiphy,\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2272-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2273:\tret = mm81x_mac_restart(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2274-\tif (ret)\n"
} |
| 23/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26798 output: 38 thoughts: 49 Thoughts: Here's my thought process, as if I were analyzing this code: **Analyzing the Interface Addition Procedure** Okay, so `mm81x_mac_ops_add_interface` is the key function triggered when a new interface is added. That makes sense; adding an interface, especially in a wireless context using nl80211, is a significant event. I'm thinking, this function is likely responsible for setting up all the necessary data structures and configurations specific to the new interface within the MAC layer. It’s the entry point to making the interface operational. But before I delve deeper into `mm81x_mac_ops_add_interface`, a quick detour is in order. Let me confirm my understanding and make sure I haven't missed any potential side effects. I want to quickly cross-reference that with `mm81x_mac_register`. I need to ensure the MAC layer is properly initialized and registered first, so the adding can go smoothly. Let me verify the flow of operations. This registration is a foundational piece and influences everything that comes after. I need to make sure I am working with accurate assumptions. |
| 24/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_init",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=689=static int mm81x_fw_request(struct mm81x *mors, const struct firmware **fw)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-718-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:719:int mm81x_fw_init(struct mm81x *mors, bool reset)\ndrivers/net/wireless/morsemicro/mm81x/fw.c-720-{\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h=134=struct ext_host_tbl {\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h-139-\ndrivers/net/wireless/morsemicro/mm81x/fw.h:140:int mm81x_fw_init(struct mm81x *mors, bool reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.h-141-int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors);\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2107=static int mm81x_mac_restart(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2139-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2140:\tret = mm81x_fw_init(mors, true);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2141-\tif (ret \u003c 0) {\n"
} |
| 25/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 27588 output: 46 thoughts: 13 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Initial Diagnostic Query** Right, let's see... what's the first thing that springs to mind, based on the context... Given we're dealing with initialization, the immediate question is always about the core setup. A name like `mm81x_core_init` suggests it's a critical entry point for bringing a specific microcontroller core online. Is this a system I am familiar with? From my years of experience, I can immediately start thinking through potential issues that I would see from the outset. I am immediately going to consider: * Does this initialization handle clock configuration? * What about memory mapping and protection? * Interrupt vector setup? * Peripheral configuration - this is often a minefield! It's likely the starting point for low-level hardware bring-up, which is typically where you find the most subtle and frustrating bugs. Is it calling out to the more specialized subsystem initialization? This seems like a good place to start my investigation. |
| 26/2 | 2026/08/12 07:05 | tool | grepper |
0mError:no matches Args: {
"Expression": "mm81x_fw_init",
"PathPrefix": "drivers/net/wireless/morsemicro/mm81x/core.c"
}Results: {
"error": "no matches"
} |
| 27/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 27894 output: 48 thoughts: 69 Thoughts: Here's my thought process, distilled: **Navigating the `mm81x` Firmware Initialization** Okay, so I'm tracing the execution path of `mm81x_fw_init`. The first thing I need to know is *where* this function is called. Let's start with a quick search to see what's what. Right, looks like it's only called within `mm81x_mac_restart`. Hmm, that seems odd. I'd expect initialization to happen in more places, potentially during driver registration or a power-up sequence. Let me just confirm that. Okay, I've double-checked, and my initial search was correct - it's *only* in `mm81x_mac_restart`. I should probably look at what else is related to the MAC, so I think I will check `mm81x_mac_register` next. |
| 28/2 | 2026/08/12 07:05 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/morsemicro/mm81x/mac.c",
"FirstLine": 2361,
"LineCount": 100
}Results: {
"Contents": "2361:\tint mm81x_mac_register(struct mm81x *mors)\n2362:\t{\n2363:\t\tint ret;\n2364:\t\tstruct ieee80211_hw *hw = mors-\u003ehw;\n2365:\t\n2366:\t\tmors-\u003etx_power_mbm = INT_MAX;\n2367:\t\tmors-\u003etx_max_power_mbm = INT_MAX;\n2368:\t\tmors-\u003erts_threshold = IEEE80211_MAX_RTS_THRESHOLD;\n2369:\t\n2370:\t\tret = mm81x_ps_init(mors);\n2371:\t\tif (ret)\n2372:\t\t\treturn ret;\n2373:\t\n2374:\t\tmm81x_mac_config_hw(mors);\n2375:\t\tmm81x_mac_hw_scan_init(mors);\n2376:\t\tmm81x_mac_stale_tx_status_timer_init(mors);\n2377:\t\n2378:\t\tret = ieee80211_register_hw(hw);\n2379:\t\tif (ret) {\n2380:\t\t\tdev_err(mors-\u003edev, \"ieee80211_register_hw failed %d\", ret);\n2381:\t\t\tmm81x_mac_unregister(mors);\n2382:\t\t\treturn ret;\n2383:\t\t}\n2384:\t\n2385:\t\tmm81x_rc_init(mors);\n2386:\t\n2387:\t\t/*\n2388:\t\t * At this stage, we know bus and pager system interrupts are enabled.\n2389:\t\t * Trigger the receive workqueue to drain any incoming chip-to-host\n2390:\t\t * pending packets been pushed in the period between the firmware\n2391:\t\t * initialization and interrupts being enabled.\n2392:\t\t */\n2393:\t\tset_bit(MM81X_HIF_EVT_RX_PEND, \u0026mors-\u003ehif.event_flags);\n2394:\t\tqueue_work(mors-\u003echip_wq, \u0026mors-\u003ehif_work);\n2395:\t\n2396:\t\treturn ret;\n2397:\t}\n2398:\t\n2399:\tvoid mm81x_mac_unregister(struct mm81x *mors)\n2400:\t{\n2401:\t\tmm81x_ps_disable(mors);\n2402:\t\tmm81x_rc_deinit(mors);\n2403:\t\tmm81x_mac_hw_scan_destroy(mors);\n2404:\t\n2405:\t\tieee80211_stop_queues(mors-\u003ehw);\n2406:\t\tieee80211_unregister_hw(mors-\u003ehw);\n2407:\t\n2408:\t\tmm81x_hif_flush_tx_data(mors);\n2409:\t\tmm81x_hif_flush_cmds(mors);\n2410:\t\tmm81x_stale_tx_status_timer_finish(mors);\n2411:\t\tmm81x_ps_finish(mors);\n2412:\t\n2413:\t\tkfree(mors-\u003emcast_filter);\n2414:\t}\n2415:\t\n2416:\tstruct mm81x *mm81x_mac_alloc(size_t priv_size, struct device *dev)\n2417:\t{\n2418:\t\tstruct ieee80211_hw *hw;\n2419:\t\tstruct mm81x *mors;\n2420:\t\n2421:\t\thw = ieee80211_alloc_hw(sizeof(*mors) + priv_size, \u0026mm81x_ops);\n2422:\t\tif (!hw) {\n2423:\t\t\tdev_err(dev, \"ieee80211_alloc_hw failed\\r\\n\");\n2424:\t\t\treturn NULL;\n2425:\t\t}\n2426:\t\n2427:\t\tSET_IEEE80211_DEV(hw, dev);\n2428:\t\tmemset(hw-\u003epriv, 0, sizeof(*mors));\n2429:\t\n2430:\t\tmors = hw-\u003epriv;\n2431:\t\tmors-\u003ehw = hw;\n2432:\t\tmors-\u003edev = dev;\n2433:\t\tmutex_init(\u0026mors-\u003ecmd_lock);\n2434:\t\tmutex_init(\u0026mors-\u003ecmd_wait);\n2435:\t\tinit_waitqueue_head(\u0026mors-\u003etx_empty_waitq);\n2436:\t\n2437:\t\treturn mors;\n2438:\t}\n2439:\t\n2440:\tvoid mm81x_mac_free(struct mm81x *mors)\n2441:\t{\n2442:\t\tieee80211_free_hw(mors-\u003ehw);\n2443:\t}\n"
} |
| 29/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 29563 output: 46 thoughts: 41 Thoughts: **Investigating the Initialization Sequence** Okay, hold on a second. I was under the impression that `mm81x_fw_init` was always called directly from `mm81x_mac_register`, but I'm not seeing that in the code flow. That's a potential oversight or perhaps a misremembered detail on my part, or a subtle change in the driver structure I'm not immediately grasping. I need to clarify how that firmware initialization is actually happening. Right, let's back up and check the broader initialization scheme. The key seems to lie elsewhere, so I'll need to focus my attention on `mm81x_core_init`. That's where the logical flow is being handled, so that must be where the function is being called. |
| 30/2 | 2026/08/12 07:05 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/morsemicro/mm81x/core.c",
"FirstLine": 67,
"LineCount": 100
}Results: {
"Contents": " 67:\tint mm81x_core_init(struct mm81x *mors)\n 68:\t{\n 69:\t\tint ret;\n 70:\t\n 71:\t\tset_bit(MM81X_STATE_CHIP_UNRESPONSIVE, \u0026mors-\u003estate_flags);\n 72:\t\tset_bit(MM81X_STATE_RELOAD_FW_AFTER_START, \u0026mors-\u003estate_flags);\n 73:\t\n 74:\t\tmm81x_core_init_mac_addr(mors);\n 75:\t\n 76:\t\tret = mm81x_core_attach_regs(mors);\n 77:\t\tif (ret)\n 78:\t\t\treturn ret;\n 79:\t\n 80:\t\tmors-\u003echip_wq = create_singlethread_workqueue(\"chip_wq\");\n 81:\t\tif (!mors-\u003echip_wq)\n 82:\t\t\treturn -ENOMEM;\n 83:\t\n 84:\t\tmors-\u003enet_wq = create_singlethread_workqueue(\"net_wq\");\n 85:\t\tif (!mors-\u003enet_wq) {\n 86:\t\t\tret = -ENOMEM;\n 87:\t\t\tgoto err_chip_wq;\n 88:\t\t}\n 89:\t\n 90:\t\tret = mm81x_hif_init(mors);\n 91:\t\tif (ret)\n 92:\t\t\tgoto err_wqs;\n 93:\t\n 94:\t\treturn 0;\n 95:\t\n 96:\terr_wqs:\n 97:\t\tflush_workqueue(mors-\u003enet_wq);\n 98:\t\tdestroy_workqueue(mors-\u003enet_wq);\n 99:\t\n 100:\terr_chip_wq:\n 101:\t\tflush_workqueue(mors-\u003echip_wq);\n 102:\t\tdestroy_workqueue(mors-\u003echip_wq);\n 103:\t\n 104:\t\treturn ret;\n 105:\t}\n 106:\tEXPORT_SYMBOL_GPL(mm81x_core_init);\n 107:\t\n 108:\tint mm81x_core_register(struct mm81x *mors)\n 109:\t{\n 110:\t\treturn mm81x_mac_register(mors);\n 111:\t}\n 112:\tEXPORT_SYMBOL_GPL(mm81x_core_register);\n 113:\t\n 114:\tvoid mm81x_core_unregister(struct mm81x *mors)\n 115:\t{\n 116:\t\tmm81x_mac_unregister(mors);\n 117:\t}\n 118:\tEXPORT_SYMBOL_GPL(mm81x_core_unregister);\n 119:\t\n 120:\tvoid mm81x_core_deinit(struct mm81x *mors)\n 121:\t{\n 122:\t\tmm81x_hif_finish(mors);\n 123:\t\tflush_workqueue(mors-\u003enet_wq);\n 124:\t\tdestroy_workqueue(mors-\u003enet_wq);\n 125:\t\tflush_workqueue(mors-\u003echip_wq);\n 126:\t\tdestroy_workqueue(mors-\u003echip_wq);\n 127:\t}\n 128:\tEXPORT_SYMBOL_GPL(mm81x_core_deinit);\n 129:\t\n 130:\tvoid mm81x_core_free(struct mm81x *mors)\n 131:\t{\n 132:\t\tmm81x_mac_free(mors);\n 133:\t}\n 134:\tEXPORT_SYMBOL_GPL(mm81x_core_free);\n 135:\t\n 136:\tMODULE_AUTHOR(\"Morse Micro\");\n 137:\tMODULE_DESCRIPTION(\"Driver support for Morse Micro MM81X core\");\n 138:\tMODULE_LICENSE(\"Dual BSD/GPL\");\n"
} |
| 31/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 30884 output: 40 thoughts: 288 Thoughts: **Analyzing the Firmware Loading Logic** Okay, first things first, I need to understand how this `mm81x_fw_init` function is actually triggered. Hmm, it looks like it's only called within `mm81x_mac_restart`. Now, where does *that* get called? Right, `mm81x_mac_restart` is called from `mm81x_mac_ops_add_interface` and also `mm81x_reg_notifier`. So, adding an interface restarts the MAC, and *that* loads the firmware. Makes sense, that's a completely valid path. This should be a reachable point. The patch itself focuses on the firmware parsing, which makes sense if the loading process is solid. The firmware's loaded using `request_firmware`, which is pretty standard. Now, can syzkaller actually *fuzz* this? Let me see… I know syzkaller has `syz_mount_image`, or can mock `request_firmware` if supported... but, wait, it can also just drop files in `/lib/firmware`, or use the firmware loader fallback. Oh, yeah, syzkaller *does* fuzz firmware loading via `request_firmware`, by intercepting it or providing files directly. Alright, let's nail down precisely which functions are being modified here. Looks like: `mm81x_fw_parse_info`, `mm81x_fw_load_fw`, `mm81x_fw_read_ext_host_table`, and `mm81x_fw_parse_ext_host_tbl`. Now the question is, *is* `mm81x_fw_parse_info` reachable? We need to verify that. |
| 32/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_parse_info",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=28=static int mm81x_fw_get_header(const u8 *data, Elf32_Ehdr *ehdr)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-54-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:55:static void mm81x_fw_parse_info(struct mm81x *mors, const u8 *data, int length)\ndrivers/net/wireless/morsemicro/mm81x/fw.c-56-{\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c=110=static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-184-\t\t\t sizeof(\".fw_info\")))\ndrivers/net/wireless/morsemicro/mm81x/fw.c:185:\t\t\tmm81x_fw_parse_info(mors, fw-\u003edata + shdr.sh_offset,\ndrivers/net/wireless/morsemicro/mm81x/fw.c-186-\t\t\t\t\t shdr.sh_size);\n"
} |
| 33/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31930 output: 44 thoughts: 38 Thoughts: Here's my take on the thought process, as if it were my own: **Analyzing the Firmware Loading Sequence** Okay, so I'm digging into this firmware loading process. I see that the function `mm81x_fw_load_fw` is definitely the one initiating the load, that's clear enough. Now, I need to understand the data flow, how it's being fed, where the actual firmware image comes from, and any specific configurations being loaded. I'm noting that. Let me also check what `mm81x_fw_read_ext_host_table` is about. Is it reading a file? From external memory? Or perhaps an internal lookup table? Is that the table of "external host" information? I'll have to investigate that function to determine what it does, the nature of the data involved and how this relates to my firmware loading sequence. It's likely involved, so I need to understand its role within the broader context. |
| 34/2 | 2026/08/12 07:05 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_read_ext_host_table",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=442=static int mm81x_fw_get_host_table_ptr(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-457-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:458:static int mm81x_fw_read_ext_host_table(struct mm81x *mors,\ndrivers/net/wireless/morsemicro/mm81x/fw.c-459-\t\t\t\t\tstruct ext_host_tbl **ext_host_table)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c=564=int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-570-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:571:\tret = mm81x_fw_read_ext_host_table(mors, \u0026ext_host_table);\ndrivers/net/wireless/morsemicro/mm81x/fw.c-572-\tif (ret || !ext_host_table)\n"
} |
| 35/2 | 2026/08/12 07:05 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 32563 output: 44 thoughts: 18 Thoughts: Okay, here's my interpretation of that thought process, from an expert's perspective: **Diving into the Firmware Parsing** Alright, so we're looking at firmware parsing, specifically the `mm81x_fw_parse_ext_host_tbl` function. My mind immediately goes to the potential complexities. This function name strongly suggests we're dealing with an extended host table, meaning we're likely processing more than just basic information about the host system. It could be parsing configurations, resource allocations, device-specific settings... the possibilities are vast. I'm starting to think about the underlying data structures. What format is this host table in? Is it a standard format or something proprietary? Are we talking about a binary blob, a structured text file, or something else entirely? What kind of error handling is in place? Are there checksums or integrity checks to ensure data validity? My experience tells me this will involve bit-level manipulation, memory management considerations if the table is large, and potentially dealing with endianness issues depending on the target architecture. I’ll need to understand the context of this call within the larger firmware image to figure out where the information is used. This kind of parsing function is where vulnerabilities like buffer overflows or format string bugs tend to hide, so I'm already mentally preparing to scrutinize the code for those. |
| 36/2 | 2026/08/12 07:06 | tool | grepper |
0mArgs:{
"Expression": "mm81x_fw_parse_ext_host_tbl",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/fw.c=554=static void mm81x_fw_update_validate_skb_checksum(\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.c-563-\ndrivers/net/wireless/morsemicro/mm81x/fw.c:564:int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)\ndrivers/net/wireless/morsemicro/mm81x/fw.c-565-{\n--\ndrivers/net/wireless/morsemicro/mm81x/fw.h=140=int mm81x_fw_init(struct mm81x *mors, bool reset);\ndrivers/net/wireless/morsemicro/mm81x/fw.h:141:int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors);\ndrivers/net/wireless/morsemicro/mm81x/fw.h-142-\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c=2107=static int mm81x_mac_restart(struct mm81x *mors)\n--\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2147-\ndrivers/net/wireless/morsemicro/mm81x/mac.c:2148:\tret = mm81x_fw_parse_ext_host_tbl(mors);\ndrivers/net/wireless/morsemicro/mm81x/mac.c-2149-\tif (ret) {\n"
} |
| 37/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 33333 output: 35 thoughts: 237 Thoughts: **Fuzzing Target Identification** Okay, so I've traced down how this `mm81x_fw_parse_ext_host_tbl` function is called, and it looks like it's also called from `mm81x_mac_restart`. That's interesting, which means the firmware parsing logic is definitely reachable during runtime and therefore a valid target for fuzzing. Excellent! Now, which functions are the most promising? Let's see... Initially, I was looking at `mm81x_fw_parse_info`. It's static, so it's a bit less attractive but it's important to understand where we're going. Let's dig deeper. It looks like it's a while loop with a switch statement. It's probably not inlined because that's a decent size, even though it's static. Better to pivot and focus on `mm81x_fw_load_fw` since it calls `mm81x_fw_parse_info`. Wait a minute, `mm81x_fw_init` is *not* static, so that's definitely a point of interest, and `mm81x_fw_parse_ext_host_tbl` is also non-static, so we've got a couple of good leads there! Okay, let's prioritize and investigate `mm81x_fw_init` and `mm81x_fw_parse_ext_host_tbl` and see where we are. Just to be safe, I'll quickly check the Kconfig to see if the `MM81X` symbol is defined. Gotta check that off the list. |
| 38/2 | 2026/08/12 07:06 | tool | grepper |
0mArgs:{
"Expression": "config MM81X",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/mm81x/Kconfig-2-\ndrivers/net/wireless/morsemicro/mm81x/Kconfig:3:config MM81X\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-4-\ttristate \"Morse Micro MM81x wireless devices\" if COMPILE_TEST\n--\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-11-\ndrivers/net/wireless/morsemicro/mm81x/Kconfig:12:config MM81X_USB\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-13-\ttristate \"Morse Micro MM81x USB support\"\n--\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-19-\ndrivers/net/wireless/morsemicro/mm81x/Kconfig:20:config MM81X_SDIO\ndrivers/net/wireless/morsemicro/mm81x/Kconfig-21-\ttristate \"Morse Micro MM81x SDIO support\"\n"
} |
| 39/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 34248 output: 43 thoughts: 22 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Analyzing Module Dependencies** Okay, so I'm looking at `MM81X_USB` and `MM81X`. My immediate thought is to drill down into their interdependencies. This is a crucial first step. I need to understand which other modules, drivers, libraries, or even specific hardware components these rely on. Are we talking about core kernel modules, user-space utilities, or something more specialized within our proprietary stack? I need to build a mental map – a dependency graph really – to see the full scope. Specifically, I'm thinking about: * **Explicit Dependencies:** What's listed in the makefiles or configuration files? Any obvious `requires` directives or build flags? * **Implicit Dependencies:** Where do they *use* functionality that isn't directly declared? Are there shared resources like memory regions, interrupt handlers, or device registers? * **Versioning and Compatibility:** Are there version constraints on the modules they depend on? What happens if a dependent module is updated or patched? Compatibility problems here are the worst. * **Hardware Abstraction Layer (HAL):** How abstract is the hardware access? Are they talking directly to registers or relying on a well-defined HAL that I'm already familiar with? This can give me some hints to start with. * **External Libraries:** I'll need to check for external libraries and their versions. Any issues in the past? Any known vulnerabilities that could affect these? The goal is to get a solid grasp of where changes in either `MM81X_USB` or `MM81X` could propagate and what potential impact they could have on the rest of the system. This baseline knowledge is critical for efficient debugging, feature implementation, and any sort of modification. |
| 40/2 | 2026/08/12 07:06 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/morsemicro/mm81x/Kconfig",
"FirstLine": 1,
"LineCount": 30
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0\n 2:\t\n 3:\tconfig MM81X\n 4:\t\ttristate \"Morse Micro MM81x wireless devices\" if COMPILE_TEST\n 5:\t\tdepends on MAC80211\n 6:\t\tselect FW_LOADER\n 7:\t\tselect CRC7\n 8:\t\thelp\n 9:\t\t This module adds support for wireless devices based\n 10:\t\t on Morse Micro MM81xx chipsets.\n 11:\t\n 12:\tconfig MM81X_USB\n 13:\t\ttristate \"Morse Micro MM81x USB support\"\n 14:\t\tdepends on MAC80211 \u0026\u0026 USB\n 15:\t\tselect MM81X\n 16:\t\thelp\n 17:\t\t This module adds support for the USB interface of\n 18:\t\t devices using the Morse Micro MM81x chipset.\n 19:\t\n 20:\tconfig MM81X_SDIO\n 21:\t\ttristate \"Morse Micro MM81x SDIO support\"\n 22:\t\tdepends on MAC80211 \u0026\u0026 MMC\n 23:\t\tselect MM81X\n 24:\t\thelp\n 25:\t\t This module adds support for the SDIO interface of\n 26:\t\t devices using the Morse Micro MM81x chipset.\n"
} |
| 41/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 35052 output: 39 thoughts: 38 Thoughts: Okay, here's my interpretation of those thoughts, presented as my own mental process, keeping in mind I'm an expert in this field. **Enabling USB Gadget Testing and WLAN Vendor Support** Alright, I'm thinking, to get this USB gadget testing for the MM81X working, we absolutely need to ensure `MM81X_USB` is enabled. That's a no-brainer, that's what's going to allow the system to recognize the USB gadget functionality of this specific piece of hardware. I can't even *think* about testing without that. And then, alongside that, I'm making sure `WLAN_VENDOR_MORSEMICRO` is enabled too. It's crucial we don't overlook any dependencies or underlying vendor-specific requirements. Without enabling this support, we're likely going to run into issues with the wireless components when we start testing. It is a good practice to ensure all the relevant parts of the system are up and running, to avoid the frustration of troubleshooting the wrong things. Best to be prepared, right? |
| 42/2 | 2026/08/12 07:06 | tool | grepper |
0mArgs:{
"Expression": "config WLAN_VENDOR_MORSEMICRO",
"PathPrefix": "drivers/net/wireless/morsemicro/"
}Results: {
"Output": "drivers/net/wireless/morsemicro/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/morsemicro/Kconfig:2:config WLAN_VENDOR_MORSEMICRO\ndrivers/net/wireless/morsemicro/Kconfig-3-\tbool \"Morse Micro devices\"\n"
} |
| 43/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 35449 output: 46 thoughts: 261 Thoughts: **Analyzing the Morse Micro Firmware Initialization** Okay, so I'm looking at the `WLAN_VENDOR_MORSEMICRO` and `MM81X_USB` configurations here. My initial thought is to zero in on specific functions within the Morse Micro driver to understand the initialization and firmware loading process. I'm seeing that `mm81x_fw_parse_ext_host_tbl` and `mm81x_fw_init` are key. Now, I need to understand the relationship between `mm81x_fw_load_fw`, `__mm81x_fw_flash`, and `mm81x_fw_flash`. It looks like `mm81x_fw_load_fw` is static, which is interesting, but it's called by `__mm81x_fw_flash`, which is then called by `mm81x_fw_flash`, and finally, that function is called by `mm81x_fw_init`. Since `mm81x_fw_init` is at the core of this chain, it looks like a good starting point. I can quickly see that `mm81x_fw_parse_ext_host_tbl` is not static. I'm confirming that `mm81x_fw_init` is non-static as well. I'll need to remember that `mm81x_fw_parse_ext_host_tbl` is definitely non-static, and also that `mm81x_fw_init` is, too. Now I need to take a look at the actual code for `mm81x_fw_init`. I'll find it in `drivers/net/wireless/morsemicro/mm81x/fw.c` and start digging deeper. |
| 44/2 | 2026/08/12 07:06 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/morsemicro/mm81x/fw.c",
"FirstLine": 719,
"LineCount": 50
}Results: {
"Contents": " 719:\tint mm81x_fw_init(struct mm81x *mors, bool reset)\n 720:\t{\n 721:\t\tint ret;\n 722:\t\tint board_id;\n 723:\t\tchar *bcf_path = NULL;\n 724:\t\tconst struct firmware *fw = NULL;\n 725:\t\tconst struct firmware *bcf = NULL;\n 726:\t\n 727:\t\tboard_id = mm81x_hw_otp_get_board_type(mors);\n 728:\t\n 729:\t\tif (!mm81x_hw_otp_valid_board_type(board_id)) {\n 730:\t\t\tdev_err(mors-\u003edev,\n 731:\t\t\t\t\"OTP not set, unable to determine BCF to use\");\n 732:\t\t\tret = -EINVAL;\n 733:\t\t\tgoto out;\n 734:\t\t}\n 735:\t\n 736:\t\tdev_dbg(mors-\u003edev, \"Using board type 0x%04x from OTP\", board_id);\n 737:\t\n 738:\t\tret = mm81x_fw_request(mors, \u0026fw);\n 739:\t\tif (ret)\n 740:\t\t\tgoto out;\n 741:\t\n 742:\t\tbcf_path = kasprintf(GFP_KERNEL,\n 743:\t\t\t\t MM81X_FW_DIR\n 744:\t\t\t\t \"/v%u/bcf_boardtype_%04x\" MM81X_FW_EXT,\n 745:\t\t\t\t mors-\u003efw_major, board_id);\n 746:\t\tif (!bcf_path) {\n 747:\t\t\tret = -ENOMEM;\n 748:\t\t\tgoto out;\n 749:\t\t}\n 750:\t\n 751:\t\tret = request_firmware(\u0026bcf, bcf_path, mors-\u003edev);\n 752:\t\tif (ret) {\n 753:\t\t\tif (ret == -ENOENT)\n 754:\t\t\t\tdev_err(mors-\u003edev, \"BCF %s not found\\n\", bcf_path);\n 755:\t\t\tgoto out;\n 756:\t\t}\n 757:\t\n 758:\t\tdev_info(mors-\u003edev, \"Loaded BCF from %s, size %zu, crc32 0x%08x\\n\",\n 759:\t\t\t bcf_path, bcf-\u003esize, binary_crc(bcf));\n 760:\t\n 761:\t\tret = mm81x_fw_flash(mors, fw, bcf, reset);\n 762:\t\tif (ret) {\n 763:\t\t\tdev_err(mors-\u003edev, \"failed to flash firmware: %d\", ret);\n 764:\t\t\tgoto out;\n 765:\t\t}\n 766:\t\n 767:\t\tret = mm81x_fw_get_flags(mors);\n 768:\t\n"
} |
| 45/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 36949 output: 46 thoughts: 81 Thoughts: Here's my summary, as the expert: **Focusing on Firmware Initialization and Table Parsing** Okay, so I'm thinking about where to dig into this firmware initialization. `mm81x_fw_init` seems like a solid entry point, and worth a deeper dive to see how the overall system gets started. I'm also really interested in how it handles external host tables. That's why I'm now honing in on `mm81x_fw_parse_ext_host_tbl`. Given the name, I'm guessing it's responsible for interpreting configuration data passed in from the host side, probably defining parameters or configurations specific to this module. I'll need to check the code to see what kind of table it handles, how it's validated, and how it is used. I'm going to start by taking a look at the implementation of `mm81x_fw_parse_ext_host_tbl` in `drivers/net/wireless/morsemicro/mm81x/fw.c` to understand this process in detail. |
| 46/2 | 2026/08/12 07:06 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/morsemicro/mm81x/fw.c",
"FirstLine": 564,
"LineCount": 50
}Results: {
"Contents": " 564:\tint mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)\n 565:\t{\n 566:\t\tint ret;\n 567:\t\tu8 *head;\n 568:\t\tu8 *end;\n 569:\t\tstruct ext_host_tbl *ext_host_table = NULL;\n 570:\t\n 571:\t\tret = mm81x_fw_read_ext_host_table(mors, \u0026ext_host_table);\n 572:\t\tif (ret || !ext_host_table)\n 573:\t\t\tgoto exit;\n 574:\t\n 575:\t\t/* Parse the TLVs */\n 576:\t\thead = ext_host_table-\u003eext_host_table_data_tlvs;\n 577:\t\tend = ((u8 *)ext_host_table) +\n 578:\t\t le32_to_cpu(ext_host_table-\u003eext_host_tbl_length);\n 579:\t\n 580:\t\twhile (end - head \u003e= (ptrdiff_t)sizeof(struct ext_host_tbl_tlv_hdr)) {\n 581:\t\t\tstruct ext_host_tbl_tlv_hdr *hdr =\n 582:\t\t\t\t(struct ext_host_tbl_tlv_hdr *)head;\n 583:\t\t\tu16 tlv_len = le16_to_cpu(hdr-\u003elength);\n 584:\t\n 585:\t\t\tif (tlv_len \u003c sizeof(*hdr) || tlv_len \u003e end - head)\n 586:\t\t\t\tbreak;\n 587:\t\n 588:\t\t\tswitch (le16_to_cpu(hdr-\u003etag)) {\n 589:\t\t\tcase MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES: {\n 590:\t\t\t\tstruct ext_host_tbl_s1g_caps *caps = (void *)hdr;\n 591:\t\n 592:\t\t\t\tif (tlv_len \u003e= sizeof(*caps))\n 593:\t\t\t\t\tmm81x_fw_update_capabilities(mors, caps);\n 594:\t\t\t\tbreak;\n 595:\t\t\t}\n 596:\t\t\tcase MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM: {\n 597:\t\t\t\tstruct ext_host_tbl_insert_skb_checksum *csum =\n 598:\t\t\t\t\t(void *)hdr;\n 599:\t\n 600:\t\t\t\tif (tlv_len \u003e= sizeof(*csum))\n 601:\t\t\t\t\tmm81x_fw_update_validate_skb_checksum(mors,\n 602:\t\t\t\t\t\t\t\t\t csum);\n 603:\t\t\t\tbreak;\n 604:\t\t\t}\n 605:\t\t\tcase MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE: {\n 606:\t\t\t\tstruct ext_host_tbl_yaps_table *yaps = (void *)hdr;\n 607:\t\n 608:\t\t\t\tif (tlv_len \u003e= sizeof(*yaps))\n 609:\t\t\t\t\tmm81x_yaps_hw_read_table(mors,\n 610:\t\t\t\t\t\t\t\t \u0026yaps-\u003eyaps_table);\n 611:\t\t\t\tbreak;\n 612:\t\t\t}\n 613:\t\t\tdefault:\n"
} |
| 47/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 38179 output: 38 thoughts: 216 Thoughts: **Fuzzing Target Identification and Dependency Analysis** Okay, so I'm looking at these functions, `mm81x_fw_init` and `mm81x_fw_parse_ext_host_tbl`. They're non-static, which immediately makes them interesting targets for fuzzing. Seems like a good starting point. Now, before I dive in too deep, let's see what configs are required to get these functions built and running correctly. I see `WLAN_VENDOR_MORSEMICRO` and `MM81X_USB` mentioned. Ah, right, `MM81X` is selected by `MM81X_USB`, so `MM81X` is indirectly relevant. Let me check the dependencies for `MM81X`. It looks like it needs `MAC80211`. Okay, so `MAC80211` is definitely essential. But is that *all*? Let me double-check. Okay, `MM81X_USB` itself depends on `MAC80211 && USB`. So, just to be absolutely thorough, I'll need to include `WLAN_VENDOR_MORSEMICRO` and `MM81X_USB` along with their dependencies. Alright, let me just make sure I'm not missing anything obvious. Let's dig into `drivers/net/wireless/morsemicro/Kconfig` and verify that I have everything. Need to be sure before I move forward. |
| 48/2 | 2026/08/12 07:06 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/morsemicro/Kconfig",
"FirstLine": 1,
"LineCount": 20
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\tconfig WLAN_VENDOR_MORSEMICRO\n 3:\t\tbool \"Morse Micro devices\"\n 4:\t\tdefault y\n 5:\t\thelp\n 6:\t\t If you have a wireless card belonging to this class, say Y.\n 7:\t\n 8:\t\t Note that the answer to this question doesn't directly affect the\n 9:\t\t kernel: saying N will just cause the configurator to skip all the\n 10:\t\t questions about these cards. If you say Y, you will be asked for\n 11:\t\t your specific card in the following questions.\n 12:\t\n 13:\tif WLAN_VENDOR_MORSEMICRO\n 14:\tsource \"drivers/net/wireless/morsemicro/mm81x/Kconfig\"\n 15:\tendif # WLAN_VENDOR_MORSEMICRO\n"
} |
| 49/2 | 2026/08/12 07:06 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 38992 output: 150 thoughts: 166 Thoughts: **My Assessment of the Morse Micro Fuzzing Targets** Okay, after reviewing the details, I've got a solid picture of what we're dealing with here. My conclusion is that `WLAN_VENDOR_MORSEMICRO` and `MM81X_USB` are the key configurations we need to enable for this. Here’s the breakdown in my head: * **WorthFuzzing:** Absolutely, this is a definite "yes." We've got vulnerabilities – out-of-bounds reads and memory leaks – specifically within the firmware parsing logic of the Morse Micro mm81x driver. This is classic fuzzing territory. * **FocusSymbols:** Specifically, I'm going to concentrate on `mm81x_fw_init` and `mm81x_fw_parse_ext_host_tbl`. Those seem to be where the bugs are hiding, based on the description of the patch and the vulnerable code. They're clearly critical functions within the firmware parsing process. * **EnableConfigs:** Again, `WLAN_VENDOR_MORSEMICRO` and `MM81X_USB` are what's going to allow us to trigger the relevant code paths. The USB interface is the route for interaction here, and the vendor flag allows us to engage. * **Reasoning:** The driver handles firmware parsing, and that’s where the bugs are. The USB interface, whether through a dummy HCD or syzkaller, provides the attack surface. This code is triggered during device probing and interface startup, making it reachable with the right configurations. It’s pretty straightforward – bring the device up, load the firmware (which is the parsing target), and let the fuzzing begin. We have a clear path to trigger the vulnerable code, so I'm optimistic about finding some new bugs with the fuzzing approach. |
| 50/2 | 2026/08/12 07:06 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"WLAN_VENDOR_MORSEMICRO",
"MM81X_USB"
],
"FocusSymbols": [
"mm81x_fw_init",
"mm81x_fw_parse_ext_host_tbl"
],
"Reasoning": "The patch fixes out-of-bounds reads and memory leaks in the firmware parsing logic of the Morse Micro mm81x driver. The driver can be tested via the USB interface using a dummy HCD or syzkaller's USB fuzzing capabilities. The firmware loading and parsing logic is reachable when the device is probed and the interface is brought up.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"WLAN_VENDOR_MORSEMICRO",
"MM81X_USB"
],
"FocusSymbols": [
"mm81x_fw_init",
"mm81x_fw_parse_ext_host_tbl"
],
"Reasoning": "The patch fixes out-of-bounds reads and memory leaks in the firmware parsing logic of the Morse Micro mm81x driver. The driver can be tested via the USB interface using a dummy HCD or syzkaller's USB fuzzing capabilities. The firmware loading and parsing logic is reachable when the device is probed and the interface is brought up.",
"WorthFuzzing": true
} |
| 51/1 | 2026/08/12 07:06 | action | If |
0mArgs:{
"WorthFuzzing": true
}Results: null |
| 52/2 | 2026/08/12 07:06 | agent | kmsan-evaluator |
0mModel:best-expensive Args: null Results: {
"KMSANReasoning": "The patch fixes out-of-bounds reads and memory leaks during firmware parsing. The bounds checks prevent reading past the end of allocated buffers containing firmware data, which are out-of-bounds memory accesses rather than uninitialized memory uses. KASAN is fully capable of detecting these out-of-bounds reads, and kmemleak detects the fixed memory leaks. There is no risk of uninitialized memory being exposed to user space or used in control flow, so a dedicated KMSAN fuzzing session is not necessary.",
"NeedsKMSAN": false
}Instruction: You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.
CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
a comprehensive suite of debugging tools and sanitizers, including KASAN
(out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
(locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
or page allocations) and kernel-to-user memory info-leaks.
Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.
Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.
Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
attributes, ioctl output arguments, socket options, or BPF buffers) where fields
or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
uninitialized bytes of existing buffers.
Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
dereferences, locking deadlocks, or use-after-free bugs (these are already caught
by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.
Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: For your convenience, here is the diff of the changes:
commit 00660705ed6fca873a029ee3c252fc3fb88a154b
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Aug 12 07:04:43 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/morsemicro/mm81x/fw.c b/drivers/net/wireless/morsemicro/mm81x/fw.c
index d6d2ad086c328..50fa9e4b5f803 100644
--- a/drivers/net/wireless/morsemicro/mm81x/fw.c
+++ b/drivers/net/wireless/morsemicro/mm81x/fw.c
@@ -54,21 +54,29 @@ static int mm81x_fw_get_header(const u8 *data, Elf32_Ehdr *ehdr)
static void mm81x_fw_parse_info(struct mm81x *mors, const u8 *data, int length)
{
- const struct mm81x_fw_info_tlv *tlv =
- (const struct mm81x_fw_info_tlv *)data;
+ const u8 *end = data + length;
+ const u8 *pos = data;
+
+ while (end - pos >= (ptrdiff_t)sizeof(struct mm81x_fw_info_tlv)) {
+ const struct mm81x_fw_info_tlv *tlv =
+ (const struct mm81x_fw_info_tlv *)pos;
+ u16 tlv_len = le16_to_cpu(tlv->length);
+
+ pos = tlv->val;
+ if (tlv_len > end - pos)
+ break;
- while ((u8 *)tlv < (data + length)) {
switch (le16_to_cpu(tlv->type)) {
case MM81X_FW_INFO_TLV_BCF_ADDR:
- mors->bcf_address = get_unaligned_le32(tlv->val);
+ if (tlv_len >= sizeof(__le32))
+ mors->bcf_address =
+ get_unaligned_le32(tlv->val);
break;
default:
break;
}
- tlv = (const struct mm81x_fw_info_tlv *)((u8 *)tlv +
- le16_to_cpu(
- tlv->length) +
- sizeof(*tlv));
+
+ pos += tlv_len;
}
}
@@ -117,13 +125,15 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)
if (mm81x_fw_get_header(fw->data, &ehdr)) {
dev_err(mors->dev, "Wrong file format");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_free;
}
if (mm81x_fw_get_section_header(fw->data, &ehdr, &sh_strtab,
ehdr.e_shstrndx)) {
dev_err(mors->dev, "Invalid firmware. Missing string table");
- return -ENOENT;
+ ret = -ENOENT;
+ goto out_free;
}
sh_strs = (const char *)fw->data + sh_strtab.sh_offset;
@@ -160,7 +170,7 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)
mm81x_release_bus(mors);
if (status) {
ret = -EIO;
- break;
+ goto out_free;
}
}
}
@@ -179,6 +189,7 @@ static int mm81x_fw_load_fw(struct mm81x *mors, const struct firmware *fw)
if (ehdr.e_entry)
ret = mm81x_fw_set_boot_addr(mors, ehdr.e_entry);
+out_free:
devm_kfree(mors->dev, fw_buf);
return ret;
}
@@ -492,6 +503,13 @@ static int mm81x_fw_read_ext_host_table(struct mm81x *mors,
if (ret)
goto exit;
+ /* The table describes its own length; it must fit what was read */
+ if (le32_to_cpu(host_tbl->ext_host_tbl_length) < sizeof(*host_tbl) ||
+ le32_to_cpu(host_tbl->ext_host_tbl_length) > ext_host_tbl_len) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
mm81x_release_bus(mors);
*ext_host_table = host_tbl;
return ret;
@@ -559,34 +577,44 @@ int mm81x_fw_parse_ext_host_tbl(struct mm81x *mors)
end = ((u8 *)ext_host_table) +
le32_to_cpu(ext_host_table->ext_host_tbl_length);
- while (head < end) {
+ while (end - head >= (ptrdiff_t)sizeof(struct ext_host_tbl_tlv_hdr)) {
struct ext_host_tbl_tlv_hdr *hdr =
(struct ext_host_tbl_tlv_hdr *)head;
+ u16 tlv_len = le16_to_cpu(hdr->length);
+
+ if (tlv_len < sizeof(*hdr) || tlv_len > end - head)
+ break;
switch (le16_to_cpu(hdr->tag)) {
- case MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES:
- mm81x_fw_update_capabilities(
- mors, (struct ext_host_tbl_s1g_caps *)hdr);
+ case MM81X_FW_HOST_TABLE_TAG_S1G_CAPABILITIES: {
+ struct ext_host_tbl_s1g_caps *caps = (void *)hdr;
+
+ if (tlv_len >= sizeof(*caps))
+ mm81x_fw_update_capabilities(mors, caps);
break;
+ }
+ case MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM: {
+ struct ext_host_tbl_insert_skb_checksum *csum =
+ (void *)hdr;
- case MM81X_FW_HOST_TABLE_TAG_INSERT_SKB_CHECKSUM:
- mm81x_fw_update_validate_skb_checksum(
- mors,
- (struct ext_host_tbl_insert_skb_checksum *)hdr);
+ if (tlv_len >= sizeof(*csum))
+ mm81x_fw_update_validate_skb_checksum(mors,
+ csum);
break;
+ }
+ case MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE: {
+ struct ext_host_tbl_yaps_table *yaps = (void *)hdr;
- case MM81X_FW_HOST_TABLE_TAG_YAPS_TABLE:
- mm81x_yaps_hw_read_table(
- mors, &((struct ext_host_tbl_yaps_table *)hdr)
- ->yaps_table);
+ if (tlv_len >= sizeof(*yaps))
+ mm81x_yaps_hw_read_table(mors,
+ &yaps->yaps_table);
break;
+ }
default:
break;
}
- head += le16_to_cpu(hdr->length);
- if (!hdr->length)
- break;
+ head += tlv_len;
}
kfree(ext_host_table);
|
| 53/3 | 2026/08/12 07:06 | llm | kmsan-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3866 output: 130 thoughts: 414 Thoughts: **Analyzing the Morse Micro Firmware Patch** Okay, so this patch is cleaning up some firmware parsing routines within the `mm81x` wireless driver. My initial assessment is that it's a straightforward improvement, primarily focused on hardening against potential vulnerabilities. The changes are all localized within `drivers/net/wireless/morsemicro/mm81x/fw.c`. Specifically, I see fixes to four functions: `mm81x_fw_parse_info`, `mm81x_fw_load_fw`, `mm81x_fw_read_ext_host_table`, and `mm81x_fw_parse_ext_host_tbl`. The core of the patch seems to be adding bounds checking during TLV (Type-Length-Value) parsing within the firmware data and addressing memory leaks in the firmware loading process. The memory leak fix in `mm81x_fw_load_fw` is a standard `goto out_free` which is what I would expect. My immediate thought is, are we dealing with any *uninitialized* memory exposures? I need to be sure. The patch itself is using KASAN to catch the OOB reads and kmemleak to catch the memory leaks. The data itself seems to come from the firmware image (`fw->data`) or is read from the device hardware itself (in the case of the extended host table). So, there shouldn't be anything uninitialized being exposed, but I need to be thorough. Let's break down the attack surface. If the `tlv_len` is too large, it results in an out-of-bounds read and is caught by KASAN. Now, what if `tlv_len` is smaller, *potentially* leading to an uninitialized read? No, it's not going to read uninitialized memory because the buffer is allocated and initialized with firmware data. If we're reading past the end of the data, it's still out-of-bounds, and KASAN will catch it. The same logic applies to `host_tbl->ext_host_tbl_length` versus `ext_host_tbl_len`. KASAN should be able to catch the OOB reads there. Given that, I don't see any immediate concerns of uninitialized memory being leaked. This looks like a solid patch. Standard OOB and memory leak fixes. No KMSAN is necessary here. |
| 54/3 | 2026/08/12 07:06 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch fixes out-of-bounds reads and memory leaks during firmware parsing. The bounds checks prevent reading past the end of allocated buffers containing firmware data, which are out-of-bounds memory accesses rather than uninitialized memory uses. KASAN is fully capable of detecting these out-of-bounds reads, and kmemleak detects the fixed memory leaks. There is no risk of uninitialized memory being exposed to user space or used in control flow, so a dedicated KMSAN fuzzing session is not necessary.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch fixes out-of-bounds reads and memory leaks during firmware parsing. The bounds checks prevent reading past the end of allocated buffers containing firmware data, which are out-of-bounds memory accesses rather than uninitialized memory uses. KASAN is fully capable of detecting these out-of-bounds reads, and kmemleak detects the fixed memory leaks. There is no risk of uninitialized memory being exposed to user space or used in control flow, so a dedicated KMSAN fuzzing session is not necessary.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|