From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f182.google.com (mail-dy1-f182.google.com [74.125.82.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F400036C5B3 for ; Tue, 20 Jan 2026 06:28:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890540; cv=none; b=ZPG1s3lTa2k5DcNkKtAhnuXm4XVTYB0MXUV9ZMUo8WsB79Zpf7tCWCzzuEKlrcCJU4cK1vhELuBRMWL4f+dxScmgH07KvzMQ1Q8UFMkOKAjQRh+3jIIi1T/QXwuE0MRL6UdiPsjHvp/isBPKcqX9yWyqtP2CJnF8lcRaKJ3qOCM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890540; c=relaxed/simple; bh=2+HHCsL4CHpvAxtcpZ+oNfJ91XAAY5ApArx/L+V3+Ww=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WxDLTDKyGC15Cfe15wM4hK+0e5Gp3EWnICGMsrYhhQ/WvY7WPYqAUhcgz5FZrK/JgPpD6LSr7d2ZYvVA9yKhBoh7EWBsAil2RXJT+mcl4LNYdnegO2YgOfmm+PslElG6wKmi/Ku7u7BAXPiFpD5jhEIBBwNC+5241f5yy9rbs0o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KfBVCy6B; arc=none smtp.client-ip=74.125.82.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KfBVCy6B" Received: by mail-dy1-f182.google.com with SMTP id 5a478bee46e88-2b6bf6adc65so4982769eec.0 for ; Mon, 19 Jan 2026 22:28:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890538; x=1769495338; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=hZqhvQUqHyPjd5YwFiryR+es7m9UdWSAqM9hdcVMAYY=; b=KfBVCy6Btat3on8k4RWjWohTf/kL/A3GiZd/jR1dWPTZ7i8oymlmP7SNvzFIyhz0XK 8nA5MBTVR2ZmcixOvOKqha7hwOgVfpEE4xClNZ9FbNCVyLLP1aa5qOCRci/93z/xAJ7y gGlVLb1IqjLb5qLobEpBugeiuNlaRdhzhF6g8sf8BY8uIZ7EuHNjUJsaWkjYu/EZCp7b ip0bDp+gWeLFxjsiP/2+eaSJkuHG8NRqay56tqxJeJ6D24Zf8zmryBhuoUKZjByAH3Hd zxBSCdt4hcC3HfQkao6ggL4hhq4z1UHu3RdOUQ5VVwsO6Wfat6XaFhuwUCErshY199Q/ x32g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890538; x=1769495338; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hZqhvQUqHyPjd5YwFiryR+es7m9UdWSAqM9hdcVMAYY=; b=NYsZZKlKwYAVM+zFAHb9mWMR7khjb9mXqCQs2vt4yf9gykDKN0wJXhNFrJLiJ2FImb B8AzDxqrCkh75xqfnSoI4zvytQiFLxQzkGKHuv0VjRf7s/8t2VrjZP6BOxOMz1wlgMUi fgCFUmn6UhnczLDGcuW7pquKvqkE6Ta7QoRnNtUIrLN8TpZpNHTb7KiJwe9WEHB20VRj qZA7MiLg2nmziPhkBrO1q9SjD7bJz6hs/RZ1QHD5risGNJ9Zb04QCOmVqzDazZv7Moj3 1PnPajYF1nPA8a+eiRDGHDbJW4hvoq7ARp58UzYUBEgJF++A+7mA76mhbt5qmloqD13W ts4g== X-Forwarded-Encrypted: i=1; AJvYcCXteWqmmTuRni8KMS4fHSvZaGnqBczCU6mrTzq7x7qbmk1oM4qcUXRvsu0eQfRwsKPsmGKx7AlrIfL2R4k=@vger.kernel.org X-Gm-Message-State: AOJu0YyqUlGG2MS2yNZuV0n7MINcjgcIlpsi9ZjTBhhfXwWL/UstFlTa el/FrN0+ICh/tzksTmnQndNyPiwQxhuhHSQw8k08ivlgOOdYVu410Pi3 X-Gm-Gg: AZuq6aIqC/ydhNkNQby0l0EOZCn9MUErlyZMLcd+W4l3tDGaPs20Izz0ODDbHeSd97I 8pSix9u7+sPZ32vSL2f65rhxy7LS2wFFwI0H0OfbiFcGVcA90IICG2+FmEk+s2nDmYPF+6XmhKm L5WvSLi4UlgEDoZ6PqIfnxNYizIAlsDEMlOo+fFJWTwtTz59hchug+OPPZhGc/wp9nIFelCfXQh x/f9+t21EaP5HsEln29x6H5NbACEnoKsSJW/ZMYvofinu8vM7an5AXraiF53aYggzjSLNcskL6U x/F6bPTKG5yT/nAy4sJgDBiNtMbJ6KNxYLhqBt4VZFqZGNsm0elgXauU9Ex4QOg4u6QFo3J2EkL IP4lmpW+KS3lG+MXvdkD7ZMRbbUdlgaevR/EjIveceI/sdecV3+leZ4IG7lZJEG9XDarbAnUHlU +S19R1ferNbgVrrVMIww1asyHTMeLYegxeM2wvPCwprflW4oV6NK/gxzD3uw1HEXont20EW/g= X-Received: by 2002:a05:7300:6420:b0:2ac:1c5a:9950 with SMTP id 5a478bee46e88-2b6b4e98df3mr12535391eec.34.1768890538000; Mon, 19 Jan 2026 22:28:58 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.28.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:28:57 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 01/11] wifi: mt76: fix list corruption in mt76_wcid_cleanup Date: Mon, 19 Jan 2026 22:28:44 -0800 Message-ID: <20260120062854.126501-2-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling mt76_wcid_cleanup() was not removing wcid entries from sta_poll_list before mt76_reset_device() reinitializes the master list. This leaves stale pointers in wcid->poll_list, causing list corruption when mt76_wcid_add_poll() later checks list_empty() and tries to add the entry back. The fix adds proper cleanup of poll_list in mt76_wcid_cleanup(), matching how tx_list is already handled. This is similar to what mt7996_mac_sta_deinit_link() already does correctly. Fixes list corruption warnings like: list_add corruption. prev->next should be next (ffffffff...) Signed-off-by: Zac Bowling --- drivers/net/wireless/mediatek/mt76/mac80211.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wi= reless/mediatek/mt76/mac80211.c index 75772979f438..d0c522909e98 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1716,6 +1716,16 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct = mt76_wcid *wcid) =20 idr_destroy(&wcid->pktid); =20 + /* Remove from sta_poll_list to prevent list corruption after reset. + * Without this, mt76_reset_device() reinitializes sta_poll_list but + * leaves wcid->poll_list with stale pointers, causing list corruption + * when mt76_wcid_add_poll() checks list_empty(). + */ + spin_lock_bh(&dev->sta_poll_lock); + if (!list_empty(&wcid->poll_list)) + list_del_init(&wcid->poll_list); + spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&phy->tx_lock); =20 if (!list_empty(&wcid->tx_list)) --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEE2C374185 for ; Tue, 20 Jan 2026 06:29:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890543; cv=none; b=Gb/xcCD/iCS41Y8j/Ccv+OUfK2l72Wj+8gdzpwZ6ifRN8KI/PJfVqafGR3HVe7pgM81VR2yNIN+7UisqN0T1xm+Q82/u/3WyRrzAKN5tFcsa2sW1oo4NjjtjZ22g9XuuknmqY+0TzqEsk0GN+y5Jp2wXAu0zrEQW1JP0RKb5crY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890543; c=relaxed/simple; bh=U3Nyq3NqiqDHDQqkseFznMKgRIxsJy24U5IKOEvZynU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y+67Is6M0OZ1bCRyYAL3zKcl5tPH3mp4jAlZgBBoFIRfLkQWGN0VNiBJUCRu+vhfAT9qcFuyg9t8EwFRTMQaJV9WwRRN9PxiExx2xemBeb1qyURzBczlAJD7BV/9D15UJ42J6+kETqkVmgBpm4t6c/y80S8/olouDv/K4KSZVcs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hjxv9Uac; arc=none smtp.client-ip=74.125.82.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hjxv9Uac" Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-2b0ea1edf11so9056365eec.0 for ; Mon, 19 Jan 2026 22:29:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890540; x=1769495340; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=QR+w7fOhhpyJjkq0X/V8TVo4iOOXXnMSK4qWX/dQNIE=; b=hjxv9UacipiMzOCPp4LF1+mn+BQyU+EDAC+RQaNB/xGuqe13Y78ZEkm9H8/cPUzK8D aYO5/FWmOqOjXLon0gpabv5CN4pAFPQZHAClgkOW7ZFXV7fscx/phS0rgtRzgdyu0IlI B95qyZYzy11v9zN0SdgdRaQYsMZj7XDjaTWshh/96B2CzZ6umNdDXoM6C30VUg9YldiE Zc+/10Q0mzCpzLzUX34XlMtbAIXMY9ktnzw0V5msh5GdagvQnSXy9+77U13PFt3iRj+g EV5i25L/HMNG5ex+k4xPvLHUiZ9lD+HUvnTO4g6/1dOg9djnJsYz8n8qk6dV1oj6DsSJ sEOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890540; x=1769495340; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QR+w7fOhhpyJjkq0X/V8TVo4iOOXXnMSK4qWX/dQNIE=; b=Tt0hAl1wki0cuooXW7wv7P9H7aGK+I8QULOL1pldXybNDK6JSVr4KbgXp6sCLUiyBR zUHMlr+WRfRyw48vj6y+qyBIVm97yDWpVV7c8l3FP50IgrH8iQedxaofIBICqHrxHHFe DPeWEFKrEavA4+pQwSYdUYsARBvcIDoNuMR5ex0N0MboO1JuVSbqWm9ivWl6i3s5taxV NP8HG3ys8n0ho4g8AgL5vHSr+b8U2/5ldf3j4OjNpy3Yo2jof8kMf8aZPhJ63mT/z1pv WY6NCAWqJv8NIFKHOD28AcNxNWaTBRtWs+v4SLgntC6eFdTZaVuzqRJgtzDnvT5gUWWw vo1A== X-Forwarded-Encrypted: i=1; AJvYcCWudSO/UMajSTyye4+iP+wQN2aIz3sbFnHmBrf7Y2df1C2wyLCsgQRgUCCPeDvtaXNU7cjOW5WP4W/TjdA=@vger.kernel.org X-Gm-Message-State: AOJu0YxUvR2cmPh6uxTn8RdlQGq2L8b4/c/+xLj4wH8Urb0nt1Qng8ap 8qSTZzSrFDcNIKqaYiZYsLN+x9/855FlmxWdKB52uE3ahfvgVthTFeVT X-Gm-Gg: AZuq6aJhn0ZILLlBbtKPTMOTqAFtHlbIwlOhuBrCIaqaEE/XiyuRn5vdHs5sjJ+/fRR cv/YK8ic/2QHNwxCUx4DgSxBPLYBtvN6H2DxQEIrusPwSFB7xLyKAU0a0oD+L55MNXxvOE0LIuD FpaXOBQPNw1UohcAtGGiGWXAiCZpPOIJjXixEZEiq9iztizInO6TNGv580w27Sysl/UUytcs5sp QxunljPfcJYwzZw/Xszo4L544YLzEurQsrPoqqmEaK37P0uhoqUKRIkJkctMH5KetPqcRvIwsd0 jEO1UYZkN9NJDa8sjxJh3sKfUf61ddzUHQcTxxwqrLosFqpBeov0+gQuLacMsotWfhKcKXufxCR WLVxEFkIPdPC/lqAcWkRrGoGREGyA9gT4dgzAKYDtScUS6ZXrcfp/lCuy/YgxKtdQycVSISr8RN Bwvz1CiPeLu3J3hEdAhaK/228oBMHLEc1HgYiH7V+odUJ1SBUVk4CKVwTJVt7K X-Received: by 2002:a05:7300:e825:b0:2ab:f56e:bea6 with SMTP id 5a478bee46e88-2b6b505d137mr10313793eec.39.1768890539343; Mon, 19 Jan 2026 22:28:59 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.28.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:28:58 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 02/11] wifi: mt76: mt792x: fix NULL pointer and firmware reload issues Date: Mon, 19 Jan 2026 22:28:45 -0800 Message-ID: <20260120062854.126501-3-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling This patch combines two fixes for the shared mt792x code used by both MT7921 and MT7925 drivers: 1. Fix NULL pointer dereference in TX path: Add NULL pointer checks in mt792x_tx() to prevent kernel crashes when transmitting packets during MLO link removal. The function calls mt792x_sta_to_link() which can return NULL if the link is being removed, but the return value was dereferenced without checking. Similarly, the RCU-protected link_conf and link_sta pointers were used without NULL validation. This race can occur when: - A packet is queued for transmission - Concurrently, the link is being removed (mt7925_mac_link_sta_remove) - mt792x_sta_to_link() returns NULL for the removed link - Kernel crashes on wcid =3D &mlink->wcid dereference Fix by checking mlink, conf, and link_sta before use, freeing the SKB and returning early if any pointer is NULL. 2. Fix firmware reload failure after previous load crash: If the firmware loading process crashes or is interrupted after acquiring the patch semaphore but before releasing it, subsequent firmware load attempts will fail with 'Failed to get patch semaphore'. Apply the same fix from MT7915 (commit 79dd14f): release the patch semaphore before starting firmware load and restart MCU firmware to ensure clean state. Fixes: c74df1c067f2 ("wifi: mt76: mt792x: introduce mt792x-lib module") Fixes: 583204ae70f9 ("wifi: mt76: mt792x: move mt7921_load_firmware in mt79= 2x-lib module") Link: https://github.com/openwrt/mt76/commit/79dd14f2e8161b656341b665326177= 9199aedbe4 Signed-off-by: Zac Bowling --- .../net/wireless/mediatek/mt76/mt792x_core.c | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net= /wireless/mediatek/mt76/mt792x_core.c index f2ed16feb6c1..05598202b488 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c @@ -95,6 +95,8 @@ void mt792x_tx(struct ieee80211_hw *hw, struct ieee80211_= tx_control *control, IEEE80211_TX_CTRL_MLO_LINK); sta =3D (struct mt792x_sta *)control->sta->drv_priv; mlink =3D mt792x_sta_to_link(sta, link_id); + if (!mlink) + goto free_skb; wcid =3D &mlink->wcid; } =20 @@ -113,9 +115,12 @@ void mt792x_tx(struct ieee80211_hw *hw, struct ieee802= 11_tx_control *control, link_id =3D wcid->link_id; rcu_read_lock(); conf =3D rcu_dereference(vif->link_conf[link_id]); - memcpy(hdr->addr2, conf->addr, ETH_ALEN); - link_sta =3D rcu_dereference(control->sta->link[link_id]); + if (!conf || !link_sta) { + rcu_read_unlock(); + goto free_skb; + } + memcpy(hdr->addr2, conf->addr, ETH_ALEN); memcpy(hdr->addr1, link_sta->addr, ETH_ALEN); =20 if (vif->type =3D=3D NL80211_IFTYPE_STATION) @@ -136,6 +141,10 @@ void mt792x_tx(struct ieee80211_hw *hw, struct ieee802= 11_tx_control *control, } =20 mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb); + return; + +free_skb: + ieee80211_free_txskb(hw, skb); } EXPORT_SYMBOL_GPL(mt792x_tx); =20 @@ -927,6 +936,20 @@ int mt792x_load_firmware(struct mt792x_dev *dev) { int ret; =20 + /* Release semaphore if taken by previous failed load attempt. + * This prevents "Failed to get patch semaphore" errors when + * recovering from firmware crashes or suspend/resume failures. + */ + ret =3D mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false); + if (ret < 0) + dev_dbg(dev->mt76.dev, "Semaphore release returned %d (may be expected)\= n", ret); + + /* Always restart MCU to ensure clean state before loading firmware */ + mt76_connac_mcu_restart(&dev->mt76); + + /* Wait for MCU to be ready after restart */ + msleep(100); + ret =3D mt76_connac2_load_patch(&dev->mt76, mt792x_patch_name(dev)); if (ret) return ret; --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f170.google.com (mail-dy1-f170.google.com [74.125.82.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4770376BC1 for ; Tue, 20 Jan 2026 06:29:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890544; cv=none; b=nIkv/lKNbr3G2MXyGDkWyURvQSLTMJDmtY75DT99ea7zlEW0LJD5xVWCmrxdSvo4MSxrhWaZDUw7QBamQN7U1KySn1MPFvyZ77qy46jcryBj5IiZT4vNWp65mjiPzLU9q+gKlm1jA9KSDhWRpcqwi+h9iWzDnov7pkiGuBthO1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890544; c=relaxed/simple; bh=+j1glTN1s7e1zsffxY9Njim+inPXTcqaomOdVXpZvQE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=C+PsmN1TTv78Rlr/Wnu14rYdOBUiaC2I7/tykdxCcnnIArgU8oe1bckgk2SfotALoiD8+K6QFpouYbZy32N0kdAtSwKjAzxWvT5p+95Lj0enRFUx6EREgvXDgWc+k0uSu4U7B0e2kFvhS2FdcRD3yrJ4Tw3adCK9Xz81zxqYqp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Fb1JE9O7; arc=none smtp.client-ip=74.125.82.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Fb1JE9O7" Received: by mail-dy1-f170.google.com with SMTP id 5a478bee46e88-2ae38f81be1so5614156eec.0 for ; Mon, 19 Jan 2026 22:29:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890541; x=1769495341; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=HSaHJrj/+nVdwpmK2iA7Md9bL4shBev7TU9wO57zhqs=; b=Fb1JE9O7QoJOj8dS4IrfZQa2cyS3FxfAyqkGHAzPsL8xDtynVkzAml+t8Ol+VK45A1 HVV9rkMtRiaQn53wUf8nKJC7fU/SiJmRAZoqgWBl7Ba6nxq2gCx34IzF5QUF07xtHZQb 4kdMIF70pPchT5kwYexv/Q1AHtgm+GXoABScsMXZqCXYfE9dvPkagwqpvRvY9GDBlqak NBHXz9aLf1sKPLgBFr/t9pgGDjcL/nTQA8XbxubBYGwRFVQeX/2Clr9mNGhpzsg3LGL2 jv7IAdolvsusQw8N/M/jDEA2aBO6RXciawyoVuZphWDtDEESXTHy7Vr/sLZenvrvjmBU Yf4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890541; x=1769495341; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HSaHJrj/+nVdwpmK2iA7Md9bL4shBev7TU9wO57zhqs=; b=G5r/B7dgO1xkAVXYt6LqnhEnCvcGd5hWlBtZxLxGAEJp+Zfww5XhtJFWhkTW3vK+58 1Ab+yRyIfV+Fu4lF2K9dy3S/1k0wpmHC+PJlaNvfQh7dYEEiGPHlFIo3jbs8OhOMTyIY Jg6ZFcz14WsnL5pkqVbKa7PmSVEvbJ6geTe0KBFY49DMLENVNtpo9x4TPdsSBgbRSq9w 8WZMRxnMjKIR3mTCB8LTEOxAxooY7oFMDstXKTxsBEGz0697iielineRJcanFRoyNUwK w+/yAmJHtK0K0aC7ZTX6b9cgRdTocuqTDmEcUNiP8jWnocBR4nrRDQYw2iHrDQQGWAKH 3aHw== X-Forwarded-Encrypted: i=1; AJvYcCUa2AGZGMxI4NOHOPwA7RxQMPhVKMUvTjW/cZG4MXDSkYichYFKrS0qTtFobLkehQvoA5JmBgq6fH9Sgbg=@vger.kernel.org X-Gm-Message-State: AOJu0Yzs6vTDTZ69fz+ci8c/f/WhK4Pw6FQ4VRntbbo4iS7er3nAaBHb j4+tf0JaWMKjlrnhOXLFuKe0xgGbIP6ZzbFhZQyqR3vgvZEh57Tcr9gX X-Gm-Gg: AZuq6aJO0s1bDeB1OEjtilJZP0ilMJMgd+2HjUUGtAsy58AmidymZM4+CFuKoEMMMlf RbVVetOilC0rmeaZYv2LHBLmShAtWuy85mlo6UkxJc7MtMuhgEkSSum03aDWRrLX03Dd5CpT0ZR wRWHNtcv/G0str4ogYSy+3N9b1WcRlzkOpSZa9DHXO/vlM7gIphFvDtds2BkkbGhLI7VUQZ0uWd N4kJ2SZomqlifymg47Gg3XM3gMIu+6hPjt1YQ6l1CddRKH/bJKoAOzVHvj/5ofkJzLl8wbdqjCo 5rvk+8SN5+E5TR9Az+jVWBebnIb0+ybVldDRH0PBNuahMtajIO9uEPyBB6i++agPOrdw4McCcg2 /v7TlUKubVJbuOsBglLnO5YLAntQRXznyqD2VbH4C0SbQ64dpUByC4/uASc2L7HUv3fC4ZO8Per GahKiuo5wy5fEWDMeSNdLOcyVRhuukuqO0rjKN+k6RMNZsH4mEQrUH4QQMnz3e X-Received: by 2002:a05:7301:1124:b0:2ae:56dc:eb21 with SMTP id 5a478bee46e88-2b6b4e8b378mr8266159eec.23.1768890540838; Mon, 19 Jan 2026 22:29:00 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.28.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:00 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 03/11] wifi: mt76: mt7921: add mutex protection in critical paths Date: Mon, 19 Jan 2026 22:28:46 -0800 Message-ID: <20260120062854.126501-4-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Add proper mutex protection for mt7921 driver operations that access hardware state without proper synchronization. This fixes multiple race conditions that can cause system instability. Fixes added: 1. mac.c: mt7921_mac_reset_work() - Wrap ieee80211_iterate_active_interfaces() with mt792x_mutex - The vif_connect_iter callback accesses hw_encap state 2. main.c: mt7921_remain_on_channel() - Remove mt792x_mutex_acquire/release around mt7925_set_channel_state() - The function is already called with mutex held from mac80211 - This was causing double-lock deadlock 3. main.c: mt7921_cancel_remain_on_channel() - Remove mt792x_mutex_acquire/release - Function is called from mac80211 with mutex already held 4. pci.c: mt7921_pci_pm_complete() - Remove mt792x_mutex_acquire/release around ieee80211_iterate_active_in= terfaces - This was causing deadlock as the vif connect iteration tries to acquire the mutex again 5. usb.c: mt7921_usb_pm_complete() - Same fix as pci.c for USB driver path These changes prevent both missing mutex protection and mutex deadlocks in the mt7921 driver. Fixes: 5c14a5f944b9 ("wifi: mt76: mt7921: introduce remain_on_channel suppo= rt") Signed-off-by: Zac Bowling --- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 2 ++ drivers/net/wireless/mediatek/mt76/mt7921/main.c | 8 ++++++++ drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 2 ++ drivers/net/wireless/mediatek/mt76/mt7921/sdio.c | 2 ++ 4 files changed, 14 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/= wireless/mediatek/mt76/mt7921/mac.c index 03b4960db73f..f5c882e45bbe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -693,9 +693,11 @@ void mt7921_mac_reset_work(struct work_struct *work) clear_bit(MT76_RESET, &dev->mphy.state); pm->suspended =3D false; ieee80211_wake_queues(hw); + mt792x_mutex_acquire(dev); ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7921_vif_connect_iter, NULL); + mt792x_mutex_release(dev); mt76_connac_power_save_sched(&dev->mt76.phy, pm); } =20 diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net= /wireless/mediatek/mt76/mt7921/main.c index 5fae9a6e273c..9315dbdf8880 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -373,6 +373,11 @@ void mt7921_roc_abort_sync(struct mt792x_dev *dev) =20 timer_delete_sync(&phy->roc_timer); cancel_work_sync(&phy->roc_work); + /* Note: caller must hold mutex if ieee80211_iterate_interfaces is + * needed for ROC cleanup. Some call sites (like mt7921_mac_sta_remove) + * already hold the mutex via mt76_sta_remove(). For suspend paths, + * the mutex should be acquired before calling this function. + */ if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) ieee80211_iterate_interfaces(mt76_hw(dev), IEEE80211_IFACE_ITER_RESUME_ALL, @@ -619,6 +624,7 @@ void mt7921_set_runtime_pm(struct mt792x_dev *dev) bool monitor =3D !!(hw->conf.flags & IEEE80211_CONF_MONITOR); =20 pm->enable =3D pm->enable_user && !monitor; + /* Note: caller (debugfs) must hold mutex before calling this function */ ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7921_pm_interface_iter, dev); @@ -765,9 +771,11 @@ mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *= vif, bool is_add) struct mt792x_dev *dev =3D phy->dev; u32 valid_vif_num =3D 0; =20 + mt792x_mutex_acquire(dev); ieee80211_iterate_active_interfaces(mt76_hw(dev), IEEE80211_IFACE_ITER_RESUME_ALL, mt7921_calc_vif_num, &valid_vif_num); + mt792x_mutex_release(dev); =20 if (valid_vif_num > 1) { phy->power_type =3D MT_AP_DEFAULT; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/= wireless/mediatek/mt76/mt7921/pci.c index ec9686183251..9f76b334b93d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -426,7 +426,9 @@ static int mt7921_pci_suspend(struct device *device) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); =20 + mt792x_mutex_acquire(dev); mt7921_roc_abort_sync(dev); + mt792x_mutex_release(dev); =20 err =3D mt792x_mcu_drv_pmctrl(dev); if (err < 0) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net= /wireless/mediatek/mt76/mt7921/sdio.c index 3421e53dc948..92ea2811816f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -219,7 +219,9 @@ static int mt7921s_suspend(struct device *__dev) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); =20 + mt792x_mutex_acquire(dev); mt7921_roc_abort_sync(dev); + mt792x_mutex_release(dev); =20 err =3D mt792x_mcu_drv_pmctrl(dev); if (err < 0) --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f177.google.com (mail-dy1-f177.google.com [74.125.82.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7685F36CDF4 for ; Tue, 20 Jan 2026 06:29:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890545; cv=none; b=FU7GZetapB5vdgOhxwDPH6kkOagcCGs7dSf0nn9zutzegaCKm9TJKbvt/TuQmL7hZoL4JVqnFcL0/wMQ9+cSK87VepM8rPTHFG7aZNP2mxuhEBtfWbPgdIbfJrB4+bUrTAgkSNU4siaYAcPKDaMNpR5R+mxCLdB+BeOTSX9JU9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890545; c=relaxed/simple; bh=opbV4IdcTAjTugROH0USOiae0jYpBQAjBUnIclDTNyE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TK8QLXxK18XewcxsJrhgzVT05o9GtAqR8vL4ITy1CNz5rzzB7TSKVXfBVkXMjrIZqKA386Ukxv9nmSpNu6DG2hpgP7rQARhPuwAPOZD7vpuBgPc9xB0MOoQ6yffDF/wW42JtHsOONgO4D8GFKjb80mA0bHsxCnyaGja4gI0LvYI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PQQWr79p; arc=none smtp.client-ip=74.125.82.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PQQWr79p" Received: by mail-dy1-f177.google.com with SMTP id 5a478bee46e88-2b04fcfc0daso5984515eec.0 for ; Mon, 19 Jan 2026 22:29:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890542; x=1769495342; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=oLLa5fZdpzWHQDj1zzbC4zgrpjcPTG+wEA6kFtMuqxE=; b=PQQWr79pBmxcy1Qz6W84HEYSMmMT0+IUwcyFKyjmqUdbsCer+DedcO5Je/CPUlyuGV 9PwWpL++JYXHFsevjlYWMC7QK5xjwlXdnIhOiLqk0yie4bC/BthBnBVe3kR3DvW54FTP aDyGgL2sJgo/mdcJ9/uuGTJA0ruccCQyWyDDQK8sGlXoPKYdzL9Egk2by2PlOEMLnpwd dnsQUOqW5RS2J0Mo3rwa9DhdbBTMDROmyUFgtRKxcf0BzLrFjtoC4e3HUy+cDLpBV09c BtdpCDe0ekzCdWlsMpDVv6dBdMLeP9bxmoPX6YPxepgPk9pVch5JOiiYPUdiywR4JSC7 OlNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890542; x=1769495342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=oLLa5fZdpzWHQDj1zzbC4zgrpjcPTG+wEA6kFtMuqxE=; b=eLk6tHbMHVQ+2UUKRAl1y6MPNqv5bum3+fMUGLYxieX5RSt4LFgrA3r2/n0l7G8m8/ z7fFexh/UIg0MWs5QJpDls6RIRxsnkSE+3BdNcvHW5tqdoywXQPJAO+YcXzdCwm3m/Xb UeG87f/RYZlRJ+CCYsaiVrEw4N61g0jgw1xCCBub531eUzZjnEPlVseqm8mqA/djTYWa Myjac2dcfajfbQnd9576pR7g1Hu0OFI2/dERVSFGCJPgnaOGdmSpRNTzx1QrrgiL0r2t evVqAbKboOCecoj5X84yyAZUfGN3xbhiIS7N9pr5loExrctVnmNk01u7xgtvQCGjhdDL C4ug== X-Forwarded-Encrypted: i=1; AJvYcCWx/JTWaLbZWeBotnslUbLpxHkWYqAv50z+cTaoeAAEJlJv7Nts9nMLRKMzg+4Qcr7F7KH+oNjBAk6xjjg=@vger.kernel.org X-Gm-Message-State: AOJu0Yx39JzAeg9ZPURM9RwVJ2HLXY9BCVWjvNnTWkqu/y+2gA+VGF1Z Qo8+B3NOv4wgIX6C/5K//2W1aBid2R/xn930W7+KHJ1MbqbdB7uV8SR7 X-Gm-Gg: AZuq6aL2eg6AWM+SPp/bn3yZ+1JrWImBfHnV3lwu4XXyKx2DkfmCOQJFkqBzDS2X8Nf D8RANZiLCV9p55wPCMj2W1JBqMyEZuPTk9sDSstngFQyO44YyPtvjZrs8UIopY0cS/3q4+yz0Oo FfWeHTk71VWFljBOrKHxrKGrgHtkDXyMFoTH00oAAKZQDZzpxQvFkgNjJmCo/ayRg9sa3+lL5qM KoSR9jvF7/x7JD1QN6AwrqYlexfBygeOSvRQcWt14FapPb4D0UnXvNAAM43yLSsv8uPIBN5mKBb 9au9JDsVGkvkTcXz7hKGoiIwPzF5Or6JVrlxmt1x4crtRP3S3vV6qlTMsGGcAtDk9JsPc5amV8u WTJlWa7vxkudV0NIAoD3Oiw+xrZ8tHoqw3KE50snhNEGIgBSIBoUJkPNDOf8aWJn/TVEPp9OYdt s9FKp5SXH3wLvGsRjde9r4MYg8pbcp0dAYYJkEyT7tXOlNdDaDXEAIXdhxSgl2 X-Received: by 2002:a05:7301:5f85:b0:2ae:5af4:7d65 with SMTP id 5a478bee46e88-2b6b410b608mr10898547eec.31.1768890542196; Mon, 19 Jan 2026 22:29:02 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:01 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 04/11] wifi: mt76: mt7921: fix deadlock in sta removal and suspend ROC abort Date: Mon, 19 Jan 2026 22:28:47 -0800 Message-ID: <20260120062854.126501-5-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Zac Bowling Fix deadlock scenarios in mt7921 ROC (Remain On Channel) abort paths: 1. Suspend path deadlock (pci.c, sdio.c): - Previous fix (b74d48c46f) added mutex around mt7921_roc_abort_sync - But roc_work acquires mutex, so cancel_work_sync can deadlock - Fix: Remove mutex wrappers since mt7921_roc_abort_sync doesn't actually need them (it only calls timer_delete_sync, cancel_work_sync, and ieee80211_iterate_interfaces which handles its own locking) 2. sta_remove path deadlock: - mt7921_mac_sta_remove is called from mt76_sta_remove which holds mutex - Calling mt7921_roc_abort_sync =E2=86=92 cancel_work_sync can deadlock = if roc_work is waiting for the mutex - Fix: Add mt7921_roc_abort_async (matching mt7925 pattern) that sets abort flag and schedules work instead of blocking - Add abort flag checking in mt7921_roc_work to handle async abort The fix mirrors the mt7925 implementation which already handles these scenarios correctly. Fixes: b74d48c46f ("wifi: mt76: mt7921: fix mutex handling in multiple path= s") Signed-off-by: Zac Bowling --- .../net/wireless/mediatek/mt76/mt7921/main.c | 29 +++++++++++++++---- .../net/wireless/mediatek/mt76/mt7921/pci.c | 2 -- .../net/wireless/mediatek/mt76/mt7921/sdio.c | 2 -- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net= /wireless/mediatek/mt76/mt7921/main.c index 9315dbdf8880..07d1d0d497f1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -367,17 +367,24 @@ static void mt7921_roc_iter(void *priv, u8 *mac, mt7921_mcu_abort_roc(phy, mvif, phy->roc_token_id); } =20 +/* Async ROC abort - safe to call while holding mutex. + * Sets abort flag and schedules roc_work for cleanup. + */ +static void mt7921_roc_abort_async(struct mt792x_dev *dev) +{ + struct mt792x_phy *phy =3D &dev->phy; + + set_bit(MT76_STATE_ROC_ABORT, &phy->mt76->state); + timer_delete(&phy->roc_timer); + ieee80211_queue_work(phy->mt76->hw, &phy->roc_work); +} + void mt7921_roc_abort_sync(struct mt792x_dev *dev) { struct mt792x_phy *phy =3D &dev->phy; =20 timer_delete_sync(&phy->roc_timer); cancel_work_sync(&phy->roc_work); - /* Note: caller must hold mutex if ieee80211_iterate_interfaces is - * needed for ROC cleanup. Some call sites (like mt7921_mac_sta_remove) - * already hold the mutex via mt76_sta_remove(). For suspend paths, - * the mutex should be acquired before calling this function. - */ if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) ieee80211_iterate_interfaces(mt76_hw(dev), IEEE80211_IFACE_ITER_RESUME_ALL, @@ -392,6 +399,15 @@ void mt7921_roc_work(struct work_struct *work) phy =3D (struct mt792x_phy *)container_of(work, struct mt792x_phy, roc_work); =20 + /* Check abort flag before acquiring mutex to prevent deadlock. + * Only send expired callback if ROC was actually active. + */ + if (test_and_clear_bit(MT76_STATE_ROC_ABORT, &phy->mt76->state)) { + if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) + ieee80211_remain_on_channel_expired(phy->mt76->hw); + return; + } + if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) return; =20 @@ -887,7 +903,8 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struc= t ieee80211_vif *vif, struct mt792x_dev *dev =3D container_of(mdev, struct mt792x_dev, mt76); struct mt792x_sta *msta =3D (struct mt792x_sta *)sta->drv_priv; =20 - mt7921_roc_abort_sync(dev); + /* Async abort - caller already holds mutex */ + mt7921_roc_abort_async(dev); mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->deflink.wcid); mt76_connac_pm_wake(&dev->mphy, &dev->pm); =20 diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/= wireless/mediatek/mt76/mt7921/pci.c index 9f76b334b93d..ec9686183251 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -426,9 +426,7 @@ static int mt7921_pci_suspend(struct device *device) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); =20 - mt792x_mutex_acquire(dev); mt7921_roc_abort_sync(dev); - mt792x_mutex_release(dev); =20 err =3D mt792x_mcu_drv_pmctrl(dev); if (err < 0) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net= /wireless/mediatek/mt76/mt7921/sdio.c index 92ea2811816f..3421e53dc948 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -219,9 +219,7 @@ static int mt7921s_suspend(struct device *__dev) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); =20 - mt792x_mutex_acquire(dev); mt7921_roc_abort_sync(dev); - mt792x_mutex_release(dev); =20 err =3D mt792x_mcu_drv_pmctrl(dev); if (err < 0) --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f177.google.com (mail-dy1-f177.google.com [74.125.82.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6F7D36CE04 for ; Tue, 20 Jan 2026 06:29:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890546; cv=none; b=Lln/7VpjV6UtCzx8X1hplbLwnK9as9vezYRhxw1iCM+tEEyR9sVSKUhwrl4SbGxDgS9K3j3uK6uPNisza79s/ASiDQ4g345NzlrbnqvHstVFwy1QMVAfxlnvEyiKRzjQI4GgKLZs37H+2w8ilveyn0NBgs7h6p73c1eF2oacppY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890546; c=relaxed/simple; bh=1vGbeUFHZoPrw+RBYT0ajksYNqGtsOHNrs6As9l5Mbg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VqexIO0AkILInz0GifTx18bBijgzynXyqR0ImhI3shjEpUhuJ5Ju+eoLApJo81PmUxPEQ3uo/6RZ8YjTuL02jwZb9c+w9kdsE046N03Ef4ra6xnGWW2ebq8rZ+6Gd6F1zWBJ1+GQ0pW60zzRbjlz/PQtT82+897vUfIojjbto54= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lTV2nKGk; arc=none smtp.client-ip=74.125.82.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lTV2nKGk" Received: by mail-dy1-f177.google.com with SMTP id 5a478bee46e88-2b6fd5bec41so602705eec.1 for ; Mon, 19 Jan 2026 22:29:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890544; x=1769495344; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=cZ1oBr1p2m8ckSj93rp5Wujk0nNyKJFebQgZ7BR/4/Q=; b=lTV2nKGk6aExKyZQK77rBUB+uSjBVHPPDDwTTYV1TAWr2qIY4jJQL/Q33SxaB6nDQS iz0URy336d+McnC++4k9XWujF9/xlf5LDX9hxBWLSxYD62Z1al+gjiwQUrM0TrdHsQfx MXF/CAvEnXWVCTVC//RCe2Uky2ocexpbvzAowVmtpecNNSe9a1qzFk/sz+GEnAy//EvT 717RCZbUffaqaPRoVmuEpvQcpPtyC094ZdB8TMBfXTlbac3nltF521OTVmOZmCBS3/+C 4to8zf55BaAaRWNLbnPg+iLRHTIk4I7spoYVpueTUzKbXzLrxgGs0gAH7DHx51kvm9WW olJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890544; x=1769495344; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=cZ1oBr1p2m8ckSj93rp5Wujk0nNyKJFebQgZ7BR/4/Q=; b=IN1c1BvkiQzSIcvz2zGawidjL4/6/yrc7BmO9Mx++htDs2YMd1L7d5shEiCZEdUUy0 pmnzMtotti7YOYWByKH47Vwnp+2XYAoOoPvNYzBjX7ivp6xiNBi0RqOGho0+/D27zXg7 wWNP5ZDat/bxdaTPaQ/We2ZhvHE5FZ1PN0hLEINHE8T6CkFdRrHvIPEYVvHF2Aqj3Yt2 vmiGI9zPBxZu7ibha4nuOgi/du4meShW4Ohsx7nEi8nVpQAaJAyYWC4JXXTjJ3KW7gBV EHRj+R1TjDW4Z6pSc+WEEZtEipLP4D6eaJ6/eZz4GYLqOLU6PMQ1aV+0zApMJ3TX1xCz ZA+A== X-Forwarded-Encrypted: i=1; AJvYcCXpwy1/1J26SARaEOqI87Cg0jGHqhDssQj+CV3xnwgwEw4GbCfLrV+5ooNAzlwuNwbRhWOyhvtA5sF5as8=@vger.kernel.org X-Gm-Message-State: AOJu0YyyvGJtReZ6+h5VKBwuI/booCmiVyiFnxlU2Yhix86hiGBbViyj CBIAdzZ9AXlflMcL68pmZfEZUp0XSzb+X2bf7bnwCbu9quJn8NyqPHxY X-Gm-Gg: AZuq6aLaJkA3yQf/MfwfYaDx2C8TwyaGep9XnQPILfTh8q753xIvzKBrrLDAJ/owe/5 Dbj39olbuabYJ/r/gJaU52O0OVb8L/XKeH3ygoEXhRGgJxwnHII/+wJ0HSJo/MUhCi0fk9G1d0q NU6mZUsypO8+vQzdZi+dZIws9zkSBJPQYgkb6Iw3xlQCNbEI4Y7Rw6YpmGVjRR9GRtB3NOf19c8 dq/vYSuHGjUh4TqD0qU9vxJPf2/VFLdjFYN/u6k0SWh4jbKASFfvJKUP6jtWSde/CqvCSl0Ed+b DlQhMplV6v2YrzayuM2l6OJitgnxSD5fPeypwdqKrvPGVi8MUMjbOeKxQMzYax82duyiaQlVggz TCB6ncpfodm0MtjX9TUG4yuHqAKH+dnCUaWpjP7GTFRx2OPrVXBAkOrqk2rirLflMH6GrOxk2aD 2QpeR/UMIG5Y9PnC0Y83mNTxXP4LGAQrZpHRow5pqohc0uhFR8CZLUM+WsEl7v X-Received: by 2002:a05:7301:3f16:b0:2ae:5552:b5ae with SMTP id 5a478bee46e88-2b6b411a106mr8033764eec.36.1768890543650; Mon, 19 Jan 2026 22:29:03 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:03 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 05/11] wifi: mt76: mt7925: add comprehensive NULL pointer protection for MLO Date: Mon, 19 Jan 2026 22:28:48 -0800 Message-ID: <20260120062854.126501-6-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Add NULL pointer checks for functions that return pointers to link-related structures throughout the mt7925 driver. During MLO state transitions, these functions can return NULL when link configuration is not synchronized. Functions protected: - mt792x_vif_to_bss_conf(): Returns link BSS configuration - mt792x_vif_to_link(): Returns driver link state - mt792x_sta_to_link(): Returns station link state Files updated: 1. mac.c: - mt7925_vif_connect_iter(): Check bss_conf before use - mt7925_mac_sta_assoc(): Check bss_conf before use 2. main.c: - mt7925_set_key(): Check link_conf and mlink - mt7925_mac_link_sta_add(): Check link_conf and mlink - mt7925_mac_link_sta_assoc(): Check bss_conf and mlink - mt7925_mac_link_sta_remove(): Check bss_conf and mlink - mt7925_change_vif_links(): Check conf before use - mt7925_assign_vif_chanctx(): Check mconf and mlink - mt7925_unassign_vif_chanctx(): Check mconf and mlink - mt7925_mgd_prepare_tx(): Check link_conf 3. mcu.c: - mt7925_mcu_sta_phy_tlv(): Check link_sta - mt7925_mcu_sta_amsdu_tlv(): Check link_sta - mt7925_mcu_sta_mld_tlv(): Check link_sta - mt7925_mcu_sta_cmd(): Check mlink - mt7925_mcu_add_bss_info(): Check link_conf - mt7925_mcu_set_chctx(): Check link_conf and mlink Prevents crashes during: - BSSID roaming transitions - MLO setup and teardown - Hardware reset operations - Runtime power management Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt= 7925 device") Signed-off-by: Zac Bowling --- .../net/wireless/mediatek/mt76/mt7925/mac.c | 6 ++ .../net/wireless/mediatek/mt76/mt7925/main.c | 82 ++++++++++++++++--- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 22 ++++- 3 files changed, 97 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/= wireless/mediatek/mt76/mt7925/mac.c index 871b67101976..184efe8afa10 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -1271,6 +1271,12 @@ mt7925_vif_connect_iter(void *priv, u8 *mac, bss_conf =3D mt792x_vif_to_bss_conf(vif, i); mconf =3D mt792x_vif_to_link(mvif, i); =20 + /* Skip links that don't have bss_conf set up yet in mac80211. + * This can happen during HW reset when link state is inconsistent. + */ + if (!bss_conf) + continue; + mt76_connac_mcu_uni_add_dev(&dev->mphy, bss_conf, &mconf->mt76, &mvif->sta.deflink.wcid, true); mt7925_mcu_set_tx(dev, bss_conf); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net= /wireless/mediatek/mt76/mt7925/main.c index 2d358a96640c..15d1b1b8d9f8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -604,6 +604,10 @@ static int mt7925_set_link_key(struct ieee80211_hw *hw= , enum set_key_cmd cmd, link_sta =3D sta ? mt792x_sta_to_link_sta(vif, sta, link_id) : NULL; mconf =3D mt792x_vif_to_link(mvif, link_id); mlink =3D mt792x_sta_to_link(msta, link_id); + + if (!link_conf || !mconf || !mlink) + return -EINVAL; + wcid =3D &mlink->wcid; wcid_keyidx =3D &wcid->hw_key_idx; =20 @@ -856,12 +860,17 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *m= dev, =20 msta =3D (struct mt792x_sta *)link_sta->sta->drv_priv; mlink =3D mt792x_sta_to_link(msta, link_id); + if (!mlink) + return -EINVAL; =20 idx =3D mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1); if (idx < 0) return -ENOSPC; =20 mconf =3D mt792x_vif_to_link(mvif, link_id); + if (!mconf) + return -EINVAL; + mt76_wcid_init(&mlink->wcid, 0); mlink->wcid.sta =3D 1; mlink->wcid.idx =3D idx; @@ -887,6 +896,8 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mde= v, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); =20 link_conf =3D mt792x_vif_to_bss_conf(vif, link_id); + if (!link_conf) + return -EINVAL; =20 /* should update bss info before STA add */ if (vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { @@ -993,18 +1004,29 @@ mt7925_mac_set_links(struct mt76_dev *mdev, struct i= eee80211_vif *vif) { struct mt792x_dev *dev =3D container_of(mdev, struct mt792x_dev, mt76); struct mt792x_vif *mvif =3D (struct mt792x_vif *)vif->drv_priv; - struct ieee80211_bss_conf *link_conf =3D - mt792x_vif_to_bss_conf(vif, mvif->deflink_id); - struct cfg80211_chan_def *chandef =3D &link_conf->chanreq.oper; - enum nl80211_band band =3D chandef->chan->band, secondary_band; + struct ieee80211_bss_conf *link_conf; + struct cfg80211_chan_def *chandef; + enum nl80211_band band, secondary_band; + u16 sel_links; + u8 secondary_link_id; =20 - u16 sel_links =3D mt76_select_links(vif, 2); - u8 secondary_link_id =3D __ffs(~BIT(mvif->deflink_id) & sel_links); + link_conf =3D mt792x_vif_to_bss_conf(vif, mvif->deflink_id); + if (!link_conf) + return; + + chandef =3D &link_conf->chanreq.oper; + band =3D chandef->chan->band; + + sel_links =3D mt76_select_links(vif, 2); + secondary_link_id =3D __ffs(~BIT(mvif->deflink_id) & sel_links); =20 if (!ieee80211_vif_is_mld(vif) || hweight16(sel_links) < 2) return; =20 link_conf =3D mt792x_vif_to_bss_conf(vif, secondary_link_id); + if (!link_conf) + return; + secondary_band =3D link_conf->chanreq.oper.chan->band; =20 if (band =3D=3D NL80211_BAND_2GHZ || @@ -1032,6 +1054,8 @@ static void mt7925_mac_link_sta_assoc(struct mt76_dev= *mdev, =20 msta =3D (struct mt792x_sta *)link_sta->sta->drv_priv; mlink =3D mt792x_sta_to_link(msta, link_sta->link_id); + if (!mlink) + return; =20 mt792x_mutex_acquire(dev); =20 @@ -1041,12 +1065,13 @@ static void mt7925_mac_link_sta_assoc(struct mt76_d= ev *mdev, link_conf =3D mt792x_vif_to_bss_conf(vif, vif->bss_conf.link_id); } =20 - if (vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { + if (link_conf && vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->st= a->tdls) { struct mt792x_bss_conf *mconf; =20 mconf =3D mt792x_link_conf_to_mconf(link_conf); - mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, - link_conf, link_sta, true); + if (mconf) + mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, + link_conf, link_sta, true); } =20 ewma_avg_signal_init(&mlink->avg_ack_signal); @@ -1093,6 +1118,8 @@ static void mt7925_mac_link_sta_remove(struct mt76_de= v *mdev, =20 msta =3D (struct mt792x_sta *)link_sta->sta->drv_priv; mlink =3D mt792x_sta_to_link(msta, link_id); + if (!mlink) + return; =20 mt7925_roc_abort_sync(dev); =20 @@ -1106,10 +1133,12 @@ static void mt7925_mac_link_sta_remove(struct mt76_= dev *mdev, =20 link_conf =3D mt792x_vif_to_bss_conf(vif, link_id); =20 - if (vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { + if (link_conf && vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->st= a->tdls) { struct mt792x_bss_conf *mconf; =20 mconf =3D mt792x_link_conf_to_mconf(link_conf); + if (!mconf) + goto out; =20 if (ieee80211_vif_is_mld(vif)) mt792x_mac_link_bss_remove(dev, mconf, mlink); @@ -1117,6 +1146,7 @@ static void mt7925_mac_link_sta_remove(struct mt76_de= v *mdev, mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf, link_sta, false); } +out: =20 spin_lock_bh(&mdev->sta_poll_lock); if (!list_empty(&mlink->wcid.poll_list)) @@ -1304,6 +1334,8 @@ mt7925_mlo_pm_iter(void *priv, u8 *mac, struct ieee80= 211_vif *vif) mt792x_mutex_acquire(dev); for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) { bss_conf =3D mt792x_vif_to_bss_conf(vif, i); + if (!bss_conf) + continue; mt7925_mcu_uni_bss_ps(dev, bss_conf); } mt792x_mutex_release(dev); @@ -1630,6 +1662,8 @@ static void mt7925_ipv6_addr_change(struct ieee80211_= hw *hw, =20 for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) { bss_conf =3D mt792x_vif_to_bss_conf(vif, i); + if (!bss_conf) + continue; __mt7925_ipv6_addr_change(hw, bss_conf, idev); } } @@ -1691,6 +1725,9 @@ mt7925_conf_tx(struct ieee80211_hw *hw, struct ieee80= 211_vif *vif, [IEEE80211_AC_BK] =3D 1, }; =20 + if (!mconf) + return -EINVAL; + /* firmware uses access class index */ mconf->queue_params[mq_to_aci[queue]] =3D *params; =20 @@ -1861,6 +1898,8 @@ static void mt7925_vif_cfg_changed(struct ieee80211_h= w *hw, if (changed & BSS_CHANGED_ARP_FILTER) { for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) { bss_conf =3D mt792x_vif_to_bss_conf(vif, i); + if (!bss_conf) + continue; mt7925_mcu_update_arp_filter(&dev->mt76, bss_conf); } } @@ -1876,6 +1915,8 @@ static void mt7925_vif_cfg_changed(struct ieee80211_h= w *hw, } else if (mvif->mlo_pm_state =3D=3D MT792x_MLO_CHANGED_PS) { for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) { bss_conf =3D mt792x_vif_to_bss_conf(vif, i); + if (!bss_conf) + continue; mt7925_mcu_uni_bss_ps(dev, bss_conf); } } @@ -1897,7 +1938,12 @@ static void mt7925_link_info_changed(struct ieee8021= 1_hw *hw, struct ieee80211_bss_conf *link_conf; =20 mconf =3D mt792x_vif_to_link(mvif, info->link_id); + if (!mconf) + return; + link_conf =3D mt792x_vif_to_bss_conf(vif, mconf->link_id); + if (!link_conf) + return; =20 mt792x_mutex_acquire(dev); =20 @@ -2021,6 +2067,11 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, str= uct ieee80211_vif *vif, mlink =3D mlinks[link_id]; link_conf =3D mt792x_vif_to_bss_conf(vif, link_id); =20 + if (!link_conf) { + err =3D -EINVAL; + goto free; + } + rcu_assign_pointer(mvif->link_conf[link_id], mconf); rcu_assign_pointer(mvif->sta.link[link_id], mlink); =20 @@ -2101,9 +2152,14 @@ static int mt7925_assign_vif_chanctx(struct ieee8021= 1_hw *hw, =20 if (ieee80211_vif_is_mld(vif)) { mconf =3D mt792x_vif_to_link(mvif, link_conf->link_id); + if (!mconf) { + mutex_unlock(&dev->mt76.mutex); + return -EINVAL; + } + pri_link_conf =3D mt792x_vif_to_bss_conf(vif, mvif->deflink_id); =20 - if (vif->type =3D=3D NL80211_IFTYPE_STATION && + if (pri_link_conf && vif->type =3D=3D NL80211_IFTYPE_STATION && mconf =3D=3D &mvif->bss_conf) mt7925_mcu_add_bss_info(&dev->phy, NULL, pri_link_conf, NULL, true); @@ -2132,6 +2188,10 @@ static void mt7925_unassign_vif_chanctx(struct ieee8= 0211_hw *hw, =20 if (ieee80211_vif_is_mld(vif)) { mconf =3D mt792x_vif_to_link(mvif, link_conf->link_id); + if (!mconf) { + mutex_unlock(&dev->mt76.mutex); + return; + } =20 if (vif->type =3D=3D NL80211_IFTYPE_STATION && mconf =3D=3D &mvif->bss_conf) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/= wireless/mediatek/mt76/mt7925/mcu.c index cf0fdea45cf7..94ec62a4538a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -1087,6 +1087,8 @@ mt7925_mcu_sta_hdr_trans_tlv(struct sk_buff *skb, struct mt792x_link_sta *mlink; =20 mlink =3D mt792x_sta_to_link(msta, link_sta->link_id); + if (!mlink) + return; wcid =3D &mlink->wcid; } else { wcid =3D &mvif->sta.deflink.wcid; @@ -1120,6 +1122,9 @@ int mt7925_mcu_wtbl_update_hdr_trans(struct mt792x_de= v *dev, link_sta =3D mt792x_sta_to_link_sta(vif, sta, link_id); mconf =3D mt792x_vif_to_link(mvif, link_id); =20 + if (!mlink || !mconf) + return -EINVAL; + skb =3D __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mconf->mt76, &mlink->wcid, MT7925_STA_UPDATE_MAX_SIZE); @@ -1741,6 +1746,8 @@ mt7925_mcu_sta_amsdu_tlv(struct sk_buff *skb, amsdu->amsdu_en =3D true; =20 mlink =3D mt792x_sta_to_link(msta, link_sta->link_id); + if (!mlink) + return; mlink->wcid.amsdu =3D true; =20 switch (link_sta->agg.max_amsdu_len) { @@ -1773,6 +1780,10 @@ mt7925_mcu_sta_phy_tlv(struct sk_buff *skb, =20 link_conf =3D mt792x_vif_to_bss_conf(vif, link_sta->link_id); mconf =3D mt792x_vif_to_link(mvif, link_sta->link_id); + + if (!link_conf || !mconf) + return; + chandef =3D mconf->mt76.ctx ? &mconf->mt76.ctx->def : &link_conf->chanreq.oper; =20 @@ -1851,6 +1862,10 @@ mt7925_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, =20 link_conf =3D mt792x_vif_to_bss_conf(vif, link_sta->link_id); mconf =3D mt792x_vif_to_link(mvif, link_sta->link_id); + + if (!link_conf || !mconf) + return; + chandef =3D mconf->mt76.ctx ? &mconf->mt76.ctx->def : &link_conf->chanreq.oper; band =3D chandef->chan->band; @@ -1935,6 +1950,9 @@ mt7925_mcu_sta_mld_tlv(struct sk_buff *skb, =20 mconf =3D mt792x_vif_to_link(mvif, i); mlink =3D mt792x_sta_to_link(msta, i); + if (!mconf || !mlink) + continue; + mld->link[cnt].wlan_id =3D cpu_to_le16(mlink->wcid.idx); mld->link[cnt++].bss_idx =3D mconf->mt76.idx; =20 @@ -2027,13 +2045,13 @@ int mt7925_mcu_sta_update(struct mt792x_dev *dev, .rcpi =3D to_rcpi(rssi), }; struct mt792x_sta *msta; - struct mt792x_link_sta *mlink; + struct mt792x_link_sta *mlink =3D NULL; =20 if (link_sta) { msta =3D (struct mt792x_sta *)link_sta->sta->drv_priv; mlink =3D mt792x_sta_to_link(msta, link_sta->link_id); } - info.wcid =3D link_sta ? &mlink->wcid : &mvif->sta.deflink.wcid; + info.wcid =3D (link_sta && mlink) ? &mlink->wcid : &mvif->sta.deflink.wci= d; info.newly =3D state !=3D MT76_STA_INFO_STATE_ASSOC; =20 return mt7925_mcu_sta_cmd(&dev->mphy, &info); --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f179.google.com (mail-dy1-f179.google.com [74.125.82.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C5ECA3803D1 for ; Tue, 20 Jan 2026 06:29:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890548; cv=none; b=kQEQclKXqjD//40od4d5QDPdfuFRoT51RJmkeV/8l/qBtKfo+jJzRqS5PY2qWAQzjY1Bo9aRfwpTIvvQhXDIPL0o9UzFdFjCfWAxTTPJgaAWlgaLXcs9Evvz282TXxCkM9w+en7/fHxAWjEpJBvb5R1zi7YgvG+oHC1Wntz2/e8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890548; c=relaxed/simple; bh=IkGS2pbb9DGLGXEWPJhYUmq0EJShmdW9s055oJTD1fM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r62XJxiWPv6S/2hQzpHY56Xjegt3Zf3yRF8WiEEhLTuoiDb4/UiCfn+87yP/fWj7E2CDtwdIeF199QWk++RLJ3DU5OS2b9z3l+7wP6yItU/dOee1J7l0oBvpV4abiet7FIKwaiI1ZSSKRmxV5ieMMtYM8mR6PU72SJdmMYxVCAQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ef7RKXMl; arc=none smtp.client-ip=74.125.82.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ef7RKXMl" Received: by mail-dy1-f179.google.com with SMTP id 5a478bee46e88-2ae38f81be1so5614218eec.0 for ; Mon, 19 Jan 2026 22:29:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890545; x=1769495345; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=gq8BwtBE3udkhb8xxJaDge5ayHDcllBWREYlF8lWPK8=; b=Ef7RKXMlRU6Wl/SKant8GmP849OnO+ckbTBrRC/vbhy+QBuGwkcVg2KqHc1OlGIvKb 43KGyqAxELOBcjPrlPHLoZwBjI1t8wDXj1zTHVf8w0CcngZ2sVTKCe5OheDXFZ4O0d/G Dj2nMdtQLIzStvO1cGLqxmZCGBfMWl2tcOop/OHmDj4DhvqnWsVXQt6eeP0nSkHu9Hwu 3kuJVbLdqCyKG9sdPeu0NrIxn4XO37qXIqZr/v/yx3CTw5+V0QxCMpUQb4ecLC14b4WE B+Ev7W4quQ/TC8dLEprOi/No1f7icosDUtaFP3gR4j9EDpsjFUybAer8i8dD+5H9nd2l Bobw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890545; x=1769495345; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gq8BwtBE3udkhb8xxJaDge5ayHDcllBWREYlF8lWPK8=; b=Vcs12lOzZmP40e8bcTF+LTQkDpLFaJbAJUseNZH+TEowKoEJ7522dejAX4fscuT4Qx nCYAc6vti5W+e305JkfK2a3LW7ci4tZf1HLolY9KFMIaQRCzwyI1HnDRpabzGrKW7Hve zmAwB/ALrh2+LZZZw+WrsFLYys4Zkh/8Ign6KxAdufySsCcS7MbYaj7Jg3cxwWfH9wDu wHTNjZRrNsCLFKqrK/pAVgu+fXMjIpz4fB3U92ol73lQQc2nI7dpaVQrjMPX8M9pzMSQ Gj+mcyQaUs9GcOqytTKwnGN4UIc+j6xS84IPB0EHaAMw6mtJu8fW54nPfCj1LFVzEt/e tv7A== X-Forwarded-Encrypted: i=1; AJvYcCWIMGqk3N8G4cpds3KC0yWaExvdqL+Wmh2b+WSEf1/QkYFku3Vahq+I2AR2tOy3kXiYPrH/MICcQYRLKh4=@vger.kernel.org X-Gm-Message-State: AOJu0YzVO6c3a1lLfhm0lcp2+gtIeV+JmvRwKHBgAQf+LhAkqb9ux3Mc XH76jROhvMbA3gSar7F9HCQMHr9C0zN622O6FJV+6x9fkoic8XQgz31J X-Gm-Gg: AZuq6aJaX/U03nhpX7WbmIP1YXCLU7phTSGKJQLRh3Naj8YBKeNmkngY4medZHVa7b7 yEiBG/rUZ8J2a+Ze8QAK9rsGTEMqDp/g38JdfjD75jjTUYChFbZvayPyd/rRvDuQZlR4rdxLQ3e XCPPFzfJARz73IQLGowfG1r6Eu+93xh+/Sbqs68TEnVZLpO0bjyT07XG5pjbkrd+zFgahPepyn2 DD3LBbGFIL+8P4SWCmwjFjGVgs29sRilXGAdNmUSJdCcSjd2qzs/ao2YsP3rnFyzNcTifsNTqpQ awbp1O+YbyiEWIzhMko8gWz2CP8HhZEsaXDHPyFE1YlcoVJ8tpU0+x7Bur/33O3gUiu6vZt42DJ AYuCWwm+KWdz0OpcO672uCtJYGQKc3I5GnhhhsZ9L6iLwvK2KC3ElDfGp+ScoUPY2k250JOHYhe 0AfwQnI/sOl92fdysrUEZpAp9AvgqmF8BEgukXGQekq5OJt4I80WzsDgzNtICc X-Received: by 2002:a05:7301:290a:b0:2ae:60fd:6f18 with SMTP id 5a478bee46e88-2b6b4e8a496mr11903860eec.22.1768890544990; Mon, 19 Jan 2026 22:29:04 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:04 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 06/11] wifi: mt76: mt7925: add mutex protection in critical paths Date: Mon, 19 Jan 2026 22:28:49 -0800 Message-ID: <20260120062854.126501-7-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Add proper mutex protection for mt7925 driver operations that access hardware state without proper synchronization. This fixes race conditions that can cause system instability during power management and recovery. Fixes added: 1. mac.c: mt7925_mac_reset_work() - Wrap ieee80211_iterate_active_interfaces() with mt792x_mutex - The vif_connect_iter callback accesses hardware state 2. mac.c: mt7925_mac_sta_assoc() - Wrap vif_connect_iter call with mutex protection - Called during station association which races with PM 3. main.c: mt7925_set_runtime_pm() - Add mutex protection around mt76_connac_pm_wake/sleep - Runtime PM can race with other operations 4. main.c: mt7925_set_mlo_pm() - Add mutex protection around MLO PM configuration - Prevents races during MLO link setup/teardown 5. pci.c: mt7925_pci_resume() - Add mutex protection around ieee80211_iterate_active_interfaces - The vif iteration accesses hardware state that needs synchronization These protections ensure consistent hardware state access during power management transitions and recovery operations. Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt= 7925 device") Signed-off-by: Zac Bowling --- drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 2 ++ drivers/net/wireless/mediatek/mt76/mt7925/main.c | 6 ++++-- drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/= wireless/mediatek/mt76/mt7925/mac.c index 184efe8afa10..06420ac6ed55 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -1331,9 +1331,11 @@ void mt7925_mac_reset_work(struct work_struct *work) dev->hw_full_reset =3D false; pm->suspended =3D false; ieee80211_wake_queues(hw); + mt792x_mutex_acquire(dev); ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7925_vif_connect_iter, NULL); + mt792x_mutex_release(dev); mt76_connac_power_save_sched(&dev->mt76.phy, pm); =20 mt7925_regd_change(&dev->phy, "00"); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net= /wireless/mediatek/mt76/mt7925/main.c index 15d1b1b8d9f8..80ca5181150b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -755,9 +755,11 @@ void mt7925_set_runtime_pm(struct mt792x_dev *dev) bool monitor =3D !!(hw->conf.flags & IEEE80211_CONF_MONITOR); =20 pm->enable =3D pm->enable_user && !monitor; + mt792x_mutex_acquire(dev); ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7925_pm_interface_iter, dev); + mt792x_mutex_release(dev); pm->ds_enable =3D pm->ds_enable_user && !monitor; mt7925_mcu_set_deep_sleep(dev, pm->ds_enable); } @@ -1331,14 +1333,12 @@ mt7925_mlo_pm_iter(void *priv, u8 *mac, struct ieee= 80211_vif *vif) if (mvif->mlo_pm_state !=3D MT792x_MLO_CHANGED_PS) return; =20 - mt792x_mutex_acquire(dev); for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) { bss_conf =3D mt792x_vif_to_bss_conf(vif, i); if (!bss_conf) continue; mt7925_mcu_uni_bss_ps(dev, bss_conf); } - mt792x_mutex_release(dev); } =20 void mt7925_mlo_pm_work(struct work_struct *work) @@ -1347,9 +1347,11 @@ void mt7925_mlo_pm_work(struct work_struct *work) mlo_pm_work.work); struct ieee80211_hw *hw =3D mt76_hw(dev); =20 + mt792x_mutex_acquire(dev); ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7925_mlo_pm_iter, dev); + mt792x_mutex_release(dev); } =20 void mt7925_scan_work(struct work_struct *work) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/= wireless/mediatek/mt76/mt7925/pci.c index c4161754c01d..3a9e32a1759d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -455,7 +455,9 @@ static int mt7925_pci_suspend(struct device *device) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); =20 + mt792x_mutex_acquire(dev); mt7925_roc_abort_sync(dev); + mt792x_mutex_release(dev); =20 err =3D mt792x_mcu_drv_pmctrl(dev); if (err < 0) @@ -582,10 +584,12 @@ static int _mt7925_pci_resume(struct device *device, = bool restore) } =20 /* restore previous ds setting */ + mt792x_mutex_acquire(dev); if (!pm->ds_enable) mt7925_mcu_set_deep_sleep(dev, false); =20 mt7925_mcu_regd_update(dev, mdev->alpha2, dev->country_ie_env); + mt792x_mutex_release(dev); failed: pm->suspended =3D false; =20 --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f171.google.com (mail-dy1-f171.google.com [74.125.82.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84E5637F8A2 for ; Tue, 20 Jan 2026 06:29:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890550; cv=none; b=Xmv2g/m4dIol1gjL0vwuzr25BohadPT0Z1mxdfd8bC9pBk22riDsMWhwl4EcJfXSc8r9oABp4xKnOmsgyTSFMgzoxz6YX70eOvb92emj9B0Xjr1lJNlM/EnWb9sREaSSerIOkhWteRYa10FHYBNL+AaH+9thOqt2oRatMGn4NFE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890550; c=relaxed/simple; bh=56oCFiJ1Fh61sRezmynDWOGrNpWTbudvtUqxK0WIYv8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GuUzEno1ubz5qH/tN7ppn4nlYn5nCHbzua+k8MMq3ujiPbkSAxCvMCp9y0O+SKqhu1ojmSGDVFh8g6QQtBFwJT2wQQFa/lNuimmdWDe+FZy7UNVvTgckXz/rZhsdAcvimxdr05uDD92DLiLlVoSY883OpCeQ2NtIN8nfUdC7k5s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CPJv5e58; arc=none smtp.client-ip=74.125.82.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CPJv5e58" Received: by mail-dy1-f171.google.com with SMTP id 5a478bee46e88-2b6bf6adc65so4982887eec.0 for ; Mon, 19 Jan 2026 22:29:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890547; x=1769495347; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=VGov7+UsnnkD8BK1HtQcfIxHNxhYSq3s1xKOOfEdd3U=; b=CPJv5e58By9ox8KUwU+eCWb5ka9LmnEqfyDiXnMnSv5mUqSldNXxYMt1VxMJX9HpWu rl9w3oQ5/40PpPCg9GzjtwSwDS+YNHUkAmFkJz4Dr4t5nWzzcWrS07NW5XZrmrBhnssj 4xAwPE3x+JDSOaKURfqVROY9mCQFEe9lbAvuwWhdcMNx98Y4MZ6x+heQUgJINwagv1wj GyStPgW2HKSJJYhKS6kT1UV7ZHwCZB3JMxOmDhHO33hoV268/jdxC4I5SlIgPl9hT/ka D0qJbgNyedvgwHVBRFPjmnHRDxDm0MGwdSkwLoY1+i2Tc+JTnWDHz58S/MKgrawnQL+Z A1jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890547; x=1769495347; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=VGov7+UsnnkD8BK1HtQcfIxHNxhYSq3s1xKOOfEdd3U=; b=kC/lRf+bQs73VAa9aDfwFWPFH3FAoCfK0agt77De1f3CkKurLOnw5TKOS8AwvX8J+w REeCThJgGJSSZDnp0i+cjWKsNij6AS0GOqeQ/epCwgiUOEutB3W6OpOkOwEiHYTwAKAY uhmWj4iN9K5wQA2fDn1sNiGd6pltRxTdAQg7F5V3vLkZQsDr4ml8WXZ2qjgofzyPNfnj sga2sO09JeeWVbpyoq1a/E81ML2pUnXtteZ8EWfVKLjH7AaZFPz8mxD5DkxMmQ7oxBmW rIc4x97aZBABzKpLgLVAZlbm6t7x0GATgPBwqmgdurSBUfEeMbnOyElVOSwSF5rU9Wqi usfg== X-Forwarded-Encrypted: i=1; AJvYcCVozqzZQLv2O2QvOZnI2DT6U57YanSywYj0T5ULreNBzxidNczpSdFelk/DeszePbl2nUvEcaQLq8ptHPs=@vger.kernel.org X-Gm-Message-State: AOJu0YyylbWDS6Mcbgst4fRsjLwudYZc0F4wucNzUkoFmcKgtNdm6Wai qKAzh56FheE3FPIa1mej+Oyy4zj04cBkaEt+N5Jaa0CAy3NLrPNiP6dk X-Gm-Gg: AZuq6aIJ15hs9GzyuPhNy0Xcdl2IvHShQ+4A2BWgb78vGmTk9TrJtnjkon2BdlDlKdV ju2h4q7Gm4+Kef/OZw6paxpwLOrZ5Qby6ddAXL1HAviZuqyniXYu9hSowjiuZjnld8VscKS4m74 eVin2P9tOqUS7lKfQUF2jYES5U21onT8v3W8RAgh6e5WmeRl+lllmm/TEduUPAvZhTPpJW8OPkx vEMr+42kq2+6dQN+8WK/XNJI9lXrdvGatMIisdrUoNXDYNznQks1+LJRGMvRnHzORy/gnbz7s5D 15m7h0TPuWHf++1LN/8Is6QR1oSKwynP2HJ0AhRZ1RJEjD5QP7r0nfGBgMbVb4ixf+eMrwgGrB8 QGmbLBdk3ZM3nxwce1LnSsRJusl60i6BUb82C9ghel2xJbBYaZTnjbs6KxXRP6m643C1TFRuXxb dGfJxevbrvxt9T9/hSCvYZE85b9L2233z4qAE5GsC8oUbm2ZlJcGwmVadn+NdJtXBsBmZ9Fx8= X-Received: by 2002:a05:7300:6420:b0:2ac:1c5a:9950 with SMTP id 5a478bee46e88-2b6b4e98df3mr12535539eec.34.1768890546301; Mon, 19 Jan 2026 22:29:06 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:05 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 07/11] wifi: mt76: mt7925: add MCU command error handling Date: Mon, 19 Jan 2026 22:28:50 -0800 Message-ID: <20260120062854.126501-8-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Add proper error handling for MCU command return values that were previously being ignored. Without proper error handling, failures in MCU communication can leave the driver in an inconsistent state. Functions updated: 1. main.c: mt7925_ampdu_action() - BA session setup - Check mt7925_mcu_uni_tx_ba() return value - Check mt7925_mcu_uni_rx_ba() return value - Return error to mac80211 on failure 2. main.c: mt7925_mac_link_sta_add() - Station addition - Check mt7925_mcu_add_bss_info() return value - Propagate errors during station setup 3. main.c: mt7925_set_key() - Key installation - Check mt7925_mcu_add_bss_info() return value when setting BSS info before key installation - Prevent key setup on communication failure These changes ensure that MCU communication failures are properly detected and reported to mac80211, allowing proper error recovery instead of leaving the driver in an undefined state. Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt= 7925 device") Signed-off-by: Zac Bowling --- .../net/wireless/mediatek/mt76/mt7925/main.c | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net= /wireless/mediatek/mt76/mt7925/main.c index 80ca5181150b..5f8a28d5ff72 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -637,8 +637,10 @@ static int mt7925_set_link_key(struct ieee80211_hw *hw= , enum set_key_cmd cmd, struct mt792x_phy *phy =3D mt792x_hw_phy(hw); =20 mconf->mt76.cipher =3D mt7925_mcu_get_cipher(key->cipher); - mt7925_mcu_add_bss_info(phy, mconf->mt76.ctx, link_conf, - link_sta, true); + err =3D mt7925_mcu_add_bss_info(phy, mconf->mt76.ctx, link_conf, + link_sta, true); + if (err) + goto out; } =20 if (cmd =3D=3D SET_KEY) @@ -904,11 +906,14 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *m= dev, /* should update bss info before STA add */ if (vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { if (ieee80211_vif_is_mld(vif)) - mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, - link_conf, link_sta, link_sta !=3D mlink->pri_link); + ret =3D mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, + link_conf, link_sta, + link_sta !=3D mlink->pri_link); else - mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, - link_conf, link_sta, false); + ret =3D mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, + link_conf, link_sta, false); + if (ret) + return ret; } =20 if (ieee80211_vif_is_mld(vif) && @@ -1287,22 +1292,22 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct= ieee80211_vif *vif, case IEEE80211_AMPDU_RX_START: mt76_rx_aggr_start(&dev->mt76, &msta->deflink.wcid, tid, ssn, params->buf_size); - mt7925_mcu_uni_rx_ba(dev, params, true); + ret =3D mt7925_mcu_uni_rx_ba(dev, params, true); break; case IEEE80211_AMPDU_RX_STOP: mt76_rx_aggr_stop(&dev->mt76, &msta->deflink.wcid, tid); - mt7925_mcu_uni_rx_ba(dev, params, false); + ret =3D mt7925_mcu_uni_rx_ba(dev, params, false); break; case IEEE80211_AMPDU_TX_OPERATIONAL: mtxq->aggr =3D true; mtxq->send_bar =3D false; - mt7925_mcu_uni_tx_ba(dev, params, true); + ret =3D mt7925_mcu_uni_tx_ba(dev, params, true); break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mtxq->aggr =3D false; clear_bit(tid, &msta->deflink.wcid.ampdu_state); - mt7925_mcu_uni_tx_ba(dev, params, false); + ret =3D mt7925_mcu_uni_tx_ba(dev, params, false); break; case IEEE80211_AMPDU_TX_START: set_bit(tid, &msta->deflink.wcid.ampdu_state); @@ -1311,8 +1316,9 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct i= eee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr =3D false; clear_bit(tid, &msta->deflink.wcid.ampdu_state); - mt7925_mcu_uni_tx_ba(dev, params, false); - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret =3D mt7925_mcu_uni_tx_ba(dev, params, false); + if (!ret) + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } mt792x_mutex_release(dev); --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f193.google.com (mail-dy1-f193.google.com [74.125.82.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF5D536CE09 for ; Tue, 20 Jan 2026 06:29:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890550; cv=none; b=rl+Mx/yWLSOaFqxjWDUOjENPANBcRWRV2gt9O6zVr6moxl4u6xWhkGfMgZXd4ra/ya8ajSs3FgTi73QJFBnjCF/JKezRpkU6jZgOnqhDV02oIhQMK5SoaE22LI4qRzER5SKm3XsuUe9c03g+KSefhoM+MTKceQots/Tdxje+FJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890550; c=relaxed/simple; bh=cJcXyjEZSUQDGUOvvl04ViXnS4Gd51j6mnYPp5zBgFI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nJvgKgDAbAFaja57+6dLHypoTiYZWbqk6a7l7hdZoskk8HF1e8j1Ls9rfMYOrvFf0TaZbGHyEruIOXdjvTgTyr1md9zQV1MbQLCeQ4+B1hj8m+dV9mGjnLUUcNy/k6Ory0OsCQCqrawzkDMKY4JogjuoBW2Zl8xyEKELmTBSWbc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=giqAmU8x; arc=none smtp.client-ip=74.125.82.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="giqAmU8x" Received: by mail-dy1-f193.google.com with SMTP id 5a478bee46e88-2b6bf6adc65so4982909eec.0 for ; Mon, 19 Jan 2026 22:29:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890548; x=1769495348; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=Yt1mPPXw8aFoKYpC5Tia09ZY3lzzrV+SydYHdLpjRKk=; b=giqAmU8xx9py7oVzsuNrxu3G+ede94Itd42sMGeY5FRQJe/y0gza5szqSxyZNIaeq6 Zn8Q6INsmYnS4lr0ZD0UM/XtZHnthQurpa+XMncZPuuCINA2XfNvhyw0g1yqJ6k7MOW9 gB+xCKuVqBk2p9ExMNx9fsLw9TL+stbmOKAfZhFmI2QanKzowPbnBOIZSProq1aeMYhg ha1qaclIZJDhsl6RTabzm/tgCqqgd3NuqtTHnQEEdENK5YlXJSvCkb8bevcVE5riDtS5 bVuCoT24nkploeWbDcXjc3T7pqOLw7ScZ0ufPla3FmeeYV+E9i7WMVGVIYEt9OfYUdO/ lmTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890548; x=1769495348; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Yt1mPPXw8aFoKYpC5Tia09ZY3lzzrV+SydYHdLpjRKk=; b=lhFdIhpOrfpewp2tlofencYpMSdLGJDDZBJHjjF1VIVhfIFH0ApZyTQfPeHPFUbtY7 ZWEIpnKPLcCyIaAMMDkfqsr9ZTKXVY1qpkrEkmwj4L8o7d675qQoZeoh48AV+CyjaciE 9ED9Cvny/ty58i1IUO5J4WK+aKku2+zAiculvpHcn9hanpF5Or/XRGBqrXGhg8Gw58qa BzYxOwPRd0F/fscIZvBostcfMwQebVR+E7TuKVPV65tYI7/ToaTrTwn36futvI9zONjA QXZlWY3XqkGN8xMyoSwFd1G5rbv1fV+XR9d6gEy98R6Nb5d+2B7T7owPK3bSirT6mKLa XTnw== X-Forwarded-Encrypted: i=1; AJvYcCVi/YznpP/0tnz2lD+yEpbdJCljbbQqDWxjwLmEeSug4vJRDuLQsNLKvrcc6IiF50+7fI+HrwKqSEQSLkU=@vger.kernel.org X-Gm-Message-State: AOJu0YzkTm/jewE97A+cUACp6ik7SKgaRPukU57oJK4D2VZlSYtS1Kf0 YbCGX45J1oEYNsN6avjD6LM2wKbWpFz32/TKXlsIpx4fd4zvmbgFT5x5 X-Gm-Gg: AZuq6aIKu31ZCu5nk5YYEyUrYAO717gHOOdtDWwrfGFI9Z4+/GGjSEw2dfk1k+2Unft 1QipEfT3e6jCsUWRtd7GFHEoWH6uOFvsC/qU1CK6fRG1sizVdazPmqoTpdfe6CdvCSZa8OqPd73 eoyI2fb2uVZd6WviRwIEzsoBWGD/X2zrjGXUOH4B9d6NehinMVsAfEEbB+YLsByTCC2/508eXCi zoOtw7naEZbpN+MVqGkBFn+W3Qh9JsMp8t1Wn6zFAnEdA+ZRRaydyA0eG8/JO/oY2ve3g6zrohZ K8orH4P9zzURx7AZ8//T9Eruz44X8pbxxAMpqyQMxXyYoWwfMPnVurJgHW85LQMv5E3Q4sdLvJx 7H+cdiG8XtA6gzpncqQ4kwqNjlq2EZBUxfySKkThsrB1F/RmhvLSCH6Mhjc/x8Ydj8IxcRTrKD9 sr27+b89GTeV92xr96LMd3EOD/JSsY9/7Ig6q+PmytfdJE8whBMOhIeCe22Och X-Received: by 2002:a05:7300:54d:b0:2a4:3593:ddd9 with SMTP id 5a478bee46e88-2b6b46c69ebmr9563555eec.6.1768890547673; Mon, 19 Jan 2026 22:29:07 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:07 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 08/11] wifi: mt76: mt7925: add lockdep assertions for mutex verification Date: Mon, 19 Jan 2026 22:28:51 -0800 Message-ID: <20260120062854.126501-9-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Add lockdep_assert_held() calls to critical MCU functions to help catch mutex violations during development and debugging. This follows the pattern used in other mt76 drivers (mt7996, mt7915, mt7615). Functions with new assertions: - mt7925_mcu_add_bss_info(): Core BSS configuration MCU command - mt7925_mcu_sta_update(): Station record update MCU command - mt7925_mcu_uni_bss_ps(): Power save state MCU command These functions modify firmware state and must be called with the device mutex held to prevent race conditions. The lockdep assertions will trigger warnings at runtime if code paths exist that call these functions without proper mutex protection. This aids in detecting the class of bugs fixed by patches in this series. Signed-off-by: Zac Bowling --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/= wireless/mediatek/mt76/mt7925/mcu.c index 94ec62a4538a..1c58b0be2be4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -1532,6 +1532,8 @@ int mt7925_mcu_uni_bss_ps(struct mt792x_dev *dev, }, }; =20 + lockdep_assert_held(&dev->mt76.mutex); + if (link_conf->vif->type !=3D NL80211_IFTYPE_STATION) return -EOPNOTSUPP; =20 @@ -2047,6 +2049,8 @@ int mt7925_mcu_sta_update(struct mt792x_dev *dev, struct mt792x_sta *msta; struct mt792x_link_sta *mlink =3D NULL; =20 + lockdep_assert_held(&dev->mt76.mutex); + if (link_sta) { msta =3D (struct mt792x_sta *)link_sta->sta->drv_priv; mlink =3D mt792x_sta_to_link(msta, link_sta->link_id); @@ -2853,6 +2857,8 @@ int mt7925_mcu_add_bss_info(struct mt792x_phy *phy, struct mt792x_link_sta *mlink_bc; struct sk_buff *skb; =20 + lockdep_assert_held(&dev->mt76.mutex); + skb =3D __mt7925_mcu_alloc_bss_req(&dev->mt76, &mconf->mt76, MT7925_BSS_UPDATE_MAX_SIZE); if (IS_ERR(skb)) --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dl1-f42.google.com (mail-dl1-f42.google.com [74.125.82.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38A3F38A704 for ; Tue, 20 Jan 2026 06:29:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890552; cv=none; b=nKhGsiTcewCT2T6o5cgSidHRiAEhFTd0Zb/0Vm0PRLs20FDQ0D1hDiQr1uSiB8e2SZShIP0ANbxRx3+pytl7DnPBS5gEwIuLcU1tfOroJLItZj+e0WAJbB3dtuBw/4Ip1xaA2ygOiqqksJC8o5+dVOIc1f7zrIL7vhuLN5Ac3sI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890552; c=relaxed/simple; bh=dRjFX1OxFoMErBW1Lic/dK0shEoukUCq8IytKXd5DYE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Nn5EGPV9+tRqA5fRs9598w2caBHgQI2L8sPithdS37mq/JPSviY2FUodsVwPEijylILvfRVaq7REOnLP0hy65gLbRtKvYr585YspGZd0mdhJ01jtYt3DYDBca5YRyX7/OVM9D01Lh9xQM41SGzWENjKuByxdDuk8BNL0qejgCGQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kHdzzFO9; arc=none smtp.client-ip=74.125.82.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kHdzzFO9" Received: by mail-dl1-f42.google.com with SMTP id a92af1059eb24-12460a7caa2so2243970c88.1 for ; Mon, 19 Jan 2026 22:29:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890549; x=1769495349; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=PemvynWJoEEr+vQfljTmIKiSnjimqG0bkRw68R0p5Rk=; b=kHdzzFO9h53qM9g7OK1vcSJPsRgw62MNHNEvolRc2mzPawGJmjeGwtVZX87r3ZrTW9 QW+qOh1MdJr7iRjJ9FjgYR+XOm+LBMG+yhjT97QjGBzCz+py7md/iIkyXdk1HMJOrX+4 cPKulZeWScSOEitdViakDIJ5nEI0iVJUMBvqHCeL8SXCKSazNlk6suT7SNUo4oJwNZwh NtAoUd40FZX3fLXXfJ40t4YquCxEP5RkBRwSAEuP++bAnsJ9o2BzCEtNYQPZkAQXDhY0 jg64vH8WdF3yeXNi2XmcuUsZxQ0Zxq1qVWW999Ro9RktAaTIPuhIfrZ+FqevFmhxrhUn uBug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890549; x=1769495349; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PemvynWJoEEr+vQfljTmIKiSnjimqG0bkRw68R0p5Rk=; b=XphysEeOr0aE997gVrasck/1tMpyLGnP1dSwFXumYS/qYU1dwds+7uNq9iUo13UG3Z 9S8TzkhNqxfaG+YY3RsXt4AWfzFf6ayAOSjEIdSfsjHhk89V6ksrUPtRSCpsTy0Q1xIl gK1d1Q5Se/btHkezZa5lOUl5S2T7UUbhN9TlGDNzg4D+dFi3bgS0+azE6hLyMHVeTsjY o7IkiOLUUjm1o3H9RCzH3sz8itGOIoFRBSTdG5QSgXLO0doPeubobzVUOsxsCrCqeE8j AWd5yZkLKx7Gz/xsrb3IdytqgBERBex5SvkGjNsT/7xmmhlCUh9TLN8OPpHi4YQATL6n FAmA== X-Forwarded-Encrypted: i=1; AJvYcCWU64K+XwGnQci2t6iJwbmgjWvRhsqdPVUXupxS/cqXba/l85UN1fhA5SquNf/6foQYf++UR3BKIHKJra8=@vger.kernel.org X-Gm-Message-State: AOJu0YxL4L323IqxiVB/M9z/2Uj65PI+/pXFjVd17QhOaYQuJRDj8Tq2 5aum4pjhVhKgUK0NaVY2a0B634C7PRhhy+tbShpl6yG5JHpS3QRyJS89 X-Gm-Gg: AZuq6aKBfylcbS6bJweJRONGZcLs4eF7I0q5MQ4DswgVKKUUMvqaEZsMYYkaQmYpR6j oTnOJfd4nSJA1dedGbH9dyi7GNHSKSCnscOlz5vgiuIMRKvtD76FkRj2FIb4LJ+5kasT1jcHiIb L8bY7fNA9giu/B1Q8/KtNAK10Puku71yXij3OoS7KoGKz3OSWbmJ0kbeO2jmMQfR0Ewufs/lk3c VdlqnMIAFqwCVEYxZFWey6D352PH9nQcVItjicCeseW+ABOBDFPuiDVQcKYOWUlx8r1f3JTZfQZ DzpkFV9ceO6ymvgLaxwrVjSYRbQmLedoU0gs8QP7hssaTFVPrhqXdARie4NQA0wJR2Lbah6Rso6 sbzS+3LyCM1p6Nywpet50HgX4cXnjg3eW14xRqG1hNW93MBskq+Kbl6Mwh0e6uNFnktz/8t5+OU +rDwGdGXbrZRXxvUcJFEXMmRBVLL+GXZ1r6TkSghsLyW0rfQj6QIYjiS0r3I0b X-Received: by 2002:a05:693c:4096:b0:2b7:108:40a4 with SMTP id 5a478bee46e88-2b701084a6bmr223705eec.14.1768890549004; Mon, 19 Jan 2026 22:29:09 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:08 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 09/11] wifi: mt76: mt7925: fix MLO roaming and ROC setup issues Date: Mon, 19 Jan 2026 22:28:52 -0800 Message-ID: <20260120062854.126501-10-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Fix two issues related to MLO roaming and remain-on-channel operations: 1. Key removal failure during MLO roaming: During MLO roaming, key removal can fail because the WCID (wireless client ID) is already cleaned up before the key removal operation completes. When roaming between APs in an MLO setup: - mac80211 triggers sta_state changes - mt7925_mac_link_sta_remove() is called for the old link - WCID is cleared via mt76_wcid_cleanup() - Later, key removal MCU command uses the now-invalid WCID Fix by checking if the WCID is still valid before sending key removal commands to firmware. If the WCID has already been cleaned up, skip the MCU command since the firmware has already removed the keys. 2. Kernel warning in MLO ROC setup: When starting a remain-on-channel operation in MLO mode, the driver passes incorrect parameters to mt7925_mcu_set_roc(), causing a kernel warning about invalid chanctx usage. Fix by checking for valid chanctx and link configuration before setting up ROC, and use the correct link_id from the vif when available. Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt= 7925 device") Signed-off-by: Zac Bowling --- .../net/wireless/mediatek/mt76/mt7925/main.c | 9 ++++++++- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 20 +++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net= /wireless/mediatek/mt76/mt7925/main.c index 5f8a28d5ff72..81373e479abd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -605,8 +605,15 @@ static int mt7925_set_link_key(struct ieee80211_hw *hw= , enum set_key_cmd cmd, mconf =3D mt792x_vif_to_link(mvif, link_id); mlink =3D mt792x_sta_to_link(msta, link_id); =20 - if (!link_conf || !mconf || !mlink) + if (!link_conf || !mconf || !mlink) { + /* During MLO roaming, link state may be torn down before + * mac80211 requests key removal. If removing a key and + * the link is already gone, consider it successfully removed. + */ + if (cmd !=3D SET_KEY) + return 0; return -EINVAL; + } =20 wcid =3D &mlink->wcid; wcid_keyidx =3D &wcid->hw_key_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/= wireless/mediatek/mt76/mt7925/mcu.c index 1c58b0be2be4..6f7fc1b9a440 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -1342,15 +1342,23 @@ int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *= mconf, u16 sel_links, for (i =3D 0; i < ARRAY_SIZE(links); i++) { links[i].id =3D i ? __ffs(~BIT(mconf->link_id) & sel_links) : mconf->link_id; + link_conf =3D mt792x_vif_to_bss_conf(vif, links[i].id); - if (WARN_ON_ONCE(!link_conf)) - return -EPERM; + if (!link_conf) + return -ENOLINK; =20 links[i].chan =3D link_conf->chanreq.oper.chan; - if (WARN_ON_ONCE(!links[i].chan)) - return -EPERM; + if (!links[i].chan) + /* Channel not configured yet - this can happen during + * MLO AP setup when links are being added sequentially. + * Return -ENOLINK to indicate link not ready. + */ + return -ENOLINK; =20 links[i].mconf =3D mt792x_vif_to_link(mvif, links[i].id); + if (!links[i].mconf) + return -ENOLINK; + links[i].tag =3D links[i].id =3D=3D mconf->link_id ? UNI_ROC_ACQUIRE : UNI_ROC_SUB_LINK; =20 @@ -1364,8 +1372,8 @@ int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *mc= onf, u16 sel_links, type =3D MT7925_ROC_REQ_JOIN; =20 for (i =3D 0; i < ARRAY_SIZE(links) && i < hweight16(vif->active_links); = i++) { - if (WARN_ON_ONCE(!links[i].mconf || !links[i].chan)) - continue; + if (!links[i].mconf || !links[i].chan) + return -ENOLINK; =20 chan =3D links[i].chan; center_ch =3D ieee80211_frequency_to_channel(chan->center_freq); --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f172.google.com (mail-dy1-f172.google.com [74.125.82.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5CEAC38B9AF for ; Tue, 20 Jan 2026 06:29:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890553; cv=none; b=RCWN2gYxD/b8QufRN4RmH4zQQkSExgupvZOuMCO89ycybcV4nQ4W4zrKlCz5GhjKjIubomiAxViHJY1zNQ1RK4AkzXgBn0nJc7zR2WpGJB+T871pFqVfrvXsyyTJWBF/a0WrMtj95ppPGxMk12/X7kO5CxoFmmEv/xtWdKYSAcw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890553; c=relaxed/simple; bh=Msmn00R/whpSKvYB7cyEtq9bHDCq1FKIinq7ESwlb0c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NzvY97Ud8eKBDE0DRswg0MguohlAQdum2xhrRmtt5NWnDw9J8fhJ6P9JbmOYuPWE18xrVqSV1agwMMWpQ+VKEOqOC1wLxVx0f2p5D+XPXzT8KsylhZ974S1DrZrBVtWVjmJ3apQ4ERimGEGHgcp7ptQNNnrwePebTFnb03CgD7E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bdZYWY0M; arc=none smtp.client-ip=74.125.82.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bdZYWY0M" Received: by mail-dy1-f172.google.com with SMTP id 5a478bee46e88-2b6f5a9cecaso1031390eec.0 for ; Mon, 19 Jan 2026 22:29:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890550; x=1769495350; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=jhF6S0lUNMQ6iu2San+RRE4uR0QE14549Ly/QDJAGJY=; b=bdZYWY0MQnX439Gsqr9mhNTZ95TFGUu5Rj+o0spj358gQxqF5M2PAmVgltVjB1OEKO GVZyVABRVe5U1mm6ESeZDQjySwpkv4j9tN4R6eX26Jry2H6GMOCRb+6uIWT+yb4+e4R+ PC8VsneaCHNeMErrw1o01BC0w64poyWNsZgbnwOnmHG4IlTV3dGwvrUgFmpW8dBgvdQR PlX2XGagVLTMMveJGD5RoGbBCLB6KzV32W0iKOg+vndK13BGXcfCXpfIxBBrdyKrAygl tBvbwJ6kjjMxSSIh5OBy6fp3/KG7aQIeflW/ws5OI1+Ri5j3ZeSmWCVVQLC0IXZlAUfM qokQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890550; x=1769495350; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jhF6S0lUNMQ6iu2San+RRE4uR0QE14549Ly/QDJAGJY=; b=qmaBsovzFI2xIJ8m6l3xVUG53EB+X/hQFeOs4NBmpO33clFXHJyCccM43MmAYtuRys nKcecFSst89n49ZtJ8QgyyG5Juv245i/qz2lwYbUM7IhGDPpWxOLdvPju0sZAx7XaF96 fWvxg6HJMcypblmqNbGf9JTSgFrQH4TC6BnDaLRlH0TLchU89nfgLSLSHBHSn83zhURt gCcIHeWKKY87ZtcMYXdiiRq02i6X+ceEd440pG4s1jy4pNQJQv5KBBHvWO6fyAvIpeYg JIilCfrmbSICVankJfBDrkU0CBhjI9LhJfm/vlbejD5AYDgKOfknD0tJtmpt2yfuajg0 9I9g== X-Forwarded-Encrypted: i=1; AJvYcCUIauHMiOIWGFbSGjpXAZqRz5PutG2MYL58IsKWJhdurb7zn+CsglnKANSyYRsZsa9M7aa4eko0KX8vgtA=@vger.kernel.org X-Gm-Message-State: AOJu0Yz/oZ6mn/U47ldjT1TxYKGiS1Un24tg1Drk0zJIoZY77/kQN/aP +9Fl1qBwZRHD26R0O9h+nRxOiIwy/kt22jT64zZpN7aTUfPALXjBC+JNIuUoQCYg X-Gm-Gg: AZuq6aIKd7LIrxriQU3nTOeDBFEraoZcrWrRaTIrhPFPioa65oZRZtAWMUYvNUHKrsT HB3wVTEnRAE+2G25vkB4EBKFTTit7XtZQcVJlHiIiXMlWbVBlOIzur1FXV/NrBLaZw/ynBmsSCK u9H+FLzwWl24ahRIaHtpA2+hYXZoNkxyE5IB1/aHIUTCGLlIA/6rjdjPD0otJBrwRAYm/TxK1lu AXeMRhzLV8IYsLV/w+d9hSYGV61XRTFex3GluJCcYWlQ/OBLkLk11ND+a1ZGTSQaYLIw8IKtZuW x0jjH4jqaHT23nAwb92w02Ml7M492vfEUn0nty+fGqnL6kNhryV0q/VCZ6Yx/ZiTTLyJLfP87iO IAXNCp40E43+Y5qkxPW2EtMalK4dSGvkO0AUxgWPrgs0GR5YdaiuMP8n5IfBLAfMN+KB0FwadS6 9iwkxY0s1bWwQHFKg5qUtLcOFf8A3i5DsLP6uA6qYTOGbOn1dNahLqofrpAgw/gee+HoSBgZk= X-Received: by 2002:a05:7300:3206:b0:2b4:7c92:3f7c with SMTP id 5a478bee46e88-2b6fd623ccdmr573615eec.6.1768890550416; Mon, 19 Jan 2026 22:29:10 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:10 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 10/11] wifi: mt76: mt7925: fix BA session teardown during beacon loss Date: Mon, 19 Jan 2026 22:28:53 -0800 Message-ID: <20260120062854.126501-11-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling The ieee80211_stop_tx_ba_cb_irqsafe() callback was conditionally called only when the MCU command succeeded. However, during beacon connection loss, the MCU command may fail because the AP is no longer reachable. If the callback is not called, mac80211's BA session state machine gets stuck in an intermediate state. When mac80211 later tries to tear down all BA sessions during disconnection, it hits a WARN in __ieee80211_stop_tx_ba_session() due to the inconsistent state. Fix by making the callback unconditional, matching the behavior of mt7921 and mt7996 drivers. The MCU command failure is acceptable during disconnection - what matters is that mac80211 is notified to complete the session teardown. Reported-by: Sean Wang Signed-off-by: Zac Bowling --- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net= /wireless/mediatek/mt76/mt7925/main.c index 81373e479abd..cc7ef2c17032 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1323,9 +1323,13 @@ mt7925_ampdu_action(struct ieee80211_hw *hw, struct = ieee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr =3D false; clear_bit(tid, &msta->deflink.wcid.ampdu_state); - ret =3D mt7925_mcu_uni_tx_ba(dev, params, false); - if (!ret) - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + /* MCU command may fail during beacon loss, but callback must + * always be called to complete the BA session teardown in + * mac80211. Otherwise the state machine gets stuck and triggers + * WARN in __ieee80211_stop_tx_ba_session(). + */ + mt7925_mcu_uni_tx_ba(dev, params, false); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } mt792x_mutex_release(dev); --=20 2.52.0 From nobody Sun Feb 8 04:33:42 2026 Received: from mail-dy1-f179.google.com (mail-dy1-f179.google.com [74.125.82.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 573D838A9BB for ; Tue, 20 Jan 2026 06:29:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890556; cv=none; b=XAJe2OT3mUGeMekLfWt2HR0nUlzS4PGSXv9ZRHNqTGDI98vM4yzfq5GW1OkdKPzD9j1ZHKz7yxLQyX2+atACzgJuCCGN+OLivcJO/hTmmwhtQGsf31y7AIKaUAMxMZXCJC3u6s1eYJGxH81BGD+S2ibutwsoeNuPUkFxRrKDfuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768890556; c=relaxed/simple; bh=Sndw9GK3sDCqJHnFoVwGZIb5iFCFzmXU83jlDkwH7eg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OMadqRCHAWsobCOh4KKz9JUtc+C5kTbbL3/IPJs3j0nlMmH4mBnF/5lPK5ND1KqdVEStIU3kHDi/YkxZwhTQ/NK4d+mFlbCAmsoLtoqPzwM4cGmek9+XVouhdZ37i7Tr0PWhRjlcueta/6WiHVgL/LfyTU2P+sz46z6Rkqbm20Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JlzuqDsJ; arc=none smtp.client-ip=74.125.82.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zacbowling.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JlzuqDsJ" Received: by mail-dy1-f179.google.com with SMTP id 5a478bee46e88-2b6bf6adc65so4983020eec.0 for ; Mon, 19 Jan 2026 22:29:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768890552; x=1769495352; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=t40lO5bXareLzTvQoLuZnyo9jiIRTa4btYWR4lNGZPU=; b=JlzuqDsJktiQNRWdK++irP0r+DtuFQ4zqRkVC2v/cV8zSELko5+GxfQhv2U7OrxY+f 6A4vTkPPj8y+Qv5QZpBU0Omp341lL3AYHydUmpFStOEI0O3vYpFQs1RneEwFrghKtgKH xO1E46Vhhipa+bxHyIEQfDzdQ3p3U2kqa+mZV4P43V/1SzzDScwSvPOu1ynMMTqsMdZM F2gkdwelAnCSyCGTV8L1YPlpCgMiKxV+OOTLpijIlyoy1UuXIv2LRJIX4lPE+niK2tyX MFBUCObj6S9y3gpXSxrO6S0B2Ufa3Dx0vVOnHgFZLxBTnHqeqNquI4zLc3vMn+8GzWNb M2EA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768890552; x=1769495352; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=t40lO5bXareLzTvQoLuZnyo9jiIRTa4btYWR4lNGZPU=; b=MlfHG/HSleYW06r6NK8qT6ArRGyDNOpkSlw4IL6+Jp57DsDT9ZN9f3KbQz2OQB832n WDYr/b8utG6Swt+w6Pzfk/hIh4/rIt93ZSz5VGD/5Kr4j7OA79Xi1lj4iiBzB82FvWIv zMISPdd4/kL5fB9UGPWq1CUMfb8Hf4iWv2mDU8HeSUP1VbTLmkoa1NQeAUTyIkiHtnL7 HBnEM8A91/it+8HrpXAnG41vOrsUECm0F64caraeUfh3EU8AXHjzZi2WO0SiB4bVsH6O 3c+m5SLH+LzAMwNdImBfRi2WZrsTMkq1GsfGT2kY8H49eDrQIXN2/QshHmkN7ov4nDjo QMFA== X-Forwarded-Encrypted: i=1; AJvYcCUpNMjKqd6rJwakGspHCubE3IzQuAed/ExIdrOIAF9ZYyz8mDbkUOUqFO6T8T6utYZpXRMaXUXtSNtNj7c=@vger.kernel.org X-Gm-Message-State: AOJu0YxEI5UmHRlj9JgEiZ/NQlHlIqiNaiRm+KJefjv0bZaLxl0hIpd+ YUjdVmz2E9iYBatcmHVtltaMZqKaT2RdUMW4CapwkjSkz42qfKZtYmjV X-Gm-Gg: AZuq6aKaSpGUS4AZv7rdYg9MVc4aKjgCqDp8GaLxMW6KQOeH5bUMnBNP3jeNYzohWcf 3YasEGSW7y8D3Nm98SjuPFORllKPtAibJYJMELI8jzpbYbMI5uwne8UpsmNFqivUVYhmClqItR1 OR7tCLqX7x03XMQR+kP4cr91R+nAcgwhKGY9Twl8X9qz+VP4Wwg1VTtq/++a0WWpGx+1EHPshYd 5QtN+BjNNDGZhYRGOeJiy8eUAMRb02LpIz7sNRs0kG+uBbERH9fX8C7Jv0uUfmUb+PEwZX29RM8 clEngmxZhi0aHg3dIGupPmJbnoXhHwIM1aUmPWZ4pXSXOQlDmlLkkg/R8dh+ks846pVVyr/MWGj P8HYw/GwV2GyrTbCpkwHOi1p4/TBWJKv1w8g+83q8pQveZErvGQvf0hBH7D+vKgIDr1jIQjovLR lc3DGGshZMgPger7/4Yqm8sLuVuQLH2ByjigY3a0D50cvg/tXnqSflmAKszOtjN6cQvSCRlCU= X-Received: by 2002:a05:7300:3254:b0:2b0:bd77:7ba2 with SMTP id 5a478bee46e88-2b6b4e99646mr8575481eec.35.1768890551789; Mon, 19 Jan 2026 22:29:11 -0800 (PST) Received: from zcache.home.zacbowling.com ([2001:5a8:60d:bc9:f31e:1cb:296a:cc2a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b3502c91sm15706784eec.9.2026.01.19.22.29.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 22:29:11 -0800 (PST) Sender: Zac Bowling From: Zac To: sean.wang@kernel.org Cc: deren.wu@mediatek.com, kvalo@kernel.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-wireless@vger.kernel.org, lorenzo@kernel.org, nbd@nbd.name, ryder.lee@mediatek.com, sean.wang@mediatek.com, stable@vger.kernel.org, linux@frame.work, zbowling@gmail.com, Zac Bowling Subject: [PATCH 11/11] wifi: mt76: mt7925: fix ROC deadlocks and race conditions Date: Mon, 19 Jan 2026 22:28:54 -0800 Message-ID: <20260120062854.126501-12-zac@zacbowling.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260120062854.126501-1-zac@zacbowling.com> References: <20260120062854.126501-1-zac@zacbowling.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Zac Bowling Fix multiple interrelated issues in the remain-on-channel (ROC) handling that cause deadlocks, race conditions, and resource leaks. Problems fixed: 1. Deadlock in sta removal ROC abort path: When a station is removed while a ROC operation is in progress, the driver would call mt7925_roc_abort_sync() which waits for ROC completion. However, the ROC work itself needs to acquire mt792x_mutex which is already held during station removal, causing a deadlock. Fix: Use async ROC abort (mt76_connac_mcu_abort_roc) when called from paths that already hold the mutex, and add MT76_STATE_ROC_ABORT flag to coordinate between the abort and the ROC timer. 2. ROC timer race during suspend: The ROC timer could fire after the device started suspending but before the ROC was properly aborted, causing undefined behavior. Fix: Delete ROC timer synchronously before suspend and check device state before processing ROC timeout. 3. ROC rate limiting for MLO auth failures: Rapid ROC requests during MLO authentication can overwhelm the firmware, causing authentication timeouts. The MT7925 firmware has limited ROC handling capacity. Fix: Add rate limiting infrastructure with configurable minimum interval between ROC requests. Track last ROC completion time and defer new requests if they arrive too quickly. 4. WCID leak in ROC cleanup: When ROC operations are aborted, the associated WCID resources were not being properly released, causing resource exhaustion over time. Fix: Ensure WCID cleanup happens in all ROC termination paths. 5. Async ROC abort race condition: The async ROC abort could race with normal ROC completion, causing double-free or use-after-free of ROC resources. Fix: Use MT76_STATE_ROC_ABORT flag and proper synchronization to prevent races between async abort and normal completion paths. These fixes work together to provide robust ROC handling that doesn't deadlock, properly releases resources, and handles edge cases during suspend and MLO operations. Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt= 7925 device") Signed-off-by: Zac Bowling --- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt7925/main.c | 175 ++++++++++++++++-- drivers/net/wireless/mediatek/mt76/mt792x.h | 7 + 3 files changed, 170 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wirele= ss/mediatek/mt76/mt76.h index d05e83ea1cac..91f9dd95c89e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -511,6 +511,7 @@ enum { MT76_STATE_POWER_OFF, MT76_STATE_SUSPEND, MT76_STATE_ROC, + MT76_STATE_ROC_ABORT, MT76_STATE_PM, MT76_STATE_WED_RESET, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net= /wireless/mediatek/mt76/mt7925/main.c index cc7ef2c17032..2404f7812897 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -453,6 +453,24 @@ static void mt7925_roc_iter(void *priv, u8 *mac, mt7925_mcu_abort_roc(phy, &mvif->bss_conf, phy->roc_token_id); } =20 +/* Async ROC abort - safe to call while holding mutex. + * Sets abort flag and lets roc_work handle cleanup without blocking. + * This prevents deadlock when called from sta_remove path which holds mut= ex. + */ +static void mt7925_roc_abort_async(struct mt792x_dev *dev) +{ + struct mt792x_phy *phy =3D &dev->phy; + + /* Set abort flag - roc_work checks this before acquiring mutex */ + set_bit(MT76_STATE_ROC_ABORT, &phy->mt76->state); + + /* Stop timer and schedule work to handle cleanup. + * Must schedule work since timer may not have fired yet. + */ + timer_delete(&phy->roc_timer); + ieee80211_queue_work(phy->mt76->hw, &phy->roc_work); +} + void mt7925_roc_abort_sync(struct mt792x_dev *dev) { struct mt792x_phy *phy =3D &dev->phy; @@ -473,6 +491,17 @@ void mt7925_roc_work(struct work_struct *work) phy =3D (struct mt792x_phy *)container_of(work, struct mt792x_phy, roc_work); =20 + /* Check abort flag BEFORE acquiring mutex to prevent deadlock. + * If abort is requested while we're in the sta_remove path (which + * holds the mutex), we must not try to acquire it or we'll deadlock. + * Clear the flags and only notify mac80211 if ROC was actually active. + */ + if (test_and_clear_bit(MT76_STATE_ROC_ABORT, &phy->mt76->state)) { + if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) + ieee80211_remain_on_channel_expired(phy->mt76->hw); + return; + } + if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) return; =20 @@ -500,14 +529,93 @@ static int mt7925_abort_roc(struct mt792x_phy *phy, return err; } =20 +/* ROC rate limiting constants - exponential backoff to prevent MCU overlo= ad + * when upper layers trigger rapid reconnection cycles (e.g., MLO auth fai= lures). + * Max backoff ~1.6s, resets after 10s of no timeouts. + */ +#define MT7925_ROC_BACKOFF_BASE_MS 100 +#define MT7925_ROC_BACKOFF_MAX_MS 1600 +#define MT7925_ROC_TIMEOUT_RESET_MS 10000 +#define MT7925_ROC_TIMEOUT_WARN_THRESH 5 + +/* Check if ROC should be throttled due to recent timeouts. + * Returns delay in jiffies if throttling, 0 if OK to proceed. + */ +static unsigned long mt7925_roc_throttle_check(struct mt792x_phy *phy) +{ + unsigned long now =3D jiffies; + + /* Reset timeout counter if it's been a while since last timeout */ + if (phy->roc_timeout_count && + time_after(now, phy->roc_last_timeout + + msecs_to_jiffies(MT7925_ROC_TIMEOUT_RESET_MS))) { + phy->roc_timeout_count =3D 0; + phy->roc_backoff_until =3D 0; + } + + /* Check if we're still in backoff period */ + if (phy->roc_backoff_until && time_before(now, phy->roc_backoff_until)) + return phy->roc_backoff_until - now; + + return 0; +} + +/* Record ROC timeout and calculate backoff period */ +static void mt7925_roc_record_timeout(struct mt792x_phy *phy) +{ + unsigned int backoff_ms; + + phy->roc_last_timeout =3D jiffies; + phy->roc_timeout_count++; + + /* Exponential backoff: 100ms, 200ms, 400ms, 800ms, 1600ms (capped) */ + backoff_ms =3D MT7925_ROC_BACKOFF_BASE_MS << + min_t(u8, phy->roc_timeout_count - 1, 4); + if (backoff_ms > MT7925_ROC_BACKOFF_MAX_MS) + backoff_ms =3D MT7925_ROC_BACKOFF_MAX_MS; + + phy->roc_backoff_until =3D jiffies + msecs_to_jiffies(backoff_ms); + + /* Warn if we're seeing repeated timeouts - likely upper layer issue */ + if (phy->roc_timeout_count =3D=3D MT7925_ROC_TIMEOUT_WARN_THRESH) + dev_warn(phy->dev->mt76.dev, + "mt7925: %u consecutive ROC timeouts, possible mac80211/wpa_supplicant= issue (MLO key race?)\n", + phy->roc_timeout_count); +} + +/* Clear timeout tracking on successful ROC */ +static void mt7925_roc_clear_timeout(struct mt792x_phy *phy) +{ + phy->roc_timeout_count =3D 0; + phy->roc_backoff_until =3D 0; +} + static int mt7925_set_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf, struct ieee80211_channel *chan, int duration, enum mt7925_roc_req type) { + unsigned long throttle; int err; =20 + /* Check rate limiting - if in backoff period, wait or return busy */ + throttle =3D mt7925_roc_throttle_check(phy); + if (throttle) { + /* For short backoffs, wait; for longer ones, return busy */ + if (throttle < msecs_to_jiffies(200)) { + msleep(jiffies_to_msecs(throttle)); + } else { + dev_dbg(phy->dev->mt76.dev, + "mt7925: ROC throttled, %lu ms remaining\n", + jiffies_to_msecs(throttle)); + return -EBUSY; + } + } + + /* Clear stale abort flag from previous ROC */ + clear_bit(MT76_STATE_ROC_ABORT, &phy->mt76->state); + if (test_and_set_bit(MT76_STATE_ROC, &phy->mt76->state)) return -EBUSY; =20 @@ -523,7 +631,11 @@ static int mt7925_set_roc(struct mt792x_phy *phy, if (!wait_event_timeout(phy->roc_wait, phy->roc_grant, 4 * HZ)) { mt7925_mcu_abort_roc(phy, mconf, phy->roc_token_id); clear_bit(MT76_STATE_ROC, &phy->mt76->state); + mt7925_roc_record_timeout(phy); err =3D -ETIMEDOUT; + } else { + /* Successful ROC - reset timeout tracking */ + mt7925_roc_clear_timeout(phy); } =20 out: @@ -534,8 +646,27 @@ static int mt7925_set_mlo_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf, u16 sel_links) { + unsigned long throttle; int err; =20 + /* Check rate limiting - MLO ROC is especially prone to rapid-fire + * during reconnection cycles after MLO authentication failures. + */ + throttle =3D mt7925_roc_throttle_check(phy); + if (throttle) { + if (throttle < msecs_to_jiffies(200)) { + msleep(jiffies_to_msecs(throttle)); + } else { + dev_dbg(phy->dev->mt76.dev, + "mt7925: MLO ROC throttled, %lu ms remaining\n", + jiffies_to_msecs(throttle)); + return -EBUSY; + } + } + + /* Clear stale abort flag from previous ROC */ + clear_bit(MT76_STATE_ROC_ABORT, &phy->mt76->state); + if (WARN_ON_ONCE(test_and_set_bit(MT76_STATE_ROC, &phy->mt76->state))) return -EBUSY; =20 @@ -550,7 +681,10 @@ static int mt7925_set_mlo_roc(struct mt792x_phy *phy, if (!wait_event_timeout(phy->roc_wait, phy->roc_grant, 4 * HZ)) { mt7925_mcu_abort_roc(phy, mconf, phy->roc_token_id); clear_bit(MT76_STATE_ROC, &phy->mt76->state); + mt7925_roc_record_timeout(phy); err =3D -ETIMEDOUT; + } else { + mt7925_roc_clear_timeout(phy); } =20 out: @@ -567,6 +701,7 @@ static int mt7925_remain_on_channel(struct ieee80211_hw= *hw, struct mt792x_phy *phy =3D mt792x_hw_phy(hw); int err; =20 + cancel_work_sync(&phy->roc_work); mt792x_mutex_acquire(phy->dev); err =3D mt7925_set_roc(phy, &mvif->bss_conf, chan, duration, MT7925_ROC_REQ_ROC); @@ -874,14 +1009,14 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *= mdev, if (!mlink) return -EINVAL; =20 - idx =3D mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1); - if (idx < 0) - return -ENOSPC; - mconf =3D mt792x_vif_to_link(mvif, link_id); if (!mconf) return -EINVAL; =20 + idx =3D mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1); + if (idx < 0) + return -ENOSPC; + mt76_wcid_init(&mlink->wcid, 0); mlink->wcid.sta =3D 1; mlink->wcid.idx =3D idx; @@ -901,14 +1036,16 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *= mdev, =20 ret =3D mt76_connac_pm_wake(&dev->mphy, &dev->pm); if (ret) - return ret; + goto err_wcid; =20 mt7925_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); =20 link_conf =3D mt792x_vif_to_bss_conf(vif, link_id); - if (!link_conf) - return -EINVAL; + if (!link_conf) { + ret =3D -EINVAL; + goto err_wcid; + } =20 /* should update bss info before STA add */ if (vif->type =3D=3D NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { @@ -920,7 +1057,7 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *md= ev, ret =3D mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf, link_sta, false); if (ret) - return ret; + goto err_wcid; } =20 if (ieee80211_vif_is_mld(vif) && @@ -928,28 +1065,34 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *= mdev, ret =3D mt7925_mcu_sta_update(dev, link_sta, vif, true, MT76_STA_INFO_STATE_NONE); if (ret) - return ret; + goto err_wcid; } else if (ieee80211_vif_is_mld(vif) && link_sta !=3D mlink->pri_link) { ret =3D mt7925_mcu_sta_update(dev, mlink->pri_link, vif, true, MT76_STA_INFO_STATE_ASSOC); if (ret) - return ret; + goto err_wcid; =20 ret =3D mt7925_mcu_sta_update(dev, link_sta, vif, true, MT76_STA_INFO_STATE_ASSOC); if (ret) - return ret; + goto err_wcid; } else { ret =3D mt7925_mcu_sta_update(dev, link_sta, vif, true, MT76_STA_INFO_STATE_NONE); if (ret) - return ret; + goto err_wcid; } =20 mt76_connac_power_save_sched(&dev->mphy, &dev->pm); =20 return 0; + +err_wcid: + rcu_assign_pointer(dev->mt76.wcid[idx], NULL); + mt76_wcid_mask_clear(dev->mt76.wcid_mask, idx); + mt76_connac_power_save_sched(&dev->mphy, &dev->pm); + return ret; } =20 static int @@ -1135,7 +1278,8 @@ static void mt7925_mac_link_sta_remove(struct mt76_de= v *mdev, if (!mlink) return; =20 - mt7925_roc_abort_sync(dev); + /* Async abort - caller already holds mutex */ + mt7925_roc_abort_async(dev); =20 mt76_connac_free_pending_tx_skbs(&dev->pm, &mlink->wcid); mt76_connac_pm_wake(&dev->mphy, &dev->pm); @@ -1530,6 +1674,8 @@ static int mt7925_suspend(struct ieee80211_hw *hw, cancel_delayed_work_sync(&dev->pm.ps_work); mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); =20 + /* Cancel ROC before quiescing starts */ + mt7925_roc_abort_sync(dev); mt792x_mutex_acquire(dev); =20 clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); @@ -1876,6 +2022,8 @@ static void mt7925_mgd_prepare_tx(struct ieee80211_hw= *hw, u16 duration =3D info->duration ? info->duration : jiffies_to_msecs(HZ); =20 + cancel_work_sync(&mvif->phy->roc_work); + mt792x_mutex_acquire(dev); mt7925_set_roc(mvif->phy, &mvif->bss_conf, mvif->bss_conf.mt76.ctx->def.chan, duration, @@ -2033,6 +2181,7 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, stru= ct ieee80211_vif *vif, if (old_links =3D=3D new_links) return 0; =20 + cancel_work_sync(&phy->roc_work); mt792x_mutex_acquire(dev); =20 for_each_set_bit(link_id, &rem, IEEE80211_MLD_MAX_NUM_LINKS) { diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wire= less/mediatek/mt76/mt792x.h index 8388638ed550..d9c1ea709390 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -186,6 +186,13 @@ struct mt792x_phy { wait_queue_head_t roc_wait; u8 roc_token_id; bool roc_grant; + + /* ROC rate limiting to prevent MCU overload during rapid reconnection + * cycles (e.g., MLO authentication failures causing repeated ROC). + */ + u8 roc_timeout_count; /* consecutive ROC timeouts */ + unsigned long roc_last_timeout; /* jiffies of last timeout */ + unsigned long roc_backoff_until;/* don't issue ROC until this time */ }; =20 struct mt792x_irq_map { --=20 2.52.0