[PATCH 1/2] wifi: mt76: mt7996: disable RX NAPI on driver removal
From: Goliath Zhu
Date: Fri Jul 17 2026 - 07:06:48 EST
Commit 9dd05df8403b ("net: warn if NAPI instance wasn't shut down")
made the NAPI teardown ordering explicit. An instance must be disabled
first, then netif_napi_del() removes it.
mt7996_unregister_device() leaves the RX NAPI instances enabled and
eventually calls mt76_dma_cleanup(), which deletes them. This triggers
the warning in __netif_napi_del_locked() during device removal.
Disable every RX NAPI instance owned by mt76 after unregistering the
device and before releasing the DMA resources. Skip WED RRO queues
because WED owns them and mt76 never registers NAPI for those queues.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Goliath Zhu <goliath.zhu@xxxxxxxxxxxx>
---
drivers/net/wireless/mediatek/mt76/mt7996/init.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index d6f9aa1ab..73559c60f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -1797,6 +1797,8 @@ error:
void mt7996_unregister_device(struct mt7996_dev *dev)
{
+ int i;
+
cancel_work_sync(&dev->dump_work);
cancel_work_sync(&dev->wed_rro.work);
mt7996_unregister_phy(mt7996_phy3(dev));
@@ -1804,6 +1806,15 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
mt7996_unregister_thermal(&dev->phy);
mt7996_coredump_unregister(dev);
mt76_unregister_device(&dev->mt76);
+ mt76_for_each_q_rx(&dev->mt76, i) {
+ struct mt76_queue *q = &dev->mt76.q_rx[i];
+
+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+ mt76_queue_is_wed_rro(q))
+ continue;
+
+ napi_disable(&dev->mt76.napi[i]);
+ }
mt7996_wed_rro_free(dev);
mt7996_mcu_exit(dev);
mt7996_tx_token_put(dev);
--
2.55.0