[PATCH mt76 v2 12/17] wifi: mt76: mt7996: Add __mt7996_npu_hw_init routine

Lorenzo Bianconi lorenzo at kernel.org
Thu Jan 22 02:39:56 PST 2026


Introduce __mt7996_npu_hw_init utility routine in order to run it
holding mt76 mutex and move NPU hw re-initialization before restarting
the NAPIs during device reset.

Tested-by: Kang Yang <kang.yang at airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c    |  4 +--
 drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h |  6 +++++
 drivers/net/wireless/mediatek/mt76/mt7996/npu.c    | 31 +++++++++++++---------
 3 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index db2eda2f1c4c097aafc55245e523e39c7bc71e34..ebce6b080886896be746c37690ef38713fe2cbc2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -2607,6 +2607,8 @@ void mt7996_mac_reset_work(struct work_struct *work)
 				     MT_INT_TX_RX_DONE_EXT);
 	}
 
+	__mt7996_npu_hw_init(dev);
+
 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
 	mt7996_for_each_phy(dev, phy)
 		clear_bit(MT76_RESET, &phy->mt76->state);
@@ -2636,8 +2638,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
 
 	mutex_unlock(&dev->mt76.mutex);
 
-	mt7996_npu_hw_init(dev);
-
 	mt7996_for_each_phy(dev, phy)
 		ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
 					     MT7996_WATCHDOG_TIME);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index de31385aa966116b34e545de92623a214bddc8f8..3928e059fd2a41aa7d4aa41b0d303b0763384523 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -881,10 +881,16 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
 int mt7996_dma_rro_init(struct mt7996_dev *dev);
 
 #ifdef CONFIG_MT7996_NPU
+int __mt7996_npu_hw_init(struct mt7996_dev *dev);
 int mt7996_npu_hw_init(struct mt7996_dev *dev);
 int mt7996_npu_hw_stop(struct mt7996_dev *dev);
 int mt7996_npu_rx_queues_init(struct mt7996_dev *dev);
 #else
+static inline int __mt7996_npu_hw_init(struct mt7996_dev *dev)
+{
+	return 0;
+}
+
 static inline int mt7996_npu_hw_init(struct mt7996_dev *dev)
 {
 	return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/npu.c b/drivers/net/wireless/mediatek/mt76/mt7996/npu.c
index 1a77a7dc103762c8cc998508348e418858c30029..7941996891c88333d121e4c739001ea19bff94c9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/npu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/npu.c
@@ -525,20 +525,18 @@ int mt7996_npu_rx_queues_init(struct mt7996_dev *dev)
 				      &dev->mt76.q_rx[MT_RXQ_NPU1]);
 }
 
-int mt7996_npu_hw_init(struct mt7996_dev *dev)
+int __mt7996_npu_hw_init(struct mt7996_dev *dev)
 {
 	struct airoha_npu *npu;
-	int i, err = 0;
-
-	mutex_lock(&dev->mt76.mutex);
+	int i, err;
 
 	npu = rcu_dereference_protected(dev->mt76.mmio.npu, &dev->mt76.mutex);
 	if (!npu)
-		goto unlock;
+		return 0;
 
 	err = mt7996_npu_offload_init(dev, npu);
 	if (err)
-		goto unlock;
+		return err;
 
 	if (is_mt7996(&dev->mt76))
 		err = mt7996_npu_rxd_init(dev, npu);
@@ -546,27 +544,36 @@ int mt7996_npu_hw_init(struct mt7996_dev *dev)
 		err = mt7992_npu_rxd_init(dev, npu);
 
 	if (err)
-		goto unlock;
+		return err;
 
 	err = mt7996_npu_txd_init(dev, npu);
 	if (err)
-		goto unlock;
+		return err;
 
 	err = mt7996_npu_rx_event_init(dev, npu);
 	if (err)
-		goto unlock;
+		return err;
 
 	err = mt7996_npu_set_pcie_addr(dev, npu);
 	if (err)
-		goto unlock;
+		return err;
 
 	err = mt7996_npu_tx_done_init(dev, npu);
 	if (err)
-		goto unlock;
+		return err;
 
 	for (i = MT_RXQ_NPU0; i <= MT_RXQ_NPU1; i++)
 		airoha_npu_wlan_enable_irq(npu, i - MT_RXQ_NPU0);
-unlock:
+
+	return 0;
+}
+
+int mt7996_npu_hw_init(struct mt7996_dev *dev)
+{
+	int err;
+
+	mutex_lock(&dev->mt76.mutex);
+	err = __mt7996_npu_hw_init(dev);
 	mutex_unlock(&dev->mt76.mutex);
 
 	return err;

-- 
2.52.0




More information about the Linux-mediatek mailing list