blob: d7deb35a47437f973df89edecbe496d02c241f8e [file] [log] [blame]
From 98998425cb0089e60f7172552f8231814736e921 Mon Sep 17 00:00:00 2001
From: Evelyn Tsai <evelyn.tsai@mediatek.com>
Date: Thu, 18 May 2023 18:02:17 +0800
Subject: [PATCH 3/6] 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 | 148 +++++++++++++++++++++++++++---------------------
mt7915/mac.c | 17 +++++-
mt7915/mt7915.h | 1 +
4 files changed, 103 insertions(+), 69 deletions(-)
diff --git a/dma.c b/dma.c
index 465190e..05d9ab3 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 86a93de..4c8cf0c 100644
--- a/mt7915/dma.c
+++ b/mt7915/dma.c
@@ -250,12 +250,90 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst)
}
}
-static int mt7915_dma_enable(struct mt7915_dev *dev)
+int __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_mt798x(&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);
+
+ return 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,69 +400,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_mt798x(&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);
-
- return 0;
+ return __mt7915_dma_enable(dev, reset, true);
}
int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
@@ -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 fb6bab8..7be1e17 100644
--- a/mt7915/mac.c
+++ b/mt7915/mac.c
@@ -1574,6 +1574,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_mt798x(&dev->mt76))
@@ -1611,6 +1613,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)
@@ -1625,9 +1633,6 @@ void mt7915_mac_reset_work(struct work_struct *work)
tasklet_schedule(&dev->mt76.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();
@@ -1649,6 +1654,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 */
@@ -1723,6 +1730,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 9c79eff..d1715ff 100644
--- a/mt7915/mt7915.h
+++ b/mt7915/mt7915.h
@@ -472,6 +472,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);
+int __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