[][mac80211][mt76][stop dma tx in ser flow]

[Description]
Add stop dma tx in ser flow patch for ser hang issue
Add ctxd support

[Release-log]
N/A


Change-Id: I3aac447878e323ed190ceff0ce0333d7151a8cf8
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7361086
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch
new file mode 100644
index 0000000..751687b
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch
@@ -0,0 +1,290 @@
+From 96866c5d7d33633c450df65f2154789aca683311 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Tue, 11 Apr 2023 10:56:17 +0800
+Subject: [PATCH 3/3] wifi: mt76: mt7915: disable wfdma tx/rx during SER
+ recovery.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ dma.c           |   6 ++
+ mt7915/dma.c    | 144 +++++++++++++++++++++++++++---------------------
+ mt7915/mac.c    |  17 +++++-
+ mt7915/mt7915.h |   1 +
+ 4 files changed, 101 insertions(+), 67 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index df2ca73..c22ea64 100644
+--- a/dma.c
++++ b/dma.c
+@@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+ 	struct mt76_queue_buf buf = {};
+ 	dma_addr_t addr;
+ 
++	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
++		goto error;
++
+ 	if (q->queued + 1 >= q->ndesc - 1)
+ 		goto error;
+ 
+@@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+ 	dma_addr_t addr;
+ 	u8 *txwi;
+ 
++	if (test_bit(MT76_RESET, &dev->phy.state))
++		goto free_skb;
++
+ 	t = mt76_get_txwi(dev);
+ 	if (!t)
+ 		goto free_skb;
+diff --git a/mt7915/dma.c b/mt7915/dma.c
+index 43a5456..3b8a2ab 100644
+--- a/mt7915/dma.c
++++ b/mt7915/dma.c
+@@ -250,12 +250,88 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst)
+ 	}
+ }
+ 
+-static int mt7915_dma_enable(struct mt7915_dev *dev)
++void __mt7915_dma_enable(struct mt7915_dev *dev, bool reset, bool wed_reset)
+ {
+ 	struct mt76_dev *mdev = &dev->mt76;
+ 	u32 hif1_ofs = 0;
+ 	u32 irq_mask;
+ 
++	if (dev->hif2)
++		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++	/* enable wpdma tx/rx */
++	if (!reset) {
++		mt76_set(dev, MT_WFDMA0_GLO_CFG,
++			MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++			MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++			MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++			MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++		if (is_mt7915(mdev))
++			mt76_set(dev, MT_WFDMA1_GLO_CFG,
++				MT_WFDMA1_GLO_CFG_TX_DMA_EN |
++				MT_WFDMA1_GLO_CFG_RX_DMA_EN |
++				MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
++				MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
++
++		if (dev->hif2) {
++			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
++				MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++				MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++				MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++				MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++			if (is_mt7915(mdev))
++				mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
++					MT_WFDMA1_GLO_CFG_TX_DMA_EN |
++					MT_WFDMA1_GLO_CFG_RX_DMA_EN |
++					MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
++					MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
++
++			mt76_set(dev, MT_WFDMA_HOST_CONFIG,
++				MT_WFDMA_HOST_CONFIG_PDMA_BAND);
++		}
++	}
++
++	/* enable interrupts for TX/RX rings */
++	irq_mask = MT_INT_RX_DONE_MCU |
++		   MT_INT_TX_DONE_MCU |
++		   MT_INT_MCU_CMD;
++
++	if (!dev->phy.mt76->band_idx)
++		irq_mask |= MT_INT_BAND0_RX_DONE;
++
++	if (dev->dbdc_support || dev->phy.mt76->band_idx)
++		irq_mask |= MT_INT_BAND1_RX_DONE;
++
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
++		u32 wed_irq_mask = irq_mask;
++		int ret;
++
++		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
++		if (!is_mt7986(&dev->mt76))
++			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
++		else
++			mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++
++		ret = mt7915_mcu_wed_enable_rx_stats(dev);
++		if (ret)
++			return ret;
++
++		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
++	}
++
++	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
++
++	mt7915_irq_enable(dev, irq_mask);
++	mt7915_irq_disable(dev, 0);
++}
++
++static int mt7915_dma_enable(struct mt7915_dev *dev, bool reset)
++{
++	struct mt76_dev *mdev = &dev->mt76;
++	u32 hif1_ofs = 0;
++
+ 	if (dev->hif2)
+ 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+ 
+@@ -322,67 +398,7 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
+ 	mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
+ 		  MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
+ 
+-	/* set WFDMA Tx/Rx */
+-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
+-		 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+-		 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+-		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+-		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+-	if (is_mt7915(mdev))
+-		mt76_set(dev, MT_WFDMA1_GLO_CFG,
+-			 MT_WFDMA1_GLO_CFG_TX_DMA_EN |
+-			 MT_WFDMA1_GLO_CFG_RX_DMA_EN |
+-			 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
+-			 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
+-
+-	if (dev->hif2) {
+-		mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
+-			 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+-			 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+-			 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+-			 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+-		if (is_mt7915(mdev))
+-			mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
+-				 MT_WFDMA1_GLO_CFG_TX_DMA_EN |
+-				 MT_WFDMA1_GLO_CFG_RX_DMA_EN |
+-				 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
+-				 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
+-
+-		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
+-			 MT_WFDMA_HOST_CONFIG_PDMA_BAND);
+-	}
+-
+-	/* enable interrupts for TX/RX rings */
+-	irq_mask = MT_INT_RX_DONE_MCU |
+-		   MT_INT_TX_DONE_MCU |
+-		   MT_INT_MCU_CMD;
+-
+-	if (!dev->phy.mt76->band_idx)
+-		irq_mask |= MT_INT_BAND0_RX_DONE;
+-
+-	if (dev->dbdc_support || dev->phy.mt76->band_idx)
+-		irq_mask |= MT_INT_BAND1_RX_DONE;
+-
+-	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+-		u32 wed_irq_mask = irq_mask;
+-		int ret;
+-
+-		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
+-		if (!is_mt7986(&dev->mt76))
+-			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
+-		else
+-			mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+-
+-		ret = mt7915_mcu_wed_enable_rx_stats(dev);
+-		if (ret)
+-			return ret;
+-
+-		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
+-	}
+-
+-	mt7915_irq_enable(dev, irq_mask);
++	__mt7915_dma_enable(dev, reset, true);
+ 
+ 	return 0;
+ }
+@@ -560,7 +576,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ 			  mt7915_poll_tx);
+ 	napi_enable(&dev->mt76.tx_napi);
+ 
+-	mt7915_dma_enable(dev);
++	mt7915_dma_enable(dev, false);
+ 
+ 	return 0;
+ }
+@@ -642,7 +658,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
+ 		mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP,
+ 			 MT_WFDMA0_EXT0_RXWB_KEEP);
+ 
+-	mt7915_dma_enable(dev);
++	mt7915_dma_enable(dev, !force);
+ 
+ 	return 0;
+ }
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index 97ca55d..f1fdcfd 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -1578,6 +1578,8 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 	if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA))
+ 		return;
+ 
++	dev_info(dev->mt76.dev,"%s L1 SER recovery start.\n",
++		 wiphy_name(dev->mt76.hw->wiphy));
+ 	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ 		mtk_wed_device_stop(&dev->mt76.mmio.wed);
+ 		if (!is_mt7986(&dev->mt76))
+@@ -1615,6 +1617,12 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 		mt7915_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
+ 	}
+ 
++	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
++	mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
++
++	/* enable dma tx/rx and interrupt */
++	__mt7915_dma_enable(dev, false, false);
++
+ 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ 	clear_bit(MT76_RESET, &dev->mphy.state);
+ 	if (phy2)
+@@ -1629,9 +1637,6 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 
+ 	tasklet_schedule(&dev->irq_tasklet);
+ 
+-	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
+-	mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+-
+ 	mt76_worker_enable(&dev->mt76.tx_worker);
+ 
+ 	local_bh_disable();
+@@ -1653,6 +1658,8 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 		ieee80211_queue_delayed_work(ext_phy->hw,
+ 					     &phy2->mt76->mac_work,
+ 					     MT7915_WATCHDOG_TIME);
++	dev_info(dev->mt76.dev,"%s L1 SER recovery completed.\n",
++		 wiphy_name(dev->mt76.hw->wiphy));
+ }
+ 
+ /* firmware coredump */
+@@ -1727,6 +1734,10 @@ skip_coredump:
+ 
+ void mt7915_reset(struct mt7915_dev *dev)
+ {
++	dev_info(dev->mt76.dev, "%s SER recovery state: 0x%08x\n",
++		 wiphy_name(dev->mt76.hw->wiphy),
++		 READ_ONCE(dev->recovery.state));
++
+ 	if (!dev->recovery.hw_init_done)
+ 		return;
+ 
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index b66938b..376256d 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -481,6 +481,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2);
+ void mt7915_dma_prefetch(struct mt7915_dev *dev);
+ void mt7915_dma_cleanup(struct mt7915_dev *dev);
+ int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
++void __mt7915_dma_enable(struct mt7915_dev *dev, bool reset, bool wed_reset);
+ int mt7915_txbf_init(struct mt7915_dev *dev);
+ void mt7915_init_txpower(struct mt7915_dev *dev,
+ 			 struct ieee80211_supported_band *sband);
+-- 
+2.18.0
+