[][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
+