From: JB Tsai <jb.tsai@mediatek.com>
To: <nbd@nbd.name>, <lorenzo@kernel.org>
Cc: <linux-wireless@vger.kernel.org>,
<linux-mediatek@lists.infradead.org>, <Sean.Wang@mediatek.com>,
<Evan-ym.Li@mediatek.com>, <jb.tsai@mediatek.com>,
Yin-Ming Li <evan-ym.li@mediatek.com>,
Sean Wang <sean.wang@mediatek.com>
Subject: [PATCH 3/3] wifi: mt76: mt7921: disable SDIO work before bus teardown
Date: Tue, 3 Nov 2026 17:10:10 +0800 [thread overview]
Message-ID: <20261103091010.1148974-3-jb.tsai@mediatek.com> (raw)
In-Reply-To: <20261103091010.1148974-1-jb.tsai@mediatek.com>
From: Yin-Ming Li <evan-ym.li@mediatek.com>
Use the common unregister helper to synchronize unsolicited events
and disable reset, MAC and PM work before mac80211 destroys its workqueue.
The existing ordered cancellation cannot permanently reject a late wake
request from the SDIO TX/RX worker before mt76s_deinit() stops it.
Keep the SDIO command transport available through mac80211 teardown and
publish REMOVED afterward. Stop all SDIO workers and release the bus IRQ
before cancelling coredump work and purging scan and coredump queues.
Skip wake requests when the TX/RX worker observes REMOVED. Permanent PM
work disabling also rejects requests already past that check while the
bus workers are being stopped.
Co-developed-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Yin-Ming Li <evan-ym.li@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt7921/sdio.c | 38 +++++++-----------------
1 file changed, 10 insertions(+), 28 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
index 1c074913b3fe35707c7186358b9713916356a3b5..012e706a6eda413045136d7c01a56990e3f74b9b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
@@ -34,7 +34,9 @@ static void mt7921s_txrx_worker(struct mt76_worker *w)
if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
/* CR6593480 debug trace (NOT for upstream) */
mt76_trc(MT76_TRC_WORKER_PM_BAIL, 0, 0);
- queue_work(mdev->wq, &dev->pm.wake_work);
+ /* The bus worker can run until mt76s_deinit(). */
+ if (!test_bit(MT76_REMOVED, &dev->mphy.state))
+ queue_work(mdev->wq, &dev->pm.wake_work);
return;
}
@@ -44,37 +46,18 @@ static void mt7921s_txrx_worker(struct mt76_worker *w)
static void mt7921s_unregister_device(struct mt792x_dev *dev)
{
- struct mt76_connac_pm *pm = &dev->pm;
-
- cancel_work_sync(&dev->init_work);
- mt76_unregister_device(&dev->mt76);
-
- /* mac80211 is gone, so no driver callback can re-arm the work items
- * below anymore. Turn mt76_connac_power_save_sched() and mt792x_reset()
- * into no-ops for the rest of the removal path, so that the RX and MCU
- * paths cannot re-arm them either. Do not set this before
- * mt76_unregister_device(): it would also stop mt76_connac_pm_wake()
- * from waking the chip up for the MCU commands the mac80211 teardown
- * still has to send.
- */
- pm->suspended = true;
-
- /* The order matters: mt7921_mac_reset_work() re-arms mac_work and
- * ps_work, and ps_work putting the chip back to sleep makes
- * mt7921s_txrx_worker() re-arm wake_work, which in turn re-arms
- * mac_work. Cancel each work item only once nothing that can re-arm it
- * is left running.
- */
- cancel_work_sync(&dev->reset_work);
- cancel_delayed_work_sync(&pm->ps_work);
- cancel_work_sync(&pm->wake_work);
- cancel_delayed_work_sync(&dev->mphy.mac_work);
- cancel_delayed_work_sync(&dev->phy.scan_work);
+ mt7921_unregister_device(dev);
+ set_bit(MT76_REMOVED, &dev->mphy.state);
mt76s_deinit(&dev->mt76);
mt7921s_wfsys_reset(dev);
skb_queue_purge(&dev->mt76.mcu.res_q);
+ /* Event producers and scan_work are stopped before purging queues. */
+ skb_queue_purge(&dev->phy.scan_event_list);
+ cancel_delayed_work_sync(&dev->coredump.work);
+ skb_queue_purge(&dev->coredump.msg_list);
+
mt76_free_device(&dev->mt76);
}
@@ -225,7 +208,6 @@ static void mt7921s_remove(struct sdio_func *func)
{
struct mt792x_dev *dev = sdio_get_drvdata(func);
- set_bit(MT76_REMOVED, &dev->mphy.state);
mt7921s_unregister_device(dev);
}
--
2.43.0
prev parent reply other threads:[~2026-11-03 9:10 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 9:10 [PATCH 1/3] wifi: mt76: mt7921: quiesce work before unregistering JB Tsai
2026-11-03 9:10 ` [PATCH 2/3] wifi: mt76: mt7921: drain PCIe activity before freeing queues JB Tsai
2026-11-03 9:10 ` JB Tsai [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103091010.1148974-3-jb.tsai@mediatek.com \
--to=jb.tsai@mediatek.com \
--cc=Evan-ym.Li@mediatek.com \
--cc=Sean.Wang@mediatek.com \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lorenzo@kernel.org \
--cc=nbd@nbd.name \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox