blob: a88d36a38c1fcf41b27357bbf90b99ab1b5e95df [file] [log] [blame]
From d246d8300bcbf7dea19919d61df9d7553e21bd1b Mon Sep 17 00:00:00 2001
From: "sujuan.chen" <sujuan.chen@mediatek.com>
Date: Wed, 26 Apr 2023 15:37:23 +0800
Subject: [PATCH 33/39] wifi: mt76: mt7996: disable wfdma tx/rx during SER
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
---
dma.c | 6 ++++
mt7996/dma.c | 79 ++++++++++++++++++++++++++++++-------------------
mt7996/mac.c | 13 ++++++--
mt7996/mt7996.h | 1 +
4 files changed, 65 insertions(+), 34 deletions(-)
diff --git a/dma.c b/dma.c
index 465190e..f2b1b2a 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_MCU_RESET, &dev->phy.state))
+ goto free_skb;
+
t = mt76_get_txwi(dev);
if (!t)
goto free_skb;
diff --git a/mt7996/dma.c b/mt7996/dma.c
index fbedaac..6a21e3e 100644
--- a/mt7996/dma.c
+++ b/mt7996/dma.c
@@ -128,11 +128,55 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
}
}
-static int mt7996_dma_enable(struct mt7996_dev *dev)
+void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
{
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 (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);
+ }
+
+ /* enable interrupts for TX/RX rings */
+ irq_mask = MT_INT_MCU_CMD;
+ if (reset)
+ goto done;
+
+ irq_mask |= (MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU);
+
+ if (!dev->mphy.band_idx)
+ irq_mask |= MT_INT_BAND0_RX_DONE;
+
+ if (dev->dbdc_support)
+ irq_mask |= MT_INT_BAND1_RX_DONE;
+
+ if (dev->tbtc_support)
+ irq_mask |= MT_INT_BAND2_RX_DONE;
+
+done:
+ mt7996_irq_enable(dev, irq_mask);
+ mt7996_irq_disable(dev, 0);
+}
+
+static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+{
+ u32 hif1_ofs = 0;
+
if (dev->hif2)
hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
@@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_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);
-
/* GLO_CFG_EXT0 */
mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0,
WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
@@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
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);
-
/* GLO_CFG_EXT0 */
mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
@@ -216,21 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
}
- /* enable interrupts for TX/RX rings */
- irq_mask = MT_INT_RX_DONE_MCU |
- MT_INT_TX_DONE_MCU |
- MT_INT_MCU_CMD;
-
- if (!dev->mphy.band_idx)
- irq_mask |= MT_INT_BAND0_RX_DONE;
-
- if (dev->dbdc_support)
- irq_mask |= MT_INT_BAND1_RX_DONE;
-
- if (dev->tbtc_support)
- irq_mask |= MT_INT_BAND2_RX_DONE;
-
- mt7996_irq_enable(dev, irq_mask);
+ __mt7996_dma_enable(dev, reset);
return 0;
}
@@ -347,7 +364,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
mt7996_poll_tx);
napi_enable(&dev->mt76.tx_napi);
- mt7996_dma_enable(dev);
+ mt7996_dma_enable(dev, false);
return 0;
}
@@ -413,7 +430,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
mt76_for_each_q_rx(&dev->mt76, i)
mt76_queue_rx_reset(dev, i);
- mt7996_dma_enable(dev);
+ mt7996_dma_enable(dev, !force);
}
void mt7996_dma_cleanup(struct mt7996_dev *dev)
diff --git a/mt7996/mac.c b/mt7996/mac.c
index bddb84f..986031f 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
@@ -2028,6 +2028,12 @@ void mt7996_mac_reset_work(struct work_struct *work)
mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
}
+ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
+ mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+
+ /* enable dma tx/rx and interrupt */
+ __mt7996_dma_enable(dev, false);
+
clear_bit(MT76_MCU_RESET, &dev->mphy.state);
clear_bit(MT76_RESET, &dev->mphy.state);
if (phy2)
@@ -2044,9 +2050,6 @@ void mt7996_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);
- mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
-
mt76_worker_enable(&dev->mt76.tx_worker);
local_bh_disable();
@@ -2149,6 +2152,10 @@ skip_coredump:
void mt7996_reset(struct mt7996_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/mt7996/mt7996.h b/mt7996/mt7996.h
index 8e5b3c3..561c1cd 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
@@ -448,6 +448,7 @@ int mt7996_dma_init(struct mt7996_dev *dev);
void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
void mt7996_dma_prefetch(struct mt7996_dev *dev);
void mt7996_dma_cleanup(struct mt7996_dev *dev);
+void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset);
void mt7996_init_txpower(struct mt7996_dev *dev,
struct ieee80211_supported_band *sband);
int mt7996_txbf_init(struct mt7996_dev *dev);
--
2.18.0