OSDN Git Service

wifi: mt76: mt7915: disable WFDMA Tx/Rx during SER recovery
authorBo Jiao <Bo.Jiao@mediatek.com>
Mon, 22 May 2023 18:49:53 +0000 (02:49 +0800)
committerFelix Fietkau <nbd@nbd.name>
Tue, 25 Jul 2023 19:59:41 +0000 (21:59 +0200)
Stop WFDMA transaction to avoid potential unexpected issue while doing
system recovery.

Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/dma.c
drivers/net/wireless/mediatek/mt76/mt7915/dma.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h

index 465190e..05d9ab3 100644 (file)
@@ -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;
index 86a93de..59a44d7 100644 (file)
@@ -250,7 +250,7 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst)
        }
 }
 
-static int mt7915_dma_enable(struct mt7915_dev *dev)
+int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset)
 {
        struct mt76_dev *mdev = &dev->mt76;
        u32 hif1_ofs = 0;
@@ -259,6 +259,84 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
        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);
+
        /* reset dma idx */
        mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
        if (is_mt7915(mdev))
@@ -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_start(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;
 }
index 4226fd4..2bc2fef 100644 (file)
@@ -1407,8 +1407,12 @@ mt7915_mac_restart(struct mt7915_dev *dev)
 
        if (dev_is_pci(mdev->dev)) {
                mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
-               if (dev->hif2)
-                       mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
+               if (dev->hif2) {
+                       if (is_mt7915(mdev))
+                               mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
+                       else
+                               mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0x0);
+               }
        }
 
        set_bit(MT76_RESET, &dev->mphy.state);
@@ -1458,8 +1462,12 @@ mt7915_mac_restart(struct mt7915_dev *dev)
        }
        if (dev_is_pci(mdev->dev)) {
                mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
-               if (dev->hif2)
-                       mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
+               if (dev->hif2) {
+                       if (is_mt7915(mdev))
+                               mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
+                       else
+                               mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff);
+               }
        }
 
        /* load firmware */
@@ -1629,6 +1637,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_start(dev, false, false);
+
        clear_bit(MT76_MCU_RESET, &dev->mphy.state);
        clear_bit(MT76_RESET, &dev->mphy.state);
        if (phy2)
@@ -1643,9 +1657,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();
index 0b8380b..93b536e 100644 (file)
@@ -411,6 +411,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_start(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);