| 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 |
| |