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