AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/06/29 09:00 flow patch-triage
7m Args:
null

Results:
{
  "EnableConfigs": [
    "MT7921U"
  ],
  "FocusSymbols": [
    "__mt7921_mcu_regd_update",
    "mt7921_mcu_regd_update",
    "mt7921_regd_set_6ghz_power_type"
  ],
  "Reasoning": "The patch fixes a deadlock in the MT7921 wireless driver. `mt7921_regd_set_6ghz_power_type` is called from `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`, which are invoked by mac80211 with the `dev-\u003emutex` already held. Previously, it called `mt7921_mcu_regd_update`, which attempted to acquire the same mutex, leading to a deadlock. The patch introduces `__mt7921_mcu_regd_update` to be called when the mutex is already held. This is a functional fix for a deadlock in reachable driver code. The driver can be reached in virtualized environments via the USB interface (`CONFIG_MT7921U`).",
  "WorthFuzzing": true
}

1/1 2026/06/29 09:00 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 656483419ef6ce8868bd01d90e2f3b4c6096fb49\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Mon Jun 29 09:00:10 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c\nindex 3480205d5fb91b..68a059504e8382 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c\n@@ -802,7 +802,7 @@ mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)\n \n out:\n \tif (vif-\u003ebss_conf.chanreq.oper.chan-\u003eband == NL80211_BAND_6GHZ)\n-\t\tmt7921_mcu_regd_update(dev, dev-\u003emt76.alpha2, dev-\u003ecountry_ie_env);\n+\t\t__mt7921_mcu_regd_update(dev, dev-\u003emt76.alpha2, dev-\u003ecountry_ie_env);\n }\n \n int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regd.c b/drivers/net/wireless/mediatek/mt76/mt7921/regd.c\nindex c0e2b48a50bf09..4722007abafd5c 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7921/regd.c\n+++ b/drivers/net/wireless/mediatek/mt76/mt7921/regd.c\n@@ -71,36 +71,44 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)\n \t}\n }\n \n-int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\n-\t\t\t   enum environment_cap country_ie_env)\n+/* Internal version that assumes mutex is already held by caller */\n+int __mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\n+\t\t\t     enum environment_cap country_ie_env)\n {\n \tstruct mt76_dev *mdev = \u0026dev-\u003emt76;\n \tstruct ieee80211_hw *hw = mdev-\u003ehw;\n \tstruct wiphy *wiphy = hw-\u003ewiphy;\n \tint ret = 0;\n \n-\tdev-\u003eregd_in_progress = true;\n-\n-\tmt792x_mutex_acquire(dev);\n \tif (!dev-\u003eregd_change)\n-\t\tgoto err;\n+\t\treturn 0;\n \n \tret = mt7921_mcu_set_clc(dev, alpha2, country_ie_env);\n \tif (ret \u003c 0)\n-\t\tgoto err;\n+\t\treturn ret;\n \n \tmt7921_regd_channel_update(wiphy, dev);\n \n \tret = mt76_connac_mcu_set_channel_domain(hw-\u003epriv);\n \tif (ret \u003c 0)\n-\t\tgoto err;\n+\t\treturn ret;\n \n \tret = mt7921_set_tx_sar_pwr(hw, NULL);\n-\tif (ret \u003c 0)\n-\t\tgoto err;\n \n-err:\n+\treturn ret;\n+}\n+\n+int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\n+\t\t\t   enum environment_cap country_ie_env)\n+{\n+\tint ret = 0;\n+\n+\tdev-\u003eregd_in_progress = true;\n+\n+\tmt792x_mutex_acquire(dev);\n+\tret = __mt7921_mcu_regd_update(dev, alpha2, country_ie_env);\n \tmt792x_mutex_release(dev);\n+\n \tdev-\u003eregd_change = false;\n \tdev-\u003eregd_in_progress = false;\n \twake_up(\u0026dev-\u003ewait);\ndiff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regd.h b/drivers/net/wireless/mediatek/mt76/mt7921/regd.h\nindex 571f31629e9e01..5b24d0902c369c 100644\n--- a/drivers/net/wireless/mediatek/mt76/mt7921/regd.h\n+++ b/drivers/net/wireless/mediatek/mt76/mt7921/regd.h\n@@ -10,6 +10,8 @@ struct regulatory_request;\n \n int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\n \t\t\t   enum environment_cap country_ie_env);\n+int __mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\n+\t\t\t     enum environment_cap country_ie_env);\n void mt7921_regd_notifier(struct wiphy *wiphy,\n \t\t\t  struct regulatory_request *request);\n bool mt7921_regd_clc_supported(struct mt792x_dev *dev);\n"
}

2/1 2026/06/29 09:00 agent patch-evaluator
7m Model:
gemini-3.1-pro-preview

Args:
null

Results:
{
  "EnableConfigs": [
    "MT7921U"
  ],
  "FocusSymbols": [
    "__mt7921_mcu_regd_update",
    "mt7921_mcu_regd_update",
    "mt7921_regd_set_6ghz_power_type"
  ],
  "Reasoning": "The patch fixes a deadlock in the MT7921 wireless driver. `mt7921_regd_set_6ghz_power_type` is called from `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`, which are invoked by mac80211 with the `dev-\u003emutex` already held. Previously, it called `mt7921_mcu_regd_update`, which attempted to acquire the same mutex, leading to a deadlock. The patch introduces `__mt7921_mcu_regd_update` to be called when the mutex is already held. This is a functional fix for a deadlock in reachable driver code. The driver can be reached in virtualized environments via the USB interface (`CONFIG_MT7921U`).",
  "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).

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.
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.
   Do not list too generic configs (we already have them enabled). Only list those that
   specifically cover the modified code. 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 656483419ef6ce8868bd01d90e2f3b4c6096fb49
Author: syz-cluster <triage@syzkaller.com>
Date:   Mon Jun 29 09:00:10 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 3480205d5fb91b..68a059504e8382 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -802,7 +802,7 @@ mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)
 
 out:
 	if (vif->bss_conf.chanreq.oper.chan->band == NL80211_BAND_6GHZ)
-		mt7921_mcu_regd_update(dev, dev->mt76.alpha2, dev->country_ie_env);
+		__mt7921_mcu_regd_update(dev, dev->mt76.alpha2, dev->country_ie_env);
 }
 
 int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regd.c b/drivers/net/wireless/mediatek/mt76/mt7921/regd.c
index c0e2b48a50bf09..4722007abafd5c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/regd.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/regd.c
@@ -71,36 +71,44 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)
 	}
 }
 
-int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
-			   enum environment_cap country_ie_env)
+/* Internal version that assumes mutex is already held by caller */
+int __mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
+			     enum environment_cap country_ie_env)
 {
 	struct mt76_dev *mdev = &dev->mt76;
 	struct ieee80211_hw *hw = mdev->hw;
 	struct wiphy *wiphy = hw->wiphy;
 	int ret = 0;
 
-	dev->regd_in_progress = true;
-
-	mt792x_mutex_acquire(dev);
 	if (!dev->regd_change)
-		goto err;
+		return 0;
 
 	ret = mt7921_mcu_set_clc(dev, alpha2, country_ie_env);
 	if (ret < 0)
-		goto err;
+		return ret;
 
 	mt7921_regd_channel_update(wiphy, dev);
 
 	ret = mt76_connac_mcu_set_channel_domain(hw->priv);
 	if (ret < 0)
-		goto err;
+		return ret;
 
 	ret = mt7921_set_tx_sar_pwr(hw, NULL);
-	if (ret < 0)
-		goto err;
 
-err:
+	return ret;
+}
+
+int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
+			   enum environment_cap country_ie_env)
+{
+	int ret = 0;
+
+	dev->regd_in_progress = true;
+
+	mt792x_mutex_acquire(dev);
+	ret = __mt7921_mcu_regd_update(dev, alpha2, country_ie_env);
 	mt792x_mutex_release(dev);
+
 	dev->regd_change = false;
 	dev->regd_in_progress = false;
 	wake_up(&dev->wait);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regd.h b/drivers/net/wireless/mediatek/mt76/mt7921/regd.h
index 571f31629e9e01..5b24d0902c369c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/regd.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/regd.h
@@ -10,6 +10,8 @@ struct regulatory_request;
 
 int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
 			   enum environment_cap country_ie_env);
+int __mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
+			     enum environment_cap country_ie_env);
 void mt7921_regd_notifier(struct wiphy *wiphy,
 			  struct regulatory_request *request);
 bool mt7921_regd_clc_supported(struct mt792x_dev *dev);

3/2 2026/06/29 09:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 3089
							output: 44
							thoughts: 285
						

Thoughts:
**Analyzing a Wi-Fi Driver Patch: MT7921 and Potential Lock Issues**

Okay, so this patch targets the Mediatek MT7921 wireless driver. My initial read tells me it's modifying the `mt7921_mcu_regd_update` function, creating an internal version, `__mt7921_mcu_regd_update`, which *assumes* the mutex is already held. The important change is the call to this internal version from `mt7921_regd_set_6ghz_power_type` instead of the original function. The likely intent is to resolve some locking issue, perhaps a deadlock scenario or incorrect mutex usage. Sounds pretty standard.

Now, a question is - how reachable is this code? MT7921 is typically a PCIe, USB, or SDIO Wi-Fi driver, right? In a virtualized environment, these hardware drivers can be tricky. Unless there is software emulation like mac80211_hwsim (but that is a separate driver and this is a specific one) reaching it can be difficult.

Wait... could a USB driver like this be fuzzed using a dummy HCD or something similar? I know Syzkaller has USB fuzzing capabilities with its `dummy_hcd` and `raw-gadget` options. That's a good avenue to explore. I'll need to check if MT7921 even *has* a USB component. Let's see... a quick check shows `drivers/net/wireless/mediatek/mt76/mt7921/usb.c` existing. Bingo! That could be a way to expose this fix and test it thoroughly. I'll need to dig deeper into that USB code path to determine if it's the right entry point for fuzzing.



4/2 2026/06/29 09:00 tool grepper
0m Args:
{
  "Expression": "mt7921",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 2345 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile-2-\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:3:obj-$(CONFIG_MT7921_COMMON) += mt7921-common.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:4:obj-$(CONFIG_MT7921E) += mt7921e.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:5:obj-$(CONFIG_MT7921S) += mt7921s.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:6:obj-$(CONFIG_MT7921U) += mt7921u.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile-7-\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:8:mt7921-common-y := mac.o mcu.o regd.o main.o init.o debugfs.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:9:mt7921-common-$(CONFIG_NL80211_TESTMODE) += testmode.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:10:mt7921e-y := pci.o pci_mac.o pci_mcu.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:11:mt7921s-y := sdio.o sdio_mac.o sdio_mcu.o\ndrivers/net/wireless/mediatek/mt76/mt7921/Makefile:12:mt7921u-y := usb.o\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-3-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:4:#include \"mt7921.h\"\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-5-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=6=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:7:mt7921_reg_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-8-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=18=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:19:mt7921_reg_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-20-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-29-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:30:DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7921_reg_get, mt7921_reg_set,\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-31-\t\t\t \"0x%08llx\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=32=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:33:mt7921_fw_debug_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-34-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-39-\tdev-\u003efw_debug = (u8)val;\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:40:\tmt7921_mcu_fw_log_2_host(dev, dev-\u003efw_debug);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-41-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=47=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:48:mt7921_fw_debug_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-49-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-56-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:57:DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7921_fw_debug_get,\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:58:\t\t\t mt7921_fw_debug_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-59-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=62=static void\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:63:mt7921_seq_puts_array(struct seq_file *file, const char *str,\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-64-\t\t      s8 *val, int len)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-76-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:77:#define mt7921_print_txpwr_entry(prefix, rate)\t\t\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-78-({\t\t\t\t\t\t\t\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:79:\tmt7921_seq_puts_array(s, #prefix \" (user)\",\t\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-80-\t\t\t      txpwr.data[TXPWR_USER].rate,\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-81-\t\t\t      ARRAY_SIZE(txpwr.data[TXPWR_USER].rate)); \\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:82:\tmt7921_seq_puts_array(s, #prefix \" (eeprom)\",\t\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-83-\t\t\t      txpwr.data[TXPWR_EEPROM].rate,\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-84-\t\t\t      ARRAY_SIZE(txpwr.data[TXPWR_EEPROM].rate)); \\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:85:\tmt7921_seq_puts_array(s, #prefix \" (tmac)\",\t\t\t\\\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-86-\t\t\t      txpwr.data[TXPWR_MAC].rate,\t\t\\\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=90=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:91:mt7921_txpwr(struct seq_file *s, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-92-{\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-93-\tstruct mt792x_dev *dev = dev_get_drvdata(s-\u003eprivate);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:94:\tstruct mt7921_txpwr txpwr;\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-95-\tint ret;\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-97-\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:98:\tret = mt7921_get_txpwr_info(dev, \u0026txpwr);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-99-\tmt792x_mutex_release(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-106-\t\t   \" \", \"1m\", \"2m\", \"5m\", \"11m\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:107:\tmt7921_print_txpwr_entry(CCK, cck);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-108-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-111-\t\t   \"48m\", \"54m\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:112:\tmt7921_print_txpwr_entry(OFDM, ofdm);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-113-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-116-\t\t   \"mcs6\", \"mcs7\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:117:\tmt7921_print_txpwr_entry(HT20, ht20);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-118-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-121-\t\t   \"mcs6\", \"mcs7\", \"mcs32\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:122:\tmt7921_print_txpwr_entry(HT40, ht40);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-123-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-126-\t\t   \"mcs6\", \"mcs7\", \"mcs8\", \"mcs9\", \"mcs10\", \"mcs11\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:127:\tmt7921_print_txpwr_entry(VHT20, vht20);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:128:\tmt7921_print_txpwr_entry(VHT40, vht40);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:129:\tmt7921_print_txpwr_entry(VHT80, vht80);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:130:\tmt7921_print_txpwr_entry(VHT160, vht160);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:131:\tmt7921_print_txpwr_entry(HE26, he26);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:132:\tmt7921_print_txpwr_entry(HE52, he52);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:133:\tmt7921_print_txpwr_entry(HE106, he106);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:134:\tmt7921_print_txpwr_entry(HE242, he242);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:135:\tmt7921_print_txpwr_entry(HE484, he484);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:136:\tmt7921_print_txpwr_entry(HE996, he996);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:137:\tmt7921_print_txpwr_entry(HE996x2, he996x2);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-138-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=142=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:143:mt7921_pm_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-144-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-166-\tpm-\u003eenable_user = val;\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:167:\tmt7921_set_runtime_pm(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-168-\tmt76_connac_power_save_sched(\u0026dev-\u003emphy, pm);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=175=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:176:mt7921_pm_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-177-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-184-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:185:DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-186-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=187=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:188:mt7921_deep_sleep_set(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-189-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=211=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:212:mt7921_deep_sleep_get(void *data, u64 *val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-213-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-220-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:221:DEFINE_DEBUGFS_ATTRIBUTE(fops_ds, mt7921_deep_sleep_get,\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:222:\t\t\t mt7921_deep_sleep_set, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-223-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=224=DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt792x_pm_idle_timeout_get,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-226-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:227:static int mt7921_chip_reset(void *data, u64 val)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-228-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-247-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:248:DEFINE_DEBUGFS_ATTRIBUTE(fops_reset, NULL, mt7921_chip_reset, \"%lld\\n\");\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-249-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=250=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:251:mt7921s_sched_quota_read(struct seq_file *s, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-252-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-263-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:264:int mt7921_init_debugfs(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-265-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-279-\tdebugfs_create_devm_seqfile(dev-\u003emt76.dev, \"txpower_sku\", dir,\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:280:\t\t\t\t    mt7921_txpwr);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-281-\tdebugfs_create_file(\"tx_stats\", 0400, dir, dev, \u0026mt792x_tx_stats_fops);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-291-\t\tdebugfs_create_devm_seqfile(dev-\u003emt76.dev, \"sched-quota\", dir,\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:292:\t\t\t\t\t    mt7921s_sched_quota_read);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-293-\treturn 0;\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-8-#include \u003clinux/firmware.h\u003e\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:9:#include \"mt7921.h\"\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-10-#include \"../mt76_connac2_mac.h\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-13-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:14:static ssize_t mt7921_thermal_temp_show(struct device *dev,\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-15-\t\t\t\t\tstruct device_attribute *attr,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-24-\t\tmt792x_mutex_acquire(mdev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:25:\t\ttemperature = mt7921_mcu_get_temperature(phy);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-26-\t\tmt792x_mutex_release(mdev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-36-}\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:37:static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7921_thermal_temp, 0);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-38-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:39:static struct attribute *mt7921_hwmon_attrs[] = {\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-40-\t\u0026sensor_dev_attr_temp1_input.dev_attr.attr,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-42-};\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:43:ATTRIBUTE_GROUPS(mt7921_hwmon);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-44-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:45:static int mt7921_thermal_init(struct mt792x_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-46-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-53-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:54:\tname = devm_kasprintf(\u0026wiphy-\u003edev, GFP_KERNEL, \"mt7921_%s\",\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-55-\t\t\t      wiphy_name(wiphy));\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-59-\thwmon = devm_hwmon_device_register_with_groups(\u0026wiphy-\u003edev, name, phy,\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:60:\t\t\t\t\t\t       mt7921_hwmon_groups);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-61-\treturn PTR_ERR_OR_ZERO(hwmon);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-63-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:64:int mt7921_mac_init(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-65-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-74-\tfor (i = 0; i \u003c MT792x_WTBL_SIZE; i++)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:75:\t\tmt7921_mac_wtbl_update(dev, i,\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-76-\t\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-81-}\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:82:EXPORT_SYMBOL_GPL(mt7921_mac_init);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-83-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:84:static int __mt7921_init_hardware(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-85-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-99-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:100:\tret = mt7921_mcu_set_eeprom(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-101-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-103-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:104:\tret = mt7921_mac_init(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-105-out:\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-108-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:109:static int mt7921_init_hardware(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-110-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-115-\tfor (i = 0; i \u003c MT792x_MCU_INIT_RETRY_COUNT; i++) {\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:116:\t\tret = __mt7921_init_hardware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-117-\t\tif (!ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-130-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:131:static void mt7921_init_work(struct work_struct *work)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-132-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-136-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:137:\tret = mt7921_init_hardware(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-138-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-141-\tmt76_set_stream_caps(\u0026dev-\u003emphy, true);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:142:\tmt7921_set_stream_he_caps(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-143-\tmt792x_config_mac_addr_list(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-151-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:152:\tret = mt7921_init_debugfs(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-153-\tif (ret) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-157-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:158:\tret = mt7921_thermal_init(\u0026dev-\u003ephy);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-159-\tif (ret) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-169-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:170:int mt7921_register_device(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-171-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-189-\tINIT_DELAYED_WORK(\u0026dev-\u003emphy.mac_work, mt792x_mac_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:190:\tINIT_DELAYED_WORK(\u0026dev-\u003ephy.scan_work, mt7921_scan_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:191:\tINIT_DELAYED_WORK(\u0026dev-\u003ecoredump.work, mt7921_coredump_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-192-#if IS_ENABLED(CONFIG_IPV6)\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:193:\tINIT_WORK(\u0026dev-\u003eipv6_ns_work, mt7921_set_ipv6_ns_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-194-\tskb_queue_head_init(\u0026dev-\u003eipv6_ns_list);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-198-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:199:\tINIT_WORK(\u0026dev-\u003ereset_work, mt7921_mac_reset_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:200:\tINIT_WORK(\u0026dev-\u003einit_work, mt7921_init_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-201-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:202:\tINIT_WORK(\u0026dev-\u003ephy.roc_work, mt7921_roc_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-203-\ttimer_setup(\u0026dev-\u003ephy.roc_timer, mt792x_roc_timer, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-230-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:231:\thw-\u003ewiphy-\u003ereg_notifier = mt7921_regd_notifier;\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-232-\tdev-\u003emphy.sband_2g.sband.ht_cap.cap |=\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-255-}\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:256:EXPORT_SYMBOL_GPL(mt7921_register_device);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-6-#include \u003clinux/timekeeping.h\u003e\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:7:#include \"mt7921.h\"\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-8-#include \"../dma.h\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-18-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:19:bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-20-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-27-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:28:static u32 mt7921_mac_wtbl_lmac_addr(int idx, u8 offset)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-29-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-32-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:33:static void mt7921_mac_sta_poll(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-34-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-72-\t\tidx = mlink-\u003ewcid.idx;\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:73:\t\taddr = mt7921_mac_wtbl_lmac_addr(idx, MT_WTBL_AC0_CTT_OFFSET);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-74-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-91-\t\tif (clear) {\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:92:\t\t\tmt7921_mac_wtbl_update(dev, idx,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-93-\t\t\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-120-\t\trate = \u0026mlink-\u003ewcid.rate;\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:121:\t\taddr = mt7921_mac_wtbl_lmac_addr(idx,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-122-\t\t\t\t\t\t MT_WTBL_TXRX_CAP_RATE_OFFSET);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-152-\t\t/* get signal strength of resp frames (CTS/BA/ACK) */\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:153:\t\taddr = mt7921_mac_wtbl_lmac_addr(idx, 30);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-154-\t\tval = mt76_rr(dev, addr);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=168=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:169:mt7921_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-170-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-446-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:447:void mt7921_mac_add_txs(struct mt792x_dev *dev, void *data)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-448-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-484-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:485:static void mt7921_mac_tx_free(struct mt792x_dev *dev, void *data, int len)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-486-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-555-\trcu_read_lock();\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:556:\tmt7921_mac_sta_poll(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-557-\trcu_read_unlock();\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-561-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:562:bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-563-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-573-\t\t/* PKT_TYPE_TXRX_NOTIFY can be received only by mmio devices */\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:574:\t\tmt7921_mac_tx_free(dev, data, len); /* mmio */\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-575-\t\treturn false;\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-577-\t\tfor (rxd += 2; rxd + 8 \u003c= end; rxd += 8)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:578:\t\t\tmt7921_mac_add_txs(dev, rxd);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-579-\t\treturn false;\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-583-}\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:584:EXPORT_SYMBOL_GPL(mt7921_rx_check);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-585-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:586:void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-587-\t\t\t struct sk_buff *skb, u32 *info)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-603-\t\t/* PKT_TYPE_TXRX_NOTIFY can be received only by mmio devices */\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:604:\t\tmt7921_mac_tx_free(dev, skb-\u003edata, skb-\u003elen);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-605-\t\tnapi_consume_skb(skb, 1);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-607-\tcase PKT_TYPE_RX_EVENT:\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:608:\t\tmt7921_mcu_rx_event(dev, skb);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-609-\t\tbreak;\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-611-\t\tfor (rxd += 2; rxd + 8 \u003c= end; rxd += 8)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:612:\t\t\tmt7921_mac_add_txs(dev, rxd);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-613-\t\tdev_kfree_skb(skb);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-616-\tcase PKT_TYPE_NORMAL:\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:617:\t\tif (!mt7921_mac_fill_rx(dev, skb)) {\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-618-\t\t\tmt76_rx(\u0026dev-\u003emt76, q, skb);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-626-}\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:627:EXPORT_SYMBOL_GPL(mt7921_queue_rx_skb);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-628-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=629=static void\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:630:mt7921_vif_connect_iter(void *priv, u8 *mac,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-631-\t\t\tstruct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-642-\t\t\t\t    \u0026mvif-\u003esta.deflink.wcid, true);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:643:\tmt7921_mcu_set_tx(dev, vif);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-644-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-647-\t\t\t\t\t    true, NULL);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:648:\t\tmt7921_mcu_sta_update(dev, NULL, vif, true,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-649-\t\t\t\t      MT76_STA_INFO_STATE_NONE);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:650:\t\tmt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-651-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-654-/* system error recovery */\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:655:void mt7921_mac_reset_work(struct work_struct *work)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-656-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-701-\t\t\t\t\t    IEEE80211_IFACE_ITER_RESUME_ALL,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:702:\t\t\t\t\t    mt7921_vif_connect_iter, NULL);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-703-\tmt76_connac_power_save_sched(\u0026dev-\u003emt76.phy, pm);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-704-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:705:\tmt7921_regd_change(\u0026dev-\u003ephy, \"00\");\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-706-}\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-707-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:708:void mt7921_coredump_work(struct work_struct *work)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-709-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=756=static void\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:757:mt7921_usb_sdio_write_txwi(struct mt792x_dev *dev, struct mt76_wcid *wcid,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-758-\t\t\t   enum mt76_txq_id qid, struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-768-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:769:int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-770-\t\t\t\t   enum mt76_txq_id qid, struct mt76_wcid *wcid,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-799-\tpktid = mt76_tx_status_skb_add(\u0026dev-\u003emt76, wcid, skb);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:800:\tmt7921_usb_sdio_write_txwi(dev, wcid, qid, sta, key, pktid, skb);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-801-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-814-}\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:815:EXPORT_SYMBOL_GPL(mt7921_usb_sdio_tx_prepare_skb);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-816-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:817:void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-818-\t\t\t\t     struct mt76_queue_entry *e)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-835-}\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:836:EXPORT_SYMBOL_GPL(mt7921_usb_sdio_tx_complete_skb);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-837-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:838:bool mt7921_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-839-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-842-\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:843:\tmt7921_mac_sta_poll(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-844-\tmt792x_mutex_release(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-847-}\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:848:EXPORT_SYMBOL_GPL(mt7921_usb_sdio_tx_status_data);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-849-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-850-#if IS_ENABLED(CONFIG_IPV6)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:851:void mt7921_set_ipv6_ns_work(struct work_struct *work)\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-852-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-8-#include \u003cnet/ipv6.h\u003e\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:9:#include \"mt7921.h\"\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-10-#include \"regd.h\"\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=13=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:14:mt7921_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-15-\t\t    struct ieee80211_sband_iftype_data *data)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-195-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:196:void mt7921_set_stream_he_caps(struct mt792x_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-197-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-203-\t\tdata = phy-\u003eiftype[NL80211_BAND_2GHZ];\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:204:\t\tn = mt7921_init_he_caps(phy, NL80211_BAND_2GHZ, data);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-205-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-211-\t\tdata = phy-\u003eiftype[NL80211_BAND_5GHZ];\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:212:\t\tn = mt7921_init_he_caps(phy, NL80211_BAND_5GHZ, data);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-213-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-218-\t\t\tdata = phy-\u003eiftype[NL80211_BAND_6GHZ];\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:219:\t\t\tn = mt7921_init_he_caps(phy, NL80211_BAND_6GHZ, data);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-220-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-226-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:227:int __mt7921_start(struct mt792x_phy *phy)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-228-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-239-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:240:\terr = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-241-\tif (err)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-243-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:244:\terr = mt7921_set_tx_sar_pwr(mphy-\u003ehw, NULL);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-245-\tif (err)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-253-\tif (mt76_is_mmio(mphy-\u003edev)) {\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:254:\t\terr = mt7921_mcu_radio_led_ctrl(phy-\u003edev, EXT_CMD_RADIO_LED_CTRL_ENABLE);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-255-\t\tif (err)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-257-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:258:\t\terr = mt7921_mcu_radio_led_ctrl(phy-\u003edev, EXT_CMD_RADIO_ON_LED);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-259-\t\tif (err)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-263-\tif (phy-\u003echip_cap \u0026 MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN) {\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:264:\t\tmt7921_mcu_wf_rf_pin_ctrl(phy, WF_RF_PIN_INIT);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-265-\t\twiphy_rfkill_start_polling(mphy-\u003ehw-\u003ewiphy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-269-}\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:270:EXPORT_SYMBOL_GPL(__mt7921_start);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-271-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:272:static int mt7921_start(struct ieee80211_hw *hw)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-273-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-277-\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:278:\terr = __mt7921_start(phy);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-279-\tmt792x_mutex_release(phy-\u003edev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-283-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:284:static void mt7921_stop(struct ieee80211_hw *hw, bool suspend)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-285-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-290-\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:291:\t\terr = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-292-\t\tmt792x_mutex_release(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=300=static int\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:301:mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-302-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-338-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:339:\tmt7921_mac_wtbl_update(dev, idx,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-340-\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-353-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:354:\tINIT_WORK(\u0026mvif-\u003ecsa_work, mt7921_csa_work);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-355-\ttimer_setup(\u0026mvif-\u003ecsa_timer, mt792x_csa_timer, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-361-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:362:static void mt7921_roc_iter(void *priv, u8 *mac,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-363-\t\t\t    struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-367-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:368:\tmt7921_mcu_abort_roc(phy, mvif, phy-\u003eroc_token_id);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-369-}\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-370-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:371:void mt7921_roc_abort_sync(struct mt792x_dev *dev)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-372-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-382-\t\t\t\t     IEEE80211_IFACE_ITER_RESUME_ALL,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:383:\t\t\t\t     mt7921_roc_iter, (void *)phy);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-384-}\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:385:EXPORT_SYMBOL_GPL(mt7921_roc_abort_sync);\n\n"
}

5/2 2026/06/29 09:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 20242
							output: 46
							thoughts: 198
						

Thoughts:
**Fuzzing the MT7921U USB Driver**

Okay, so the build output clearly indicates that the `mt7921u` driver is compiled when `CONFIG_MT7921U` is enabled. And, it's defined as `usb.o`, which confirms it's a USB driver. Excellent. This is good because that means we can reach it with either syzkaller's `dummy_hcd` or the `raw-gadget` interface, opening up avenues for fuzzing in a virtualized setting, which is precisely what I want.

Now, let's drill down and figure out the exact configuration requirements. I already know `CONFIG_MT7921U` enables the USB driver, `CONFIG_MT7921E` is PCIe, and `CONFIG_MT7921S` is SDIO. And, `CONFIG_MT7921_COMMON` looks like the shared, base code.

Right, I'm going to pull up the Kconfig file for `MT7921U` and see what else needs to be flipped on.



6/2 2026/06/29 09:00 tool grepper
0m Args:
{
  "Expression": "config MT7921U",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig=17=config MT7921S\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/Kconfig-27-\ndrivers/net/wireless/mediatek/mt76/mt7921/Kconfig:28:config MT7921U\ndrivers/net/wireless/mediatek/mt76/mt7921/Kconfig-29-\ttristate \"MediaTek MT7921U (USB) support\"\n"
}

7/2 2026/06/29 09:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 20878
							output: 48
							thoughts: 15
						

Thoughts:
Here's my thought process, summarized as you requested:

**Assessing the Landscape: MT7921U Dependencies**

Okay, let's dive in. My immediate focus is on the `MT7921U` – that's where we need to start. My expert eye immediately goes to dependencies. I need to understand what this module relies on, and what relies on it. I need a clear dependency graph, both upstream and downstream. This isn't just about direct includes, either. I'm thinking about shared libraries, kernel modules, firmware, potential hardware revisions, and anything else this component touches. Anything that could cause ripple effects down the line. I need to map it all out – systematically, methodically – to understand its true role and potential impact. This understanding is the foundation for any deeper investigation.



8/2 2026/06/29 09:01 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig",
  "FirstLine": 1,
  "LineCount": 100
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: BSD-3-Clause-Clear\n   2:\tconfig MT7921_COMMON\n   3:\t\ttristate\n   4:\t\tselect MT792x_LIB\n   5:\t\tselect WANT_DEV_COREDUMP\n   6:\t\n   7:\tconfig MT7921E\n   8:\t\ttristate \"MediaTek MT7921E (PCIe) support\"\n   9:\t\tselect MT7921_COMMON\n  10:\t\tdepends on MAC80211\n  11:\t\tdepends on PCI\n  12:\t\thelp\n  13:\t\t  This adds support for MT7921E 802.11ax 2x2:2SS wireless devices.\n  14:\t\n  15:\t\t  To compile this driver as a module, choose M here.\n  16:\t\n  17:\tconfig MT7921S\n  18:\t\ttristate \"MediaTek MT7921S (SDIO) support\"\n  19:\t\tselect MT76_SDIO\n  20:\t\tselect MT7921_COMMON\n  21:\t\tdepends on MAC80211\n  22:\t\tdepends on MMC\n  23:\t\thelp\n  24:\t\t  This adds support for MT7921S 802.11ax 2x2:2SS wireless devices.\n  25:\t\n  26:\t\t  To compile this driver as a module, choose M here.\n  27:\t\n  28:\tconfig MT7921U\n  29:\t\ttristate \"MediaTek MT7921U (USB) support\"\n  30:\t\tselect MT792x_USB\n  31:\t\tselect MT7921_COMMON\n  32:\t\tdepends on MAC80211\n  33:\t\tdepends on USB\n  34:\t\thelp\n  35:\t\t  This adds support for MT7921U 802.11ax 2x2:2SS wireless devices.\n  36:\t\n  37:\t\t  To compile this driver as a module, choose M here.\n"
}

9/2 2026/06/29 09:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 21657
							output: 57
							thoughts: 113
						

Thoughts:
**Analyzing the MT7921U Configuration for Regulatory Updates**

Okay, so I see that `MT7921U` is the key configuration option we're enabling here. Now, let's dive into the details and pinpoint the key symbols we need to focus on within this patch. From a quick scan, it looks like this update primarily concerns itself with regulatory updates, and I'm seeing modifications touching several critical functions: specifically `__mt7921_mcu_regd_update`, `mt7921_mcu_regd_update`, and `mt7921_regd_set_6ghz_power_type`. The obvious next step is to determine how `mt7921_regd_set_6ghz_power_type` fits into the puzzle, and to do that, I'm going to determine if the function is reachable.



10/2 2026/06/29 09:01 tool grepper
0m Args:
{
  "Expression": "mt7921_regd_set_6ghz_power_type",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7921/main.c=765=static void\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:766:mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-767-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=808=int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-849-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:850:\tmt7921_regd_set_6ghz_power_type(vif, true);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-851-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=891=void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-920-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:921:\tmt7921_regd_set_6ghz_power_type(vif, false);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-922-\n"
}

11/2 2026/06/29 09:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 22517
							output: 52
							thoughts: 142
						

Thoughts:
**Analyzing the Regulatory Domain Update Functions**

Okay, so I'm tracing the calls to regulatory domain update functions in this mt7921 driver. I see that `__mt7921_mcu_regd_update` and `mt7921_mcu_regd_update` are clearly reachable – as expected – through `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`. This connection confirms my initial hypothesis: these functions will be hit whenever a station joins or leaves the network, triggered by mac80211 events.

That helps narrow down my area of focus. My key symbols to examine are now: `__mt7921_mcu_regd_update`, `mt7921_mcu_regd_update`, and `mt7921_regd_set_6ghz_power_type`.

Just to be absolutely thorough, I'm going to double-check that `mt7921_mcu_regd_update` isn't called from any other place. It's always good to be certain there aren't any unexpected entry points, which might influence the overall system behavior. Gotta get a full picture.



12/2 2026/06/29 09:01 tool grepper
0m Args:
{
  "Expression": "mt7921_mcu_regd_update",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7921/main.c=766=mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-804-\tif (vif-\u003ebss_conf.chanreq.oper.chan-\u003eband == NL80211_BAND_6GHZ)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:805:\t\t__mt7921_mcu_regd_update(dev, dev-\u003emt76.alpha2, dev-\u003ecountry_ie_env);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-806-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c=545=static int mt7921_pci_resume(struct device *device)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-591-\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c:592:\tmt7921_mcu_regd_update(dev, mdev-\u003ealpha2, dev-\u003ecountry_ie_env);\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-593-\terr = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_ON_LED);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c=23=mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-74-/* Internal version that assumes mutex is already held by caller */\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c:75:int __mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-76-\t\t\t     enum environment_cap country_ie_env)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-100-\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c:101:int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-102-\t\t\t   enum environment_cap country_ie_env)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-108-\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c:109:\tret = __mt7921_mcu_regd_update(dev, alpha2, country_ie_env);\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-110-\tmt792x_mutex_release(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-117-}\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c:118:EXPORT_SYMBOL_GPL(mt7921_mcu_regd_update);\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-119-\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c=120=void mt7921_regd_notifier(struct wiphy *wiphy,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-152-\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c:153:\tmt7921_mcu_regd_update(dev, req-\u003ealpha2,\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-154-\t\t\t       req-\u003ecountry_ie_env);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.h=9=struct regulatory_request;\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.h-10-\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.h:11:int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.h-12-\t\t\t   enum environment_cap country_ie_env);\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.h:13:int __mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.h-14-\t\t\t     enum environment_cap country_ie_env);\n"
}

13/2 2026/06/29 09:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24440
							output: 50
							thoughts: 261
						

Thoughts:
**Analyzing the Mutex Usage in the mt7921 Driver**

Okay, so I'm looking at this `mt7921` driver code, and I see `mt7921_mcu_regd_update` being called from a few places. Specifically, `mt7921_pci_resume` and `mt7921_regd_notifier` call it directly. I also see that `__mt7921_mcu_regd_update` is called by `mt7921_regd_set_6ghz_power_type` and, you guessed it, `mt7921_mcu_regd_update`. Hmm, this is where it gets interesting...

The patch is addressing a deadlock, and it seems to stem from `mt7921_regd_set_6ghz_power_type` calling `mt7921_mcu_regd_update`. The problem is, `mt7921_mcu_regd_update` likely acquires a mutex. But *crucially*, `mt7921_regd_set_6ghz_power_type` is called from `mt7921_mac_sta_add`. This looks like a classic mutex inversion scenario. If `mt7921_mac_sta_add` *already* has the mutex when it calls `mt7921_regd_set_6ghz_power_type`, which then tries to acquire the same mutex, we've got a deadlock on our hands.

Wait a second… I need to confirm whether `mt7921_mac_sta_add` *is* called with the mutex already held. This is the key. I need to dive into `mt7921_mac_sta_add` and see how it's called and in what context. Gotta trace those call paths. This feels like it might be an easy fix, but I need to make sure I'm right about the mutex contention.



14/2 2026/06/29 09:01 tool grepper
0m Args:
{
  "Expression": "mt7921_mac_sta_add",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7921/main.c=766=mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-807-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:808:int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-809-\t\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-855-}\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:856:EXPORT_SYMBOL_GPL(mt7921_mac_sta_add);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-857-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h=264=bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask);\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h:265:int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h-266-\t\t       struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c=259=static int mt7921_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-275-\t\t.rx_poll_complete = mt792x_rx_poll_complete,\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c:276:\t\t.sta_add = mt7921_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-277-\t\t.sta_event = mt7921_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c=90=static int mt7921s_probe(struct sdio_func *func,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-103-\t\t.rx_check = mt7921_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c:104:\t\t.sta_add = mt7921_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-105-\t\t.sta_event = mt7921_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c=150=static int mt7921u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-164-\t\t.rx_check = mt7921_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c:165:\t\t.sta_add = mt7921_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-166-\t\t.sta_event = mt7921_mac_sta_event,\n"
}

15/2 2026/06/29 09:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26285
							output: 50
							thoughts: 100
						

Thoughts:
**Analyzing the `mt7921_mac_sta_add` Function Call**

Alright, so `mt7921_mac_sta_add` is the station add callback for the mt76 driver, specifically the mt7921. That makes sense, given the naming convention. It's called by mac80211, which confirms it's the correct function triggered when a new station is associated with the device. Now, the critical question is concurrency. Is a mutex protecting this section of code? I need to quickly determine whether the caller in the mt76 framework, or the `mt7921_mac_sta_add` function itself, acquires a mutex. My next step is to examine the function's implementation directly to ascertain how the access to shared resources is handled within this routine.



16/2 2026/06/29 09:01 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/main.c",
  "FirstLine": 808,
  "LineCount": 50
}

Results:
{
  "Contents": " 808:\tint mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n 809:\t\t\t       struct ieee80211_sta *sta)\n 810:\t{\n 811:\t\tstruct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);\n 812:\t\tstruct mt792x_sta *msta = (struct mt792x_sta *)sta-\u003edrv_priv;\n 813:\t\tstruct mt792x_vif *mvif = (struct mt792x_vif *)vif-\u003edrv_priv;\n 814:\t\tint ret, idx;\n 815:\t\n 816:\t\tif (sta-\u003eaid \u003e MT7921_MAX_AID)\n 817:\t\t\treturn -ENOENT;\n 818:\t\n 819:\t\tidx = mt76_wcid_alloc(dev-\u003emt76.wcid_mask, MT792x_WTBL_STA - 1);\n 820:\t\tif (idx \u003c 0)\n 821:\t\t\treturn -ENOSPC;\n 822:\t\n 823:\t\tINIT_LIST_HEAD(\u0026msta-\u003edeflink.wcid.poll_list);\n 824:\t\tmsta-\u003evif = mvif;\n 825:\t\tmsta-\u003edeflink.wcid.sta = 1;\n 826:\t\tmsta-\u003edeflink.wcid.idx = idx;\n 827:\t\tmsta-\u003edeflink.wcid.phy_idx = mvif-\u003ebss_conf.mt76.band_idx;\n 828:\t\tmsta-\u003edeflink.wcid.tx_info |= MT_WCID_TX_INFO_SET;\n 829:\t\tmsta-\u003edeflink.last_txs = jiffies;\n 830:\t\tmsta-\u003edeflink.sta = msta;\n 831:\t\n 832:\t\tif (sta-\u003etdls)\n 833:\t\t\tset_bit(MT_WCID_FLAG_TDLS_PEER, \u0026msta-\u003edeflink.wcid.flags);\n 834:\t\n 835:\t\tret = mt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n 836:\t\tif (ret)\n 837:\t\t\treturn ret;\n 838:\t\n 839:\t\tif (vif-\u003etype == NL80211_IFTYPE_STATION)\n 840:\t\t\tmvif-\u003ewep_sta = msta;\n 841:\t\n 842:\t\tmt7921_mac_wtbl_update(dev, idx,\n 843:\t\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\n 844:\t\n 845:\t\tret = mt7921_mcu_sta_update(dev, sta, vif, true,\n 846:\t\t\t\t\t    MT76_STA_INFO_STATE_NONE);\n 847:\t\tif (ret)\n 848:\t\t\treturn ret;\n 849:\t\n 850:\t\tmt7921_regd_set_6ghz_power_type(vif, true);\n 851:\t\n 852:\t\tmt76_connac_power_save_sched(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n 853:\t\n 854:\t\treturn 0;\n 855:\t}\n 856:\tEXPORT_SYMBOL_GPL(mt7921_mac_sta_add);\n 857:\t\n"
}

17/2 2026/06/29 09:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27568
							output: 43
							thoughts: 377
						

Thoughts:
**Analyzing Mutex Usage in mt7921 Driver for 6 GHz Band Operations**

Okay, so I'm looking at this `mt7921_mac_sta_add` function and trying to figure out the mutex acquisition strategy. It doesn't seem to directly call `mt792x_mutex_acquire(dev)`, which is interesting. My initial thought is maybe the calling function, or perhaps a function *it* calls, holds the mutex. Maybe `mt7921_mcu_sta_update`? Hmm, let's see.

Wait, looking at the patch, I see they've changed `mt7921_mcu_regd_update` to `__mt7921_mcu_regd_update`. That internal function name suggests the mutex is *already* held. The change implies that the function is now being called in a context where the mutex is assumed to be acquired. Therefore, the function `mt7921_regd_set_6ghz_power_type` must be called with the mutex already held.

So the question is, *where* is this mutex acquired? Let's check the callers of `mt7921_regd_set_6ghz_power_type`. Alright, it's called from both `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`. The key question is whether `mt7921_mac_sta_add` *itself* holds the mutex. Let's see if there are any hints in the `mt76_connac_pm_wake` context.



18/2 2026/06/29 09:02 tool grepper
0m Args:
{
  "Expression": "mt76_connac_pm_wake",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c=96=mt7615_pm_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-125-\tpm-\u003eenable = false;\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c:126:\tmt76_connac_pm_wake(\u0026dev-\u003emphy, pm);\ndrivers/net/wireless/mediatek/mt76/mt7615/debugfs.c-127-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c=1945=void mt7615_update_channel(struct mt76_phy *mphy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c-1948-\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c:1949:\tif (mt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm))\ndrivers/net/wireless/mediatek/mt76/mt7615/mac.c-1950-\t\treturn;\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=284=int mt7615_set_channel(struct mt76_phy *mphy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-290-\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:291:\tmt76_connac_pm_wake(mphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-292-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=634=int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-653-\tphy = mvif-\u003emt76.band_idx ? mt7615_ext_phy(dev) : \u0026dev-\u003ephy;\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:654:\terr = mt76_connac_pm_wake(phy-\u003emt76, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-655-\tif (err)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=676=void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-686-\tphy = mvif-\u003emt76.band_idx ? mt7615_ext_phy(dev) : \u0026dev-\u003ephy;\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:687:\tmt76_connac_pm_wake(phy-\u003emt76, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-688-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c=72=static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-78-\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c:79:\terr = mt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7615/pci.c-80-\tif (err \u003c 0)\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h=356=static inline void mt76_connac_irq_enable(struct mt76_dev *dev, u32 mask)\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h-361-\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h:362:int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm);\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h-363-void mt76_connac_power_save_sched(struct mt76_phy *phy,\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h=421=mt76_connac_mutex_acquire(struct mt76_dev *dev, struct mt76_connac_pm *pm)\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h-424-\tmutex_lock(\u0026dev-\u003emutex);\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h:425:\tmt76_connac_pm_wake(\u0026dev-\u003ephy, pm);\ndrivers/net/wireless/mediatek/mt76/mt76_connac.h-426-}\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c=34=EXPORT_SYMBOL_GPL(mt76_connac_gen_ppe_thresh);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-35-\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c:36:int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-37-{\n--\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-59-}\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c:60:EXPORT_SYMBOL_GPL(mt76_connac_pm_wake);\ndrivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-61-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=143=mt7921_pm_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-163-\tpm-\u003eenable = false;\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:164:\tmt76_connac_pm_wake(\u0026dev-\u003emphy, pm);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-165-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=477=int mt7921_set_channel(struct mt76_phy *mphy)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-482-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:483:\tmt76_connac_pm_wake(mphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-484-\tret = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=808=int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-834-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:835:\tret = mt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-836-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=891=void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-898-\tmt76_connac_free_pending_tx_skbs(\u0026dev-\u003epm, \u0026msta-\u003edeflink.wcid);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:899:\tmt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-900-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=182=mt7925_pm_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-202-\tpm-\u003eenable = false;\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:203:\tmt76_connac_pm_wake(\u0026dev-\u003emphy, pm);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-204-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=887=static int mt7925_mac_link_sta_add(struct mt76_dev *mdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-932-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:933:\tret = mt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-934-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1238=static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1251-\tmt76_connac_free_pending_tx_skbs(\u0026dev-\u003epm, wcid);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1252:\tmt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1253-\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c=253=void mt792x_update_channel(struct mt76_phy *mphy)\n--\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c-256-\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c:257:\tif (mt76_connac_pm_wake(mphy, \u0026dev-\u003epm))\ndrivers/net/wireless/mediatek/mt76/mt792x_mac.c-258-\t\treturn;\n"
}

19/2 2026/06/29 09:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 31526
							output: 42
							thoughts: 49
						

Thoughts:
Here's my analysis of that code snippet:

**Diving into the MT7921 MAC STA Addition**

Alright, so `mt7921_mac_sta_add` doesn't seem to have a direct `mutex_acquire` call, which is a bit unusual. My initial thought is to trace the locking behavior here. Now, hold on, `mt792x_mutex_acquire`... that's probably a macro or a wrapper function, not a basic mutex acquisition. I need to investigate that macro or function definition to understand precisely how the mutex is being handled in this context. Let me dig into that right away and see what it reveals.



20/2 2026/06/29 09:02 tool grepper
0m Args:
{
  "Expression": "mt792x_mutex_acquire",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 585 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=7=mt7921_reg_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-10-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:11:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-12-\tmt76_wr(dev, dev-\u003emt76.debugfs_reg, val);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=19=mt7921_reg_get(void *data, u64 *val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-22-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:23:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-24-\t*val = mt76_rr(dev, dev-\u003emt76.debugfs_reg);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=33=mt7921_fw_debug_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-36-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:37:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-38-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=91=mt7921_txpwr(struct seq_file *s, void *data)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-96-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:97:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-98-\tret = mt7921_get_txpwr_info(dev, \u0026txpwr);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=188=mt7921_deep_sleep_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-197-\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:198:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-199-\tif (pm-\u003eds_enable_user == enable)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c=227=static int mt7921_chip_reset(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-238-\t\t/* Collect the core dump before reset wifisys. */\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c:239:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/debugfs.c-240-\t\tret = mt76_connac_mcu_chip_config(\u0026dev-\u003emt76);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c=14=static ssize_t mt7921_thermal_temp_show(struct device *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-23-\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c:24:\t\tmt792x_mutex_acquire(mdev);\ndrivers/net/wireless/mediatek/mt76/mt7921/init.c-25-\t\ttemperature = mt7921_mcu_get_temperature(phy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=838=bool mt7921_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-841-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:842:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-843-\tmt7921_mac_sta_poll(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c=851=void mt7921_set_ipv6_ns_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-863-\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:864:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-865-\t\tret = mt76_mcu_skb_send_msg(\u0026dev-\u003emt76, skb,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=272=static int mt7921_start(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-276-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:277:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-278-\terr = __mt7921_start(phy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=284=static void mt7921_stop(struct ieee80211_hw *hw, bool suspend)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-289-\tif (mt76_is_mmio(\u0026dev-\u003emt76)) {\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:290:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-291-\t\terr = mt7921_mcu_radio_led_ctrl(dev, EXT_CMD_RADIO_OFF_LED);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=301=mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-308-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:309:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-310-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=387=void mt7921_roc_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-393-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:394:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-395-\tif (!test_and_clear_bit(MT76_STATE_ROC, \u0026phy-\u003emt76-\u003estate)) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=406=static int mt7921_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-412-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:413:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-414-\tif (test_and_clear_bit(MT76_STATE_ROC, \u0026phy-\u003emt76-\u003estate))\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=451=static int mt7921_remain_on_channel(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-460-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:461:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-462-\terr = mt7921_set_roc(phy, mvif, chan, duration, MT7921_ROC_REQ_ROC);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=502=static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-545-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:546:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-547-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=634=static int mt7921_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-645-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:646:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-647-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=666=static void mt7921_configure_filter(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-687-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:688:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-689-\tmt7921_mcu_set_rxfilter(dev, flags, 0, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=695=static void mt7921_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-702-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:703:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-704-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=858=int mt7921_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-870-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:871:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-872-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=927=static int mt7921_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-931-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:932:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-933-\tmt76_connac_mcu_set_rts_thresh(\u0026dev-\u003emt76, val, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=940=mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-957-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:958:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-959-\tswitch (action) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=996=static int mt7921_sta_state(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1004-\tif (dev-\u003epm.ds_enable) {\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1005:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1006-\t\tmt76_connac_sta_state_dp(\u0026dev-\u003emt76, old_state, new_state);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1055=mt7921_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1061-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1062:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1063-\terr = mt76_connac_mcu_hw_scan(mphy, vif, req);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1070=mt7921_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1074-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1075:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1076-\tmt76_connac_mcu_cancel_hw_scan(mphy, vif);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1081=mt7921_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1088-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1089:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1090-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1103=mt7921_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1108-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1109:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1110-\terr = mt76_connac_mcu_sched_scan_enable(mphy, vif, false);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1117=mt7921_set_antenna(struct ieee80211_hw *hw, int radio_idx,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1129-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1130:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1131-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1144=static int mt7921_suspend(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1155-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1156:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1157-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1169=static int mt7921_resume(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1173-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1174:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1175-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1190=static void mt7921_set_rekey_data(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1195-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1196:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1197-\tmt76_connac_mcu_update_gtk_rekey(hw, vif, data);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1202=static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1212-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1213:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1214-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1302=static int mt7921_set_sar_specs(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1307-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1308:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1309-\terr = mt7921_mcu_set_clc(dev, dev-\u003emt76.alpha2,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1322=mt7921_channel_switch_beacon(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1327-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1328:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1329-\tmt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1334=mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1341-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1342:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1343-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1362=mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1369-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1370:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1371-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1404=mt7921_change_chanctx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1418-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1419:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1420-\tif (vif-\u003etype == NL80211_IFTYPE_MONITOR) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1429=static void mt7921_mgd_prepare_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1437-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1438:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1439-\tmt7921_set_roc(mvif-\u003ephy, mvif, mvif-\u003ebss_conf.mt76.ctx-\u003edef.chan, duration,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1462=void mt7921_csa_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1473-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1474:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1475-\tret = mt76_connac_mcu_uni_set_chctx(mvif-\u003ephy-\u003emt76, \u0026mvif-\u003ebss_conf.mt76,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1536=static void mt7921_rfkill_poll(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1540-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1541:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1542-\tret = mt7921_mcu_wf_rf_pin_ctrl(phy, WF_RF_PIN_POLL);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c=101=int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-107-\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c:108:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/regd.c-109-\tret = __mt7921_mcu_regd_update(dev, alpha2, country_ie_env);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=8=mt7925_reg_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-12-\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:13:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-14-\tmt7925_mcu_regval(dev, dev-\u003emt76.debugfs_reg, \u0026regval, true);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=21=mt7925_reg_get(void *data, u64 *val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-26-\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:27:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-28-\tret = mt7925_mcu_regval(dev, dev-\u003emt76.debugfs_reg, \u0026regval, false);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=39=mt7925_fw_debug_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-42-\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:43:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-44-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=118=mt7925_txpwr(struct seq_file *s, void *data)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-129-\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:130:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-131-\tret = mt7925_get_txpwr_info(dev, band_idx, txpwr);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=227=mt7925_deep_sleep_set(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-236-\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:237:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-238-\tif (pm-\u003eds_enable_user == enable)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c=266=static int mt7925_chip_reset(void *data, u64 val)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-277-\t\t/* Collect the core dump before reset wifisys. */\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c:278:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/debugfs.c-279-\t\tret = mt7925_mcu_chip_config(dev, \"assert\");\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c=14=static ssize_t mt7925_thermal_temp_show(struct device *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c-23-\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c:24:\t\tmt792x_mutex_acquire(mdev);\ndrivers/net/wireless/mediatek/mt76/mt7925/init.c-25-\t\ttemperature = mt7925_mcu_get_temperature(phy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c=1477=bool mt7925_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c-1480-\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c:1481:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c-1482-\tmt7925_mac_sta_poll(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c=1490=void mt7925_set_ipv6_ns_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c-1502-\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c:1503:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/mac.c-1504-\t\tret = mt76_mcu_skb_send_msg(\u0026dev-\u003emt76, skb,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=363=static int mt7925_start(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-367-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:368:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-369-\terr = __mt7925_start(phy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=451=mt7925_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-457-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:458:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-459-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=509=void mt7925_roc_work(struct work_struct *work)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-518-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:519:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-520-\tieee80211_iterate_active_interfaces(phy-\u003emt76-\u003ehw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=527=static int mt7925_abort_roc(struct mt792x_phy *phy,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-534-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:535:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-536-\tif (test_and_clear_bit(MT76_STATE_ROC, \u0026phy-\u003emt76-\u003estate))\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=600=static int mt7925_remain_on_channel(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-609-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:610:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-611-\terr = mt7925_set_roc(phy, \u0026mvif-\u003ebss_conf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=705=static int mt7925_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-725-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:726:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-727-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=805=static int mt7925_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-809-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:810:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-811-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=830=static void mt7925_configure_filter(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-850-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:851:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-852-\tmt7925_mcu_set_rxfilter(dev, flags, 0, 0);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1145=mt7925_mac_set_links(struct mt76_dev *mdev, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1166-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1167:\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1168-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1177=static void mt7925_mac_link_sta_assoc(struct mt76_dev *mdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1185-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1186:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1187-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1377=static int mt7925_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1381-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1382:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1383-\tmt7925_mcu_set_rts_thresh(\u0026dev-\u003ephy, val);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1390=mt7925_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1407-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1408:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1409-\tswitch (action) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1447=mt7925_mlo_pm_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1458-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1459:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1460-\tfor_each_set_bit(i, \u0026valid, IEEE80211_MLD_MAX_NUM_LINKS) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1543=mt7925_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1549-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1550:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1551-\terr = mt7925_mcu_hw_scan(mphy, vif, req);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1558=mt7925_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1562-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1563:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1564-\tmt7925_mcu_cancel_hw_scan(mphy, vif);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1569=mt7925_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1576-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1577:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1578-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1591=mt7925_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1596-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1597:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1598-\terr = mt7925_mcu_sched_scan_enable(mphy, vif, false);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1605=mt7925_set_antenna(struct ieee80211_hw *hw, int radio_idx,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1617-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1618:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1619-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1633=static int mt7925_suspend(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1644-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1645:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1646-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1658=static int mt7925_resume(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1662-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1663:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1664-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1679=static void mt7925_set_rekey_data(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1684-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1685:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1686-\tmt76_connac_mcu_update_gtk_rekey(hw, vif, data);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1691=static void mt7925_sta_set_decap_offload(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1704-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1705:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1706-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1820=static int mt7925_set_sar_specs(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1825-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1826:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1827-\terr = mt7925_set_tx_sar_pwr(hw, sar);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1834=mt7925_channel_switch_beacon(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1839-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1840:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1841-\tmt7925_mcu_uni_add_beacon_offload(dev, hw, vif, true);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1866=mt7925_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1872-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1873:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1874-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1894=mt7925_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1900-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1901:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1902-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1937=mt7925_change_chanctx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1953-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1954:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1955-\tif (vif-\u003etype == NL80211_IFTYPE_MONITOR) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1989=static void mt7925_mgd_prepare_tx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1997-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1998:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1999-\tmt7925_set_roc(mvif-\u003ephy, \u0026mvif-\u003ebss_conf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2014=static void mt7925_vif_cfg_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2024-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:2025:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2026-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2064=static void mt7925_link_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2075-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:2076:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2077-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2123=mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2140-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:2141:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2142-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2232=mt7925_change_sta_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2242-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:2243:\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2244-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2354=static void mt7925_rfkill_poll(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2358-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:2359:\tmt792x_mutex_acquire(phy-\u003edev);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2360-\tret = mt7925_mcu_wf_rf_pin_ctrl(phy);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2375=void mt7925_csa_work(struct work_struct *work)\n--\n\n"
}

21/2 2026/06/29 09:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46502
							output: 43
							thoughts: 132
						

Thoughts:
**Analyzing Mutex Acquisition and Power Management in the MT76 Driver**

Okay, so I'm looking at this code and, right off the bat, `mt792x_mutex_acquire` – that's a macro or a function, obviously. Need to understand how the mutex is being handled around power management. Let me look at `mt76_connac_pm_wake`...nope, it doesn't appear to acquire the mutex itself. Hmm, so where's the locking happening? Aha! `mt76_connac_mutex_acquire` – that one *does* acquire the mutex and then calls the power management wake-up function, `mt76_connac_pm_wake`. Okay, that makes sense, they're likely coupled to avoid race conditions.

But here's a wrinkle: I see that `mt7921_mac_sta_add` calls `mt76_connac_pm_wake` directly. That's a bit odd. I need to understand why it bypasses the mutex acquisition that is present in the normal power management flow. Is it an optimization, or is it a sign of potential synchronization issues?

Okay, let me backtrack and check where `mt792x_mutex_acquire` is defined. Aha, it's defined in `mt792x.h`. I need to review that header file to understand the context and how the mutex is declared and managed. I need to be sure that the mutex is being used correctly across all the different access paths. This direct call by `mt7921_mac_sta_add` needs to be investigated further.



22/2 2026/06/29 09:02 tool grepper
0m Args:
{
  "Expression": "define mt792x_mutex_acquire",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt792x.h=381=static inline bool mt792x_dma_need_reinit(struct mt792x_dev *dev)\n--\ndrivers/net/wireless/mediatek/mt76/mt792x.h-385-\ndrivers/net/wireless/mediatek/mt76/mt792x.h:386:#define mt792x_mutex_acquire(dev)\t\\\ndrivers/net/wireless/mediatek/mt76/mt792x.h-387-\tmt76_connac_mutex_acquire(\u0026(dev)-\u003emt76, \u0026(dev)-\u003epm)\n"
}

23/2 2026/06/29 09:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 47216
							output: 50
							thoughts: 259
						

Thoughts:
**Mutex Conundrum in MT7921 Driver**

Okay, let's break this down. My initial thought was that `mt792x_mutex_acquire` calls `mt76_connac_mutex_acquire`, which ultimately locks the device mutex (`dev->mutex`). So, at first glance, `mt7921_mac_sta_add` doesn't directly acquire that device mutex. That's good. But then I remembered that `mt7921_mac_sta_add` is called from within mac80211. And mac80211 has its own set of mutexes, so it wouldn't be holding `dev->mutex` either.

Now, things get interesting. `mt7921_regd_set_6ghz_power_type` calls `__mt7921_mcu_regd_update`, and *that* function seems to assume that the device mutex is already held. Alarm bells! If `mt7921_mac_sta_add` doesn't hold the mutex, and `mt7921_regd_set_6ghz_power_type` calls `__mt7921_mcu_regd_update`, then we have a potential race condition and a missing mutex lock, right? I need to double-check `mt7921_regd_set_6ghz_power_type` more closely. This needs further investigation.



24/2 2026/06/29 09:03 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/main.c",
  "FirstLine": 765,
  "LineCount": 45
}

Results:
{
  "Contents": " 765:\tstatic void\n 766:\tmt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)\n 767:\t{\n 768:\t\tstruct mt792x_vif *mvif = (struct mt792x_vif *)vif-\u003edrv_priv;\n 769:\t\tstruct mt792x_phy *phy = mvif-\u003ephy;\n 770:\t\tstruct mt792x_dev *dev = phy-\u003edev;\n 771:\t\tu32 valid_vif_num = 0;\n 772:\t\n 773:\t\tieee80211_iterate_active_interfaces(mt76_hw(dev),\n 774:\t\t\t\t\t\t    IEEE80211_IFACE_ITER_RESUME_ALL,\n 775:\t\t\t\t\t\t    mt7921_calc_vif_num, \u0026valid_vif_num);\n 776:\t\n 777:\t\tif (valid_vif_num \u003e 1) {\n 778:\t\t\tphy-\u003epower_type = MT_AP_DEFAULT;\n 779:\t\t\tgoto out;\n 780:\t\t}\n 781:\t\n 782:\t\tif (!is_add)\n 783:\t\t\tvif-\u003ebss_conf.power_type = IEEE80211_REG_UNSET_AP;\n 784:\t\n 785:\t\tswitch (vif-\u003ebss_conf.power_type) {\n 786:\t\tcase IEEE80211_REG_SP_AP:\n 787:\t\t\tphy-\u003epower_type = MT_AP_SP;\n 788:\t\t\tbreak;\n 789:\t\tcase IEEE80211_REG_VLP_AP:\n 790:\t\t\tphy-\u003epower_type = MT_AP_VLP;\n 791:\t\t\tbreak;\n 792:\t\tcase IEEE80211_REG_LPI_AP:\n 793:\t\t\tphy-\u003epower_type = MT_AP_LPI;\n 794:\t\t\tbreak;\n 795:\t\tcase IEEE80211_REG_UNSET_AP:\n 796:\t\t\tphy-\u003epower_type = MT_AP_UNSET;\n 797:\t\t\tbreak;\n 798:\t\tdefault:\n 799:\t\t\tphy-\u003epower_type = MT_AP_DEFAULT;\n 800:\t\t\tbreak;\n 801:\t\t}\n 802:\t\n 803:\tout:\n 804:\t\tif (vif-\u003ebss_conf.chanreq.oper.chan-\u003eband == NL80211_BAND_6GHZ)\n 805:\t\t\t__mt7921_mcu_regd_update(dev, dev-\u003emt76.alpha2, dev-\u003ecountry_ie_env);\n 806:\t}\n 807:\t\n 808:\tint mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n 809:\t\t\t       struct ieee80211_sta *sta)\n"
}

25/2 2026/06/29 09:03 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 48687
							output: 50
							thoughts: 64
						

Thoughts:
Okay, let's break this down.

**Investigating the `mt7921_mac_sta_add` Function**

Hmm, so `mt7921_mac_sta_add` is *definitely* called by mac80211, which is good to know, confirming my initial hunch. But now, a crucial question arises. Does this function, `mt7921_mac_sta_add`, handle its own mutex locking? That’s going to be key to understanding potential race conditions and concurrency issues if it doesn't. If mac80211 calls this function, and `mt7921_mac_sta_add` doesn't protect itself internally, we have a problem. I better go back and check the code for `mt7921_mac_sta_add` carefully, specifically looking at how it handles locks. This is where the devil is in the details. I need to know *exactly* what this function does and how it ensures thread safety.



26/2 2026/06/29 09:03 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/main.c",
  "FirstLine": 808,
  "LineCount": 50
}

Results:
{
  "Contents": " 808:\tint mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n 809:\t\t\t       struct ieee80211_sta *sta)\n 810:\t{\n 811:\t\tstruct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);\n 812:\t\tstruct mt792x_sta *msta = (struct mt792x_sta *)sta-\u003edrv_priv;\n 813:\t\tstruct mt792x_vif *mvif = (struct mt792x_vif *)vif-\u003edrv_priv;\n 814:\t\tint ret, idx;\n 815:\t\n 816:\t\tif (sta-\u003eaid \u003e MT7921_MAX_AID)\n 817:\t\t\treturn -ENOENT;\n 818:\t\n 819:\t\tidx = mt76_wcid_alloc(dev-\u003emt76.wcid_mask, MT792x_WTBL_STA - 1);\n 820:\t\tif (idx \u003c 0)\n 821:\t\t\treturn -ENOSPC;\n 822:\t\n 823:\t\tINIT_LIST_HEAD(\u0026msta-\u003edeflink.wcid.poll_list);\n 824:\t\tmsta-\u003evif = mvif;\n 825:\t\tmsta-\u003edeflink.wcid.sta = 1;\n 826:\t\tmsta-\u003edeflink.wcid.idx = idx;\n 827:\t\tmsta-\u003edeflink.wcid.phy_idx = mvif-\u003ebss_conf.mt76.band_idx;\n 828:\t\tmsta-\u003edeflink.wcid.tx_info |= MT_WCID_TX_INFO_SET;\n 829:\t\tmsta-\u003edeflink.last_txs = jiffies;\n 830:\t\tmsta-\u003edeflink.sta = msta;\n 831:\t\n 832:\t\tif (sta-\u003etdls)\n 833:\t\t\tset_bit(MT_WCID_FLAG_TDLS_PEER, \u0026msta-\u003edeflink.wcid.flags);\n 834:\t\n 835:\t\tret = mt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n 836:\t\tif (ret)\n 837:\t\t\treturn ret;\n 838:\t\n 839:\t\tif (vif-\u003etype == NL80211_IFTYPE_STATION)\n 840:\t\t\tmvif-\u003ewep_sta = msta;\n 841:\t\n 842:\t\tmt7921_mac_wtbl_update(dev, idx,\n 843:\t\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\n 844:\t\n 845:\t\tret = mt7921_mcu_sta_update(dev, sta, vif, true,\n 846:\t\t\t\t\t    MT76_STA_INFO_STATE_NONE);\n 847:\t\tif (ret)\n 848:\t\t\treturn ret;\n 849:\t\n 850:\t\tmt7921_regd_set_6ghz_power_type(vif, true);\n 851:\t\n 852:\t\tmt76_connac_power_save_sched(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n 853:\t\n 854:\t\treturn 0;\n 855:\t}\n 856:\tEXPORT_SYMBOL_GPL(mt7921_mac_sta_add);\n 857:\t\n"
}

27/2 2026/06/29 09:03 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49978
							output: 42
							thoughts: 93
						

Thoughts:
**Analyzing the mt7921 Mac Station Addition**

Okay, so I'm digging into this `mt7921_mac_sta_add` function and it's assigned to the `sta_add` callback, which makes sense. My immediate next step is to recall how that callback is invoked within the `mt76` framework. Right, the `sta_add` callback is called from `mt76_mac_sta_add`. Now, I need to confirm the implementation and any nuances, so I'm heading straight to `drivers/net/wireless/mediatek/mt76/mac80211.c` to examine `mt76_mac_sta_add`. I expect to find the actual call there, and I'll be looking for any context-dependent logic or potential areas of concern during this station addition process.



28/2 2026/06/29 09:03 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "mt76_mac_sta_add",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/"
}

Results:
{
  "error": "no matches"
}

29/2 2026/06/29 09:03 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 50313
							output: 36
							thoughts: 35
						

Thoughts:
Here's my take on the thought process, as if it were my own:

**Connecting the Dots: Probe Function and Driver Operations**

Okay, let me see... I'm tracing this `mt7921` driver initialization. The `sta_add` function... where does *that* get called from? Right, it's being assigned to the `sta_add` field within the `mt76_driver_ops` structure. And that structure, aha, that's being used within the `mt7921_pci_probe` function. So, the PCI probe function is essentially the entry point for detecting the device, and then it's using the standard `mt76_driver_ops` structure, which has the `sta_add` function hook. Got it, so it's all part of the standard `mt76` framework. The probe function sets up the device, then the `mt76` framework handles the rest. This confirms my understanding.



30/2 2026/06/29 09:03 tool grepper
0m Args:
{
  "Expression": "sta_add",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mac80211.c=1575=static int\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1576:mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1577-\t     struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1586-\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1587:\tret = dev-\u003edrv-\u003esta_add(dev, vif, sta);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1588-\tif (ret)\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c=1651=int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1665-\t    new_state == IEEE80211_STA_NONE)\ndrivers/net/wireless/mediatek/mt76/mac80211.c:1666:\t\treturn mt76_sta_add(phy, vif, sta);\ndrivers/net/wireless/mediatek/mt76/mac80211.c-1667-\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h=543=struct mt76_driver_ops {\n--\ndrivers/net/wireless/mediatek/mt76/mt76.h-577-\ndrivers/net/wireless/mediatek/mt76/mt76.h:578:\tint (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt76.h-579-\t\t       struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/init.c=8=const struct mt76_driver_ops mt7603_drv_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/init.c-16-\t.sta_ps = mt7603_sta_ps,\ndrivers/net/wireless/mediatek/mt76/mt7603/init.c:17:\t.sta_add = mt7603_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7603/init.c-18-\t.sta_event = mt7603_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/main.c=326=int\ndrivers/net/wireless/mediatek/mt76/mt7603/main.c:327:mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7603/main.c-328-\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h=246=void mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h:247:int mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7603/mt7603.h-248-\t\t   struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=246=static void mt7615_remove_interface(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-257-\tmt7615_mcu_add_bss_info(phy, vif, NULL, false);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:258:\tmt7615_mcu_sta_add(phy, vif, NULL, false);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-259-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=567=static void mt7615_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-587-\t\tmt7615_mcu_add_bss_info(phy, vif, NULL, true);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:588:\t\tmt7615_mcu_sta_add(phy, vif, NULL, true);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-589-\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=623=mt7615_channel_switch_beacon(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-633-\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:634:int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-635-\t\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-665-\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:666:\terr = mt7615_mcu_sta_add(\u0026dev-\u003ephy, vif, sta, true);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-667-\tif (err)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-673-}\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:674:EXPORT_SYMBOL_GPL(mt7615_mac_sta_add);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-675-\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=676=void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-688-\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:689:\tmt7615_mcu_sta_add(\u0026dev-\u003ephy, vif, sta, false);\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-690-\tmt7615_mac_wtbl_update(dev, msta-\u003ewcid.idx,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=862=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:863:mt7615_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-864-\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c=1318=const struct ieee80211_ops mt7615_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-1331-\t.bss_info_changed = mt7615_bss_info_changed,\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c:1332:\t.sta_add = mt7615_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7615/main.c-1333-\t.sta_remove = mt7615_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=839=static int\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:840:mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-841-\t\t\tstruct ieee80211_sta *sta, bool enable)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-861-\tif (!sta) {\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:862:\t\tif (mvif-\u003esta_added)\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-863-\t\t\tnew_entry = false;\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-864-\t\telse\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:865:\t\t\tmvif-\u003esta_added = true;\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-866-\t}\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=917=static const struct mt7615_mcu_ops wtbl_update_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-923-\t.add_rx_ba = mt7615_mcu_wtbl_rx_ba,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:924:\t.sta_add = mt7615_mcu_wtbl_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-925-\t.set_drv_ctrl = mt7615_mcu_drv_pmctrl,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1017=static const struct mt7615_mcu_ops sta_update_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1023-\t.add_rx_ba = mt7615_mcu_sta_rx_ba,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1024:\t.sta_add = mt7615_mcu_add_sta,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1025-\t.set_drv_ctrl = mt7615_mcu_drv_pmctrl,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c=1208=static const struct mt7615_mcu_ops uni_update_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1214-\t.add_rx_ba = mt7615_mcu_uni_rx_ba,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c:1215:\t.sta_add = mt7615_mcu_uni_add_sta,\ndrivers/net/wireless/mediatek/mt76/mt7615/mcu.c-1216-\t.set_drv_ctrl = mt7615_mcu_lp_drv_pmctrl,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c=166=int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c-181-\t\t.rx_poll_complete = mt7615_rx_poll_complete,\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c:182:\t\t.sta_add = mt7615_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7615/mmio.c-183-\t\t.sta_remove = mt7615_mac_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=142=struct mt7615_vif {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-144-\tstruct mt7615_sta sta;\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:145:\tbool sta_added;\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-146-};\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=157=struct mt7615_phy {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-209-#define mt7615_mcu_add_rx_ba(dev, ...)\t(dev)-\u003emcu_ops-\u003eadd_rx_ba((dev), __VA_ARGS__)\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:210:#define mt7615_mcu_sta_add(phy, ...)\t((phy)-\u003edev)-\u003emcu_ops-\u003esta_add((phy),  __VA_ARGS__)\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-211-#define mt7615_mcu_add_dev_info(phy, ...) ((phy)-\u003edev)-\u003emcu_ops-\u003eadd_dev_info((phy),  __VA_ARGS__)\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=218=struct mt7615_mcu_ops {\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-224-\t\t\t bool enable);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:225:\tint (*sta_add)(struct mt7615_phy *phy, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-226-\t\t       struct ieee80211_sta *sta, bool enable);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h=505=void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-506-\t\t\t struct sk_buff *skb, u32 *info);\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h:507:int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7615/mt7615.h-508-\t\t       struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c=76=static int mt7663s_probe(struct sdio_func *func,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-86-\t\t.rx_check = mt7615_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c:87:\t\t.sta_add = mt7615_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7615/sdio.c-88-\t\t.sta_remove = mt7615_mac_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c=112=static int mt7663u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-122-\t\t.rx_check = mt7615_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c:123:\t\t.sta_add = mt7615_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7615/usb.c-124-\t\t.sta_remove = mt7615_mac_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c=154=mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-168-\t\t.sta_ps = mt76x02_sta_ps,\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c:169:\t\t.sta_add = mt76x02_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt76x0/pci.c-170-\t\t.sta_remove = mt76x02_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c=213=static int mt76x0u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c-226-\t\t.sta_ps = mt76x02_sta_ps,\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c:227:\t\t.sta_add = mt76x02_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt76x0/usb.c-228-\t\t.sta_remove = mt76x02_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02.h=152=void mt76x02_configure_filter(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02.h-154-\t\t\t      unsigned int *total_flags, u64 multicast);\ndrivers/net/wireless/mediatek/mt76/mt76x02.h:155:int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt76x02.h-156-\t\t    struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c=236=EXPORT_SYMBOL_GPL(mt76x02_configure_filter);\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c-237-\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c:238:int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c-239-\t\t    struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c-264-}\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c:265:EXPORT_SYMBOL_GPL(mt76x02_sta_add);\ndrivers/net/wireless/mediatek/mt76/mt76x02_util.c-266-\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c=20=mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-34-\t\t.sta_ps = mt76x02_sta_ps,\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c:35:\t\t.sta_add = mt76x02_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt76x2/pci.c-36-\t\t.sta_remove = mt76x02_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c=32=static int mt76x2u_probe(struct usb_interface *intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c-45-\t\t.sta_ps = mt76x02_sta_ps,\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c:46:\t\t.sta_add = mt76x02_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt76x2/usb.c-47-\t\t.sta_remove = mt76x02_sta_remove,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c=1477=DEFINE_SHOW_ATTRIBUTE(mt7915_queues);\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-1478-\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:1479:void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7915/debugfs.c-1480-\t\t\t    struct ieee80211_sta *sta, struct dentry *dir)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c=731=mt7915_channel_switch_beacon(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-741-\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c:742:int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-743-\t\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c=775=struct drop_sta_iter {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-778-\tstruct ieee80211_vif *vif;\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c:779:\tu8 sta_addr[ETH_ALEN];\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-780-};\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c=783=__mt7915_drop_sta(void *ptr, u8 *mac, struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-791-\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c:792:\tsta = ieee80211_find_sta_by_ifaddr(data-\u003ehw, data-\u003esta_addr, mac);\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-793-\tif (!sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c=803=mt7915_drop_other_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-815-\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c:816:\tmemcpy(data.sta_addr, sta-\u003eaddr, ETH_ALEN);\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-817-\tieee80211_iterate_active_interfaces(data.hw, 0, __mt7915_drop_sta, \u0026data);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c=1765=const struct ieee80211_ops mt7915_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-1815-#ifdef CONFIG_MAC80211_DEBUGFS\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c:1816:\t.sta_add_debugfs = mt7915_sta_add_debugfs,\ndrivers/net/wireless/mediatek/mt76/mt7915/main.c-1817-#endif\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mmio.c=917=struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mmio.c-933-\t\t.rx_poll_complete = mt7915_rx_poll_complete,\ndrivers/net/wireless/mediatek/mt76/mt7915/mmio.c:934:\t\t.sta_add = mt7915_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7915/mmio.c-935-\t\t.sta_event = mt7915_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h=581=void mt7915_mac_set_timing(struct mt7915_phy *phy);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h:582:int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h-583-\t\t       struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h=617=bool mt7915_debugfs_rx_log(struct mt7915_dev *dev, const void *data, int len);\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h-618-#ifdef CONFIG_MAC80211_DEBUGFS\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h:619:void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7915/mt7915.h-620-\t\t\t    struct ieee80211_sta *sta, struct dentry *dir);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=766=mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-807-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:808:int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-809-\t\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-855-}\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:856:EXPORT_SYMBOL_GPL(mt7921_mac_sta_add);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-857-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h=264=bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask);\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h:265:int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h-266-\t\t       struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c=259=static int mt7921_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-275-\t\t.rx_poll_complete = mt792x_rx_poll_complete,\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c:276:\t\t.sta_add = mt7921_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7921/pci.c-277-\t\t.sta_event = mt7921_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c=90=static int mt7921s_probe(struct sdio_func *func,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-103-\t\t.rx_check = mt7921_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c:104:\t\t.sta_add = mt7921_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7921/sdio.c-105-\t\t.sta_event = mt7921_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c=150=static int mt7921u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-164-\t\t.rx_check = mt7921_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c:165:\t\t.sta_add = mt7921_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7921/usb.c-166-\t\t.sta_event = mt7921_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=859=mt7925_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-886-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:887:static int mt7925_mac_link_sta_add(struct mt76_dev *mdev,\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-888-\t\t\t\t   struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1027-/*\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1028: * Host-only unwind for sta_add_links() failures.\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1029- *\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=1066=static int\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1067:mt7925_mac_sta_add_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1068-\t\t\t struct ieee80211_sta *sta, unsigned long new_links)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1095-\t\tlink_sta = mt792x_sta_to_link_sta(vif, sta, link_id);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1096:\t\terr = mt7925_mac_link_sta_add(\u0026dev-\u003emt76, vif, link_sta, mlink);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1097-\t\tif (err) {\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1117-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1118:int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1119-\t\t       struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1133-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1134:\t\terr = mt7925_mac_sta_add_links(dev, vif, sta, sta-\u003evalid_links);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1135-\t} else {\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1136:\t\terr = mt7925_mac_link_sta_add(mdev, vif, \u0026sta-\u003edeflink,\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1137-\t\t\t\t\t      \u0026msta-\u003edeflink);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1141-}\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:1142:EXPORT_SYMBOL_GPL(mt7925_mac_sta_add);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-1143-\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c=2232=mt7925_change_sta_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2248-\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c:2249:\terr = mt7925_mac_sta_add_links(dev, vif, sta, add);\ndrivers/net/wireless/mediatek/mt76/mt7925/main.c-2250-\tif (err \u003c 0)\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/mt7925.h=293=int mt7925_mac_init(struct mt792x_dev *dev);\ndrivers/net/wireless/mediatek/mt76/mt7925/mt7925.h:294:int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7925/mt7925.h-295-\t\t       struct ieee80211_sta *sta);\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c=313=static int mt7925_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c-329-\t\t.rx_poll_complete = mt792x_rx_poll_complete,\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c:330:\t\t.sta_add = mt7925_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7925/pci.c-331-\t\t.sta_event = mt7925_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c=143=static int mt7925u_probe(struct usb_interface *usb_intf,\n--\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-157-\t\t.rx_check = mt7925_rx_check,\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c:158:\t\t.sta_add = mt7925_mac_sta_add,\ndrivers/net/wireless/mediatek/mt76/mt7925/usb.c-159-\t\t.sta_event = mt7925_mac_sta_event,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c=983=DEFINE_SHOW_ATTRIBUTE(mt7996_queues);\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c-984-\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c:985:void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c-986-\t\t\t    struct ieee80211_sta *sta, struct dentry *dir)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c=1064=static const struct file_operations fops_fixed_rate = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c-1070-\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c:1071:void mt7996_link_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7996/debugfs.c-1072-\t\t\t\t struct ieee80211_link_sta *link_sta,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c=1258=static int\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:1259:mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1260-\t\t\t struct ieee80211_sta *sta, unsigned long new_links)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c=1320=mt7996_mac_sta_change_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1331-\tmt7996_mac_sta_remove_links(dev, vif, sta, rem, false);\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:1332:\tret = mt7996_mac_sta_add_links(dev, vif, sta, add);\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1333-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c=1339=static int\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:1340:mt7996_mac_sta_add(struct mt7996_dev *dev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1341-\t\t   struct ieee80211_sta *sta)\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1352-\tmsta-\u003evif = mvif;\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:1353:\terr = mt7996_mac_sta_add_links(dev, vif, sta, links);\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1354-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c=1468=mt7996_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1476-\t    new_state == IEEE80211_STA_NONE)\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:1477:\t\treturn mt7996_mac_sta_add(dev, vif, sta);\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-1478-\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c=2510=const struct ieee80211_ops mt7996_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-2559-#ifdef CONFIG_MAC80211_DEBUGFS\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:2560:\t.sta_add_debugfs = mt7996_sta_add_debugfs,\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c:2561:\t.link_sta_add_debugfs = mt7996_link_sta_add_debugfs,\ndrivers/net/wireless/mediatek/mt76/mt7996/main.c-2562-#endif\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h=929=int mt7996_mcu_set_emlsr_mode(struct mt7996_dev *dev,\n--\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h-933-#ifdef CONFIG_MAC80211_DEBUGFS\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h:934:void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h-935-\t\t\t    struct ieee80211_sta *sta, struct dentry *dir);\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h:936:void mt7996_link_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7996/mt7996.h-937-\t\t\t\t struct ieee80211_link_sta *link_sta,\n"
}

31/2 2026/06/29 09:03 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 63173
							output: 50
							thoughts: 1029
						

Thoughts:
**Analyzing a Potential Race Condition in the MT7921 Driver**

Okay, so I'm diving into this MT7921 driver code, trying to understand this logic around station (STA) addition. It looks like `mt76_sta_add` eventually leads to a call to the driver's specific `sta_add` function.  The interesting part is that `mt76_sta_add` is called either from `mt76_sta_state` or `mt76_mac_sta_add`. `mt76_sta_state` itself calls `mt76_sta_add`. My concern is whether a mutex is correctly held during these calls, because `mt7921_mac_sta_add` does not appear to hold `dev->mutex`.

My first thought is, mac80211 might be doing something, but I can see that mac80211 doesn't manage driver-specific mutexes.  So,  `mt7921_mac_sta_add` gets called directly. However, within `mt7921_mac_sta_add`, it calls `mt7921_regd_set_6ghz_power_type`. This, in turn, calls `__mt7921_mcu_regd_update`.  The thing is, `__mt7921_mcu_regd_update` *assumes* the mutex is held!

Aha! We have a potential race condition.  `mt7921_mac_sta_add` doesn't hold the mutex, but it calls a function that expects it! Let's examine the patch that modified `mt7921_regd_set_6ghz_power_type`. The author is changing the function call to `__mt7921_mcu_regd_update`, which suggests the mutex is *already* held at that point.

But where? Before the patch, `mt7921_mcu_regd_update` had its own mutex handling. It was originally implemented like this, so it could handle calls when the mutex wasn't held. But the change means that isn't the case any longer. Now the function expects the mutex to be held. So, if we are calling `__mt7921_mcu_regd_update` directly, then we *need* to acquire the mutex beforehand.

So, let's look at `mt7921_mac_sta_add` again, to find where the mutex is acquired. I've got the code up, and I can see that `mt76_connac_pm_wake` is called before, but I know that `mt76_connac_mutex_acquire` is explicitly used with it, which means `mt76_connac_pm_wake` does *not* acquire the mutex.  `mt7921_mcu_sta_update` is also called, but I can confirm that it does not acquire the mutex.

So, where else is `mt7921_regd_set_6ghz_power_type` called? I should also check `mt7921_mac_sta_remove`. It's possible the mutex is held there.



32/2 2026/06/29 09:03 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/main.c",
  "FirstLine": 891,
  "LineCount": 40
}

Results:
{
  "Contents": " 891:\tvoid mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n 892:\t\t\t\t   struct ieee80211_sta *sta)\n 893:\t{\n 894:\t\tstruct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);\n 895:\t\tstruct mt792x_sta *msta = (struct mt792x_sta *)sta-\u003edrv_priv;\n 896:\t\n 897:\t\tmt7921_roc_abort_sync(dev);\n 898:\t\tmt76_connac_free_pending_tx_skbs(\u0026dev-\u003epm, \u0026msta-\u003edeflink.wcid);\n 899:\t\tmt76_connac_pm_wake(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n 900:\t\n 901:\t\tmt7921_mcu_sta_update(dev, sta, vif, false, MT76_STA_INFO_STATE_NONE);\n 902:\t\tmt7921_mac_wtbl_update(dev, msta-\u003edeflink.wcid.idx,\n 903:\t\t\t\t       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);\n 904:\t\n 905:\t\tif (vif-\u003etype == NL80211_IFTYPE_STATION) {\n 906:\t\t\tstruct mt792x_vif *mvif = (struct mt792x_vif *)vif-\u003edrv_priv;\n 907:\t\n 908:\t\t\tmvif-\u003ewep_sta = NULL;\n 909:\t\t\tewma_rssi_init(\u0026mvif-\u003ebss_conf.rssi);\n 910:\t\t\tif (!sta-\u003etdls)\n 911:\t\t\t\tmt76_connac_mcu_uni_add_bss(\u0026dev-\u003emphy, vif,\n 912:\t\t\t\t\t\t\t    \u0026mvif-\u003esta.deflink.wcid, false,\n 913:\t\t\t\t\t\t\t    mvif-\u003ebss_conf.mt76.ctx);\n 914:\t\t}\n 915:\t\n 916:\t\tspin_lock_bh(\u0026dev-\u003emt76.sta_poll_lock);\n 917:\t\tif (!list_empty(\u0026msta-\u003edeflink.wcid.poll_list))\n 918:\t\t\tlist_del_init(\u0026msta-\u003edeflink.wcid.poll_list);\n 919:\t\tspin_unlock_bh(\u0026dev-\u003emt76.sta_poll_lock);\n 920:\t\n 921:\t\tmt7921_regd_set_6ghz_power_type(vif, false);\n 922:\t\n 923:\t\tmt76_connac_power_save_sched(\u0026dev-\u003emphy, \u0026dev-\u003epm);\n 924:\t}\n 925:\tEXPORT_SYMBOL_GPL(mt7921_mac_sta_remove);\n 926:\t\n 927:\tstatic int mt7921_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,\n 928:\t\t\t\t\t    u32 val)\n 929:\t{\n 930:\t\tstruct mt792x_dev *dev = mt792x_hw_dev(hw);\n"
}

33/2 2026/06/29 09:03 llm patch-evaluator
1m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 65864
							output: 50
							thoughts: 218
						

Thoughts:
**Analyzing Potential Deadlock in MT7921 Driver**

Okay, so I'm looking at this `mt7921_mac_sta_remove` function and realizing it *also* doesn't seem to hold `dev->mutex`. That's interesting, but not the focus right now. My main concern is that I suspect `mt7921_mcu_regd_update` might be deadlocking. The more I think about it, the more I'm leaning towards the idea that the problem stems from `mt7921_mac_sta_add` being called while another lock is already held.  And since `mt7921_mcu_regd_update` *also* tries to acquire `dev->mutex`, we've got a classic deadlock scenario brewing.  If `dev->mutex` is already taken, calling `__mt7921_mcu_regd_update` seems like a step in the right direction. It makes sense, in that scenario.

But now I need to find where `dev->mutex` *could* be held at the time of the call. I need to trace this back.  In mac80211, `sta_add` is actually called from `mac80211_sta_add`. Then I remember, `mt76` has its own wrapper, `mt76_sta_add`, and that is called from `mt76_sta_state`. This is the most likely place where the lock is taken before `mt7921_mac_sta_add` is called. So, I need to check `mt76_sta_state` very carefully to understand exactly what's going on there.



34/2 2026/06/29 09:05 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mac80211.c",
  "FirstLine": 1651,
  "LineCount": 40
}

Results:
{
  "Contents": "1651:\tint mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n1652:\t\t\t   struct ieee80211_sta *sta,\n1653:\t\t\t   enum ieee80211_sta_state old_state,\n1654:\t\t\t   enum ieee80211_sta_state new_state)\n1655:\t{\n1656:\t\tstruct mt76_phy *phy = hw-\u003epriv;\n1657:\t\tstruct mt76_dev *dev = phy-\u003edev;\n1658:\t\tenum mt76_sta_event ev;\n1659:\t\n1660:\t\tphy = mt76_vif_phy(hw, vif);\n1661:\t\tif (!phy)\n1662:\t\t\treturn -EINVAL;\n1663:\t\n1664:\t\tif (old_state == IEEE80211_STA_NOTEXIST \u0026\u0026\n1665:\t\t    new_state == IEEE80211_STA_NONE)\n1666:\t\t\treturn mt76_sta_add(phy, vif, sta);\n1667:\t\n1668:\t\tif (old_state == IEEE80211_STA_NONE \u0026\u0026\n1669:\t\t    new_state == IEEE80211_STA_NOTEXIST)\n1670:\t\t\tmt76_sta_remove(phy, vif, sta);\n1671:\t\n1672:\t\tif (!dev-\u003edrv-\u003esta_event)\n1673:\t\t\treturn 0;\n1674:\t\n1675:\t\tif (old_state == IEEE80211_STA_AUTH \u0026\u0026\n1676:\t\t    new_state == IEEE80211_STA_ASSOC)\n1677:\t\t\tev = MT76_STA_EVENT_ASSOC;\n1678:\t\telse if (old_state == IEEE80211_STA_ASSOC \u0026\u0026\n1679:\t\t\t new_state == IEEE80211_STA_AUTHORIZED)\n1680:\t\t\tev = MT76_STA_EVENT_AUTHORIZE;\n1681:\t\telse if (old_state == IEEE80211_STA_ASSOC \u0026\u0026\n1682:\t\t\t new_state == IEEE80211_STA_AUTH)\n1683:\t\t\tev = MT76_STA_EVENT_DISASSOC;\n1684:\t\telse\n1685:\t\t\treturn 0;\n1686:\t\n1687:\t\treturn dev-\u003edrv-\u003esta_event(dev, vif, sta, ev);\n1688:\t}\n1689:\tEXPORT_SYMBOL_GPL(mt76_sta_state);\n1690:\t\n"
}

35/2 2026/06/29 09:05 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 67232
							output: 42
							thoughts: 114
						

Thoughts:
**Analyzing a Potential Race Condition in the MT76 Driver**

Okay, hold on a second. I'm taking a closer look at this `mt76_sta_state` function. My initial impression is that it doesn't seem to acquire the `dev->mutex` directly, which is a bit concerning, considering its potential interaction with other parts of the driver.

So, the next thing I need to do is confirm that. I need to figure out how `mt76_sta_state` is actually *called*. Specifically, I need to know if it's being invoked with the `dev->mutex` already held. It looks like it is an `ieee80211_ops` callback, which means it's part of the mac80211 stack.

Ah, right, now I see, the mac80211 layer can call the `sta_state` without explicit knowledge of our `dev->mutex`. This is starting to look like a possible race condition, especially if `mt76_sta_state` is accessing any shared data unprotected. 

Wait a minute, maybe I'm jumping to conclusions. Perhaps `mt76_sta_state` is wrapped by something. Let me check the `mt7921_ops` structure. I need to make sure the function pointer is not pointing to an intermediate wrapper that *does* take care of the mutex. This is a critical step to confirm my suspicion.



36/2 2026/06/29 09:06 tool grepper
0m Args:
{
  "Expression": "sta_state",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7921/main.c=940=mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-995-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:996:static int mt7921_sta_state(struct ieee80211_hw *hw,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-997-\t\t\t    struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-998-\t\t\t    struct ieee80211_sta *sta,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:999:\t\t\t    enum ieee80211_sta_state old_state,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1000:\t\t\t    enum ieee80211_sta_state new_state)\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1001-{\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1005-\t\tmt792x_mutex_acquire(dev);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1006:\t\tmt76_connac_sta_state_dp(\u0026dev-\u003emt76, old_state, new_state);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1007-\t\tmt792x_mutex_release(dev);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1009-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1010:\treturn mt76_sta_state(hw, vif, sta, old_state, new_state);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1011-}\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1548=const struct ieee80211_ops mt7921_ops = {\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1559-\t.stop_ap = mt7921_stop_ap,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1560:\t.sta_state = mt7921_sta_state,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1561-\t.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,\n"
}

37/2 2026/06/29 09:06 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 68525
							output: 51
							thoughts: 779
						

Thoughts:
**Analyzing the Concurrency in the MT7921 Driver**

Okay, let's break this down. My initial thought was that `mt7921_sta_state` was not acquiring the `dev->mutex` before calling `mt76_sta_state`. I saw the conditional block with `mt792x_mutex_acquire` and `mt792x_mutex_release`, but it's only executed if `dev->pm.ds_enable` is true. In the other case `mt76_sta_state` is being called without `dev->mutex` being held.

This is where it gets interesting. `mt76_sta_state` then calls `mt76_sta_add`, which subsequently calls `mt7921_mac_sta_add`. And it is here that `mt7921_mac_sta_add` calls `mt7921_regd_set_6ghz_power_type`, which in turn calls `__mt7921_mcu_regd_update`. The problem is that `__mt7921_mcu_regd_update` *assumes* the mutex is held. If the mutex isn't held when calling `__mt7921_mcu_regd_update`, then it won't be acquired, leading to a race condition. Is this intentional? I need to know if `mt7921_mac_sta_add` is holding the mutex.

I looked at the code for `__mt7921_mcu_regd_update`. I was able to verify that the function has a check for `dev->regd_change` to return, and it calls `mt7921_mcu_set_clc` but that doesn't tell me about the mutex being held.

So, I went back to `mt7921_mac_sta_add`. I saw that it calls `mt76_connac_pm_wake`. Then I saw that `mt76_connac_pm_wake` does *not* acquire the mutex. But, hold on a second. `mt76_connac_mutex_acquire` *does* acquire the mutex and then calls `mt76_connac_pm_wake`. This means that `mt7921_mac_sta_add` does *not* call `mt76_connac_mutex_acquire` first, it calls `mt76_connac_pm_wake` directly. I need to look at `mt7921_mcu_sta_update` since it is also called before `mt7921_regd_set_6ghz_power_type`.

This means I need to carefully review the concurrency model around `mt7921_mac_sta_add`, specifically concerning the `dev->mutex` and its interaction with `__mt7921_mcu_regd_update`. I suspect I've found a potential race condition.



38/2 2026/06/29 09:06 tool grepper
0m Args:
{
  "Expression": "mt7921_mcu_sta_update",
  "PathPrefix": "drivers/net/wireless/mediatek/mt76/mt7921/"
}

Results:
{
  "Output": "drivers/net/wireless/mediatek/mt76/mt7921/mac.c=630=mt7921_vif_connect_iter(void *priv, u8 *mac,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-647-\t\t\t\t\t    true, NULL);\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c:648:\t\tmt7921_mcu_sta_update(dev, NULL, vif, true,\ndrivers/net/wireless/mediatek/mt76/mt7921/mac.c-649-\t\t\t\t      MT76_STA_INFO_STATE_NONE);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=695=static void mt7921_bss_info_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-729-\tif (changed \u0026 BSS_CHANGED_ASSOC) {\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:730:\t\tmt7921_mcu_sta_update(dev, NULL, vif, true,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-731-\t\t\t\t      MT76_STA_INFO_STATE_ASSOC);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=808=int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-844-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:845:\tret = mt7921_mcu_sta_update(dev, sta, vif, true,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-846-\t\t\t\t    MT76_STA_INFO_STATE_NONE);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=858=int mt7921_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-882-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:883:\tmt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-884-\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=891=void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-900-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:901:\tmt7921_mcu_sta_update(dev, sta, vif, false, MT76_STA_INFO_STATE_NONE);\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-902-\tmt7921_mac_wtbl_update(dev, msta-\u003edeflink.wcid.idx,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c=1334=mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1352-\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c:1353:\terr = mt7921_mcu_sta_update(dev, NULL, vif, true,\ndrivers/net/wireless/mediatek/mt76/mt7921/main.c-1354-\t\t\t\t    MT76_STA_INFO_STATE_NONE);\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c=1010=mt7921_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c-1046-\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c:1047:int mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta,\ndrivers/net/wireless/mediatek/mt76/mt7921/mcu.c-1048-\t\t\t  struct ieee80211_vif *vif, bool enable,\n--\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h=209=int mt7921_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif,\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h-210-\t\t\t  bool enable);\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h:211:int mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta,\ndrivers/net/wireless/mediatek/mt76/mt7921/mt7921.h-212-\t\t\t  struct ieee80211_vif *vif, bool enable,\n"
}

39/2 2026/06/29 09:06 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 71656
							output: 52
							thoughts: 214
						

Thoughts:
**Analyzing the Thread Safety of the MT7921 Driver's Station Handling**

Okay, let's break this down. I'm looking at how station events are handled in this `mt7921` driver. I see that the `mt7921_mac_sta_event` function acquires the mutex using `mt792x_mutex_acquire`. Specifically:

```c
	mt792x_mutex_acquire(dev);
	mt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC);
	mt792x_mutex_release(dev);
```

Right, it grabs the mutex *before* calling `mt7921_mcu_sta_update`. Makes sense, standard mutex usage for protection. I see that and my immediate thought is "Ah, okay, `mt7921_mac_sta_event` is correctly handling mutex acquisition".

But then... I realize that `mt7921_mac_sta_add` *doesn't* acquire the mutex. That's a potential issue.

If `mt7921_mac_sta_add` doesn't acquire the mutex, then the call to `mt7921_mcu_sta_update` within that function is going to happen *without* the protection of the mutex. That's a red flag. The key question is: is `mt7921_mcu_sta_update` thread-safe? Or does it rely on the mutex being held?

I'll need to go and examine the implementation of `mt7921_mcu_sta_update` to see if it makes assumptions about mutex protection. This needs to be understood.



40/2 2026/06/29 09:06 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/mcu.c",
  "FirstLine": 1047,
  "LineCount": 20
}

Results:
{
  "Contents": "1047:\tint mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta,\n1048:\t\t\t\t  struct ieee80211_vif *vif, bool enable,\n1049:\t\t\t\t  enum mt76_sta_info_state state)\n1050:\t{\n1051:\t\tstruct mt792x_vif *mvif = (struct mt792x_vif *)vif-\u003edrv_priv;\n1052:\t\tint rssi = -ewma_rssi_read(\u0026mvif-\u003ebss_conf.rssi);\n1053:\t\tstruct mt76_sta_cmd_info info = {\n1054:\t\t\t.sta = sta,\n1055:\t\t\t.vif = vif,\n1056:\t\t\t.enable = enable,\n1057:\t\t\t.cmd = MCU_UNI_CMD(STA_REC_UPDATE),\n1058:\t\t\t.state = state,\n1059:\t\t\t.offload_fw = true,\n1060:\t\t\t.rcpi = to_rcpi(rssi),\n1061:\t\t};\n1062:\t\tstruct mt792x_sta *msta;\n1063:\t\n1064:\t\tmsta = sta ? (struct mt792x_sta *)sta-\u003edrv_priv : NULL;\n1065:\t\tinfo.wcid = msta ? \u0026msta-\u003edeflink.wcid : \u0026mvif-\u003esta.deflink.wcid;\n1066:\t\tinfo.newly = msta ? state != MT76_STA_INFO_STATE_ASSOC : true;\n"
}

41/2 2026/06/29 09:06 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 72753
							output: 52
							thoughts: 41
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**Digging into the Function Call Hierarchy**

Alright, that's a bit unexpected. I was just looking at `mt7921_mcu_sta_update`, and now I see that `mt76_connac_mcu_sta_update` is called *within* it? Intriguing. This isn't the most common naming convention, and it suggests a possible layer of abstraction or modularity that I need to understand. My initial instinct is to dig deeper. I want to know why this specific design choice was made. Are they handling different aspects of station updates, perhaps relating to the connac platform? Is there code reuse, or perhaps a specific division of labor for the different MCUs, that's driving this? I need to understand the logic behind this interaction and the rationale for splitting the update process in this particular way. Time to go spelunking in the source code.



42/2 2026/06/29 09:06 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt7921/mcu.c",
  "FirstLine": 1067,
  "LineCount": 20
}

Results:
{
  "Contents": "1067:\t\n1068:\t\treturn mt76_connac_mcu_sta_cmd(\u0026dev-\u003emphy, \u0026info);\n1069:\t}\n1070:\t\n1071:\tint mt7921_mcu_set_beacon_filter(struct mt792x_dev *dev,\n1072:\t\t\t\t\t struct ieee80211_vif *vif,\n1073:\t\t\t\t\t bool enable)\n1074:\t{\n1075:\t#define MT7921_FIF_BIT_CLR\t\tBIT(1)\n1076:\t#define MT7921_FIF_BIT_SET\t\tBIT(0)\n1077:\t\tint err;\n1078:\t\n1079:\t\tif (enable) {\n1080:\t\t\terr = mt7921_mcu_uni_bss_bcnft(dev, vif, true);\n1081:\t\t\tif (err)\n1082:\t\t\t\treturn err;\n1083:\t\n1084:\t\t\terr = mt7921_mcu_set_rxfilter(dev, 0,\n1085:\t\t\t\t\t\t      MT7921_FIF_BIT_SET,\n1086:\t\t\t\t\t\t      MT_WF_RFCR_DROP_OTHER_BEACON);\n"
}

43/2 2026/06/29 09:06 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 73410
							output: 50
							thoughts: 1296
						

Thoughts:
**Analyzing Mutex Usage in the MT7921 Driver**

Okay, so I'm digging into this `mt76_connac_mcu_sta_cmd` function. It seems pretty generic, but I need to figure out if it's thread-safe. My focus is on the mutex usage. First, I'm tracing the call stack from `mt76_connac_mcu_sta_cmd` to the functions it calls, specifically within the MT7921 driver. I'm trying to figure out if the mutex is correctly held when crucial hardware operations are performed.

I see that `mt7921_mac_sta_add` is the key function in the chain, so I want to know if `dev->mutex` is held at that point. I know it's assigned to `sta_add` within `mt76_driver_ops`. That function gets called from `mt76_sta_add`, which in turn, is triggered by `mt76_sta_state`. However, my initial hunch is that `mt76_sta_state` doesn't hold the mutex, because it is called from the mac80211 core and it's unlikely that the mac80211 core manages the device mutex. However, in this case, the `sta_state` callback for `mt7921_ops` is `mt7921_sta_state`. Now, this is interesting. I see that `mt7921_sta_state` *does* acquire and release the mutex, but `mt76_sta_state` will be called *after* this happens. Therefore, `mt7921_mac_sta_add` is called without the mutex.

Now, let's keep going. `mt7921_mac_sta_add` then calls `mt7921_regd_set_6ghz_power_type`, which in turn calls `__mt7921_mcu_regd_update`. Here's where it gets worrying. The lower function `__mt7921_mcu_regd_update` makes an assumption that the mutex is held. This function will call several more functions: `mt7921_mcu_set_clc`, `mt7921_regd_channel_update`, `mt76_connac_mcu_set_channel_domain`, and `mt7921_set_tx_sar_pwr`. I need to figure out if these require the mutex.

It turns out that `__mt7921_mcu_regd_update` itself *used* to acquire the mutex explicitly. Now I understand what's happening. The patch changes `mt7921_regd_set_6ghz_power_type` to call `__mt7921_mcu_regd_update` *directly*, which means the mutex acquisition is being *removed* from the call path! This is a potential race condition and a serious issue. We are accessing hardware without the mutex protection. The patch is probably trying to fix something, but they probably introduced this serious race by removing the mutex.

I'm double-checking the call stack. Since `mt7921_mac_sta_add` doesn't hold the mutex, which means changing to `__mt7921_mcu_regd_update` *removes* the mutex. Let me check the functions to see if any other function holds the mutex. I can see the calls to `mt76_connac_pm_wake` and `mt76_connac_power_save_sched`. These functions don't acquire the mutex. However, I know that `mt76_connac_pm_wake` is often called *with* the mutex held. I'm going to double-check the implementation of `mt76_connac_pm_wake` to confirm this.



44/2 2026/06/29 09:07 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c",
  "FirstLine": 36,
  "LineCount": 25
}

Results:
{
  "Contents": "  36:\tint mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)\n  37:\t{\n  38:\t\tstruct mt76_dev *dev = phy-\u003edev;\n  39:\t\n  40:\t\tif (mt76_is_usb(dev))\n  41:\t\t\treturn 0;\n  42:\t\n  43:\t\tcancel_delayed_work_sync(\u0026pm-\u003eps_work);\n  44:\t\tif (!test_bit(MT76_STATE_PM, \u0026phy-\u003estate))\n  45:\t\t\treturn 0;\n  46:\t\n  47:\t\tif (pm-\u003esuspended)\n  48:\t\t\treturn 0;\n  49:\t\n  50:\t\tqueue_work(dev-\u003ewq, \u0026pm-\u003ewake_work);\n  51:\t\tif (!wait_event_timeout(pm-\u003ewait,\n  52:\t\t\t\t\t!test_bit(MT76_STATE_PM, \u0026phy-\u003estate),\n  53:\t\t\t\t\t3 * HZ)) {\n  54:\t\t\tieee80211_wake_queues(phy-\u003ehw);\n  55:\t\t\treturn -ETIMEDOUT;\n  56:\t\t}\n  57:\t\n  58:\t\treturn 0;\n  59:\t}\n  60:\tEXPORT_SYMBOL_GPL(mt76_connac_pm_wake);\n"
}

45/2 2026/06/29 09:07 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 76002
							output: 50
							thoughts: 455
						

Thoughts:
**Analyzing a Suspected Mutex Issue in the MT7921 Driver**

Okay, so `mt76_connac_pm_wake` is designed to wait for the device to wake up, and it doesn't acquire the mutex itself, which is standard practice. But now I'm seeing something that makes me think there might be a subtle mutex-related issue in this driver. Specifically, I'm questioning why `mt7921_mcu_regd_update` was changed to `__mt7921_mcu_regd_update`. If `mt7921_mac_sta_add` *doesn't* hold the mutex, then why make that change? I'm missing a piece of information and I need to figure out what's going on.

Since I don't have the commit message handy, I will check the patch itself to see if it will clarify the changes:

```c
-	if (vif->bss_conf.chanreq.oper.chan->band == NL80211_BAND_6GHZ)
-		mt7921_mcu_regd_update(dev, dev->mt76.alpha2, dev->country_ie_env);
+	if (vif->bss_conf.chanreq.oper.chan->band == NL80211_BAND_6GHZ)
+		__mt7921_mcu_regd_update(dev, dev->mt76.alpha2, dev->country_ie_env);
```

Okay, so if the original `mt7921_mcu_regd_update` *did* acquire the mutex, and the new version, `__mt7921_mcu_regd_update`, does *not*, this implies the author believed the mutex was already held when this function was called. This makes sense. Where is the mutex already being held? I need to track the calls to `mt7921_regd_set_6ghz_power_type` to understand how the mutex is being managed. It appears that it is called from both `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`.

Now I'm thinking, hold on a second... maybe `mt7921_mac_sta_add` *is* called with the mutex held. I should check `mt76_sta_add` which is in `mac80211.c` and confirm that it is indeed holding the mutex. I need to trace this back to the caller to confirm my hypothesis.



46/2 2026/06/29 09:07 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mac80211.c",
  "FirstLine": 1575,
  "LineCount": 20
}

Results:
{
  "Contents": "1575:\tstatic int\n1576:\tmt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,\n1577:\t\t     struct ieee80211_sta *sta)\n1578:\t{\n1579:\t\tstruct mt76_wcid *wcid = (struct mt76_wcid *)sta-\u003edrv_priv;\n1580:\t\tstruct mt76_dev *dev = phy-\u003edev;\n1581:\t\tstruct mt76_wcid *published;\n1582:\t\tint ret;\n1583:\t\tint i;\n1584:\t\n1585:\t\tmutex_lock(\u0026dev-\u003emutex);\n1586:\t\n1587:\t\tret = dev-\u003edrv-\u003esta_add(dev, vif, sta);\n1588:\t\tif (ret)\n1589:\t\t\tgoto out;\n1590:\t\n1591:\t\tfor (i = 0; i \u003c ARRAY_SIZE(sta-\u003etxq); i++) {\n1592:\t\t\tstruct mt76_txq *mtxq;\n1593:\t\n1594:\t\t\tif (!sta-\u003etxq[i])\n"
}

47/2 2026/06/29 09:07 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 77420
							output: 50
							thoughts: 107
						

Thoughts:
**Analyzing the Station Addition and Removal Processes**

Right, okay, so I've been digging into this and it looks like I've found a key piece. Aha! It's confirmed: the `mt76_sta_add` function *does* indeed acquire `dev->mutex`! I can see it right there in the code: `mutex_lock(&dev->mutex);` This is crucial.

Now, since `mt76_sta_add` locks that mutex, that means the `dev->drv->sta_add` callback, which is `mt7921_mac_sta_add` in this context, is definitely being called with the `dev->mutex` held. Okay, that makes sense of the locking scheme used.

But what about the removal side? We've only confirmed the add, we need to know the same is true for remove. Let me quickly double-check the `mt76_sta_remove` function to be sure. This is an important part of the puzzle.



48/2 2026/06/29 09:07 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mac80211.c",
  "FirstLine": 1614,
  "LineCount": 20
}

Results:
{
  "Contents": "1614:\tout:\n1615:\t\tmutex_unlock(\u0026dev-\u003emutex);\n1616:\t\n1617:\t\treturn ret;\n1618:\t}\n1619:\t\n1620:\tvoid __mt76_sta_remove(struct mt76_phy *phy, struct ieee80211_vif *vif,\n1621:\t\t\t       struct ieee80211_sta *sta)\n1622:\t{\n1623:\t\tstruct mt76_dev *dev = phy-\u003edev;\n1624:\t\tstruct mt76_wcid *wcid = (struct mt76_wcid *)sta-\u003edrv_priv;\n1625:\t\tint i, idx = wcid-\u003eidx;\n1626:\t\n1627:\t\tfor (i = 0; i \u003c ARRAY_SIZE(wcid-\u003eaggr); i++)\n1628:\t\t\tmt76_rx_aggr_stop(dev, wcid, i);\n1629:\t\n1630:\t\tif (dev-\u003edrv-\u003esta_remove)\n1631:\t\t\tdev-\u003edrv-\u003esta_remove(dev, vif, sta);\n1632:\t\n1633:\t\tmt76_wcid_cleanup(dev, wcid);\n"
}

49/2 2026/06/29 09:07 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 78138
							output: 50
							thoughts: 36
						

Thoughts:
Okay, here's my interpretation of that thought process, from an expert's perspective:

**Diving Deep into STA Removal and Locking**

Wait a minute... I'm looking at `__mt76_sta_remove` and something's not sitting quite right. Isn't that function supposed to be responsible for removing a station's entry from the internal structures? And it's calling *without* explicitly acquiring the `dev->mutex` beforehand? That seems potentially unsafe. Race conditions are a nightmare, especially in driver code. We need to maintain strict synchronization, to prevent concurrent modification of shared data structures.

Okay, let's back up and double-check the definition of `mt76_sta_remove` – the *actual* removal function, the one *we* should be interested in - the one that presumably *does* handle the locking. I need to understand the full call graph and ensure the mutex is *always* held when accessing and modifying station-related data. If `__mt76_sta_remove` is meant to be called from inside `mt76_sta_remove`, then the higher level function should be the one to do the locking, with the lower-level function assuming the lock is already there. I'll need to confirm that this is true here. Gotta rule out any potential race conditions involving station entries being added, removed, or modified concurrently with other operations. I need to make sure this code is robust and safe, and that any potential risks are avoided.



50/2 2026/06/29 09:07 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/mediatek/mt76/mac80211.c",
  "FirstLine": 1634,
  "LineCount": 20
}

Results:
{
  "Contents": "1634:\t\n1635:\t\tmt76_wcid_mask_clear(dev-\u003ewcid_mask, idx);\n1636:\t\tphy-\u003enum_sta--;\n1637:\t}\n1638:\tEXPORT_SYMBOL_GPL(__mt76_sta_remove);\n1639:\t\n1640:\tstatic void\n1641:\tmt76_sta_remove(struct mt76_phy *phy, struct ieee80211_vif *vif,\n1642:\t\t\tstruct ieee80211_sta *sta)\n1643:\t{\n1644:\t\tstruct mt76_dev *dev = phy-\u003edev;\n1645:\t\n1646:\t\tmutex_lock(\u0026dev-\u003emutex);\n1647:\t\t__mt76_sta_remove(phy, vif, sta);\n1648:\t\tmutex_unlock(\u0026dev-\u003emutex);\n1649:\t}\n1650:\t\n1651:\tint mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n1652:\t\t\t   struct ieee80211_sta *sta,\n1653:\t\t\t   enum ieee80211_sta_state old_state,\n"
}

51/2 2026/06/29 09:07 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 78898
							output: 274
							thoughts: 1423
						

Thoughts:
**Deadlock Fix in MT7921 Driver**

Okay, so here's the situation: `mt76_sta_remove` *definitely* acquires `dev->mutex`. This means that when `mt7921_mac_sta_add` and `mt7921_mac_sta_remove` are called, `dev->mutex` is already held. The critical part is that `mt7921_mac_sta_add` calls `mt7921_regd_set_6ghz_power_type`, which in turn calls `mt7921_mcu_regd_update`. That function then attempts to acquire the same `dev->mutex` via a nested series of function calls: `mt792x_mutex_acquire`, `mt76_connac_mutex_acquire`, ultimately leading to `mutex_lock(&dev->mutex)`.

A textbook deadlock! `mt7921_mcu_regd_update` tries to grab a mutex it already owns! The patch elegantly fixes this by calling `__mt7921_mcu_regd_update` directly, which bypasses the mutex acquisition.

This is a functional change that resolves a deadlock. The good news is, this bug is reachable in virtualized environments because the MT7921 has a USB driver (`mt7921u`), which can be fuzzed using tools like `dummy_hcd` or `raw-gadget`. The essential config to enable here is `MT7921U`.

The key symbols to focus on are:
*   `__mt7921_mcu_regd_update`
*   `mt7921_mcu_regd_update`
*   `mt7921_regd_set_6ghz_power_type`

Let me check for other required configs: `MT7921U` depends on `MAC80211` and `USB`. `MT7921_COMMON` is also selected by `MT7921U`. Therefore, `MT7921U` alone is sufficient.

Let's quickly check: there are also `MT7921E` (PCIe) and `MT7921S` (SDIO), and syzkaller can fuzz USB and PCI (though USB is more common). For completeness, we should list both `MT7921U` and `MT7921E`.

Let's check `MT7921E` dependencies: `MT7921E` depends on `MAC80211` and `PCI`. However, we can focus on `MT7921U` given we are reporting a deadlock.

Now, wait...is `MT7921_COMMON` a config? Yes, but it's a `tristate` without a prompt, so it's *selected* by `MT7921U`. So, to be clear, `MT7921U` is what we should focus on.

Recapping the focus symbols:
*   `__mt7921_mcu_regd_update`
*   `mt7921_mcu_regd_update`
*   `mt7921_regd_set_6ghz_power_type`

Are any other functions modified? No, these three are the only ones.

Okay, let's verify reachability of `mt7921_regd_set_6ghz_power_type` via mac80211 operations. Yep. When a station is added or removed, mac80211 calls `sta_add` or `sta_remove`, which calls `mt76_sta_add` or `mt76_sta_remove`, which calls `mt7921_mac_sta_add` or `mt7921_mac_sta_remove`, which calls `mt7921_regd_set_6ghz_power_type`. This *is* definitely reachable.

Here's the reasoning: The patch fixes a deadlock in the MT7921 wireless driver. `mt7921_regd_set_6ghz_power_type` is called from `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`, which are invoked by mac80211 with `dev->mutex` already held. Previously, it called `mt7921_mcu_regd_update`, which attempted to acquire the same


52/2 2026/06/29 09:08 tool set-results
0m Args:
{
  "EnableConfigs": [
    "MT7921U"
  ],
  "FocusSymbols": [
    "__mt7921_mcu_regd_update",
    "mt7921_mcu_regd_update",
    "mt7921_regd_set_6ghz_power_type"
  ],
  "Reasoning": "The patch fixes a deadlock in the MT7921 wireless driver. `mt7921_regd_set_6ghz_power_type` is called from `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`, which are invoked by mac80211 with the `dev-\u003emutex` already held. Previously, it called `mt7921_mcu_regd_update`, which attempted to acquire the same mutex, leading to a deadlock. The patch introduces `__mt7921_mcu_regd_update` to be called when the mutex is already held. This is a functional fix for a deadlock in reachable driver code. The driver can be reached in virtualized environments via the USB interface (`CONFIG_MT7921U`).",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "MT7921U"
  ],
  "FocusSymbols": [
    "__mt7921_mcu_regd_update",
    "mt7921_mcu_regd_update",
    "mt7921_regd_set_6ghz_power_type"
  ],
  "Reasoning": "The patch fixes a deadlock in the MT7921 wireless driver. `mt7921_regd_set_6ghz_power_type` is called from `mt7921_mac_sta_add` and `mt7921_mac_sta_remove`, which are invoked by mac80211 with the `dev-\u003emutex` already held. Previously, it called `mt7921_mcu_regd_update`, which attempted to acquire the same mutex, leading to a deadlock. The patch introduces `__mt7921_mcu_regd_update` to be called when the mutex is already held. This is a functional fix for a deadlock in reachable driver code. The driver can be reached in virtualized environments via the USB interface (`CONFIG_MT7921U`).",
  "WorthFuzzing": true
}

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