wifi: mt76: mt7996: disable WFDMA Tx/Rx during SER recovery
authorBo Jiao <Bo.Jiao@mediatek.com>
Mon, 22 May 2023 18:49:54 +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/mt7996/dma.c
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

index 534143465d9b3471b392c716276fe6817b26f54b..99b00a13571196b7514629e782e8660be41e92eb 100644 (file)
@@ -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_start(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 WFDMA 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 void 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,23 +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);
-
-       return 0;
+       mt7996_dma_start(dev, reset);
 }
 
 int mt7996_dma_init(struct mt7996_dev *dev)
@@ -347,7 +362,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 +428,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)
index d05d7e79781f61743d828c114c700048fe9f857e..de159090331838984f297f2b4857a0c73a357c65 100644 (file)
@@ -2051,6 +2051,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/Tx and interrupt */
+       mt7996_dma_start(dev, false);
+
        clear_bit(MT76_MCU_RESET, &dev->mphy.state);
        clear_bit(MT76_RESET, &dev->mphy.state);
        if (phy2)
@@ -2067,9 +2073,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();
index 348d3ad3f9e7554a545c5c0dde4af346c76820b1..7b74477abbe3f04320686de77d79f8dcfc79837f 100644 (file)
@@ -351,6 +351,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_start(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);