Patch "wifi: mt76: mt7921e: improve reliability of dma reset" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    wifi: mt76: mt7921e: improve reliability of dma reset

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     wifi-mt76-mt7921e-improve-reliability-of-dma-reset.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit cb4a79e355f8ea84a519e008ea9dbe7f368782a0
Author: Quan Zhou <quan.zhou@xxxxxxxxxxxx>
Date:   Thu Apr 13 05:11:13 2023 +0800

    wifi: mt76: mt7921e: improve reliability of dma reset
    
    [ Upstream commit 87714bf6ed1589813e473db5471e6e9857755764 ]
    
    The hardware team has advised the driver that it is necessary to first put
    WFDMA into an idle state before resetting the WFDMA. Otherwise, the WFDMA
    may enter an unknown state where it cannot be polled with the right state
    successfully. To ensure that the DMA can work properly while a stressful
    cold reboot test was being made, we have reordered the programming sequence
    in the driver based on the hardware team's guidance.
    
    The patch would modify the WFDMA disabling flow from
    
    "DMA reset -> disabling DMASHDL -> disabling WFDMA -> polling and waiting
    until DMA idle" to "disabling WFDMA -> polling and waiting for DMA idle ->
    disabling DMASHDL -> DMA reset.
    
    Where he polling and waiting until WFDMA is idle is coordinated with the
    operation of disabling WFDMA. Even while WFDMA is being disabled, it can
    still handle Tx/Rx requests. The additional polling allows sufficient time
    for WFDMA to process the last T/Rx request. When the idle state of WFDMA is
    reached, it is a reliable indication that DMASHDL is also idle to ensure it
    is safe to disable it and perform the DMA reset.
    
    Fixes: 0a1059d0f060 ("mt76: mt7921: move mt7921_dma_reset in dma.c")
    Co-developed-by: Sean Wang <sean.wang@xxxxxxxxxxxx>
    Signed-off-by: Sean Wang <sean.wang@xxxxxxxxxxxx>
    Co-developed-by: Deren Wu <deren.wu@xxxxxxxxxxxx>
    Signed-off-by: Deren Wu <deren.wu@xxxxxxxxxxxx>
    Co-developed-by: Wang Zhao <wang.zhao@xxxxxxxxxxxx>
    Signed-off-by: Wang Zhao <wang.zhao@xxxxxxxxxxxx>
    Signed-off-by: Quan Zhou <quan.zhou@xxxxxxxxxxxx>
    Signed-off-by: Felix Fietkau <nbd@xxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index 7e39bcfdb0b7a..983861edc6834 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -120,22 +120,6 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev)
 
 static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
 {
-	if (force) {
-		/* reset */
-		mt76_clear(dev, MT_WFDMA0_RST,
-			   MT_WFDMA0_RST_DMASHDL_ALL_RST |
-			   MT_WFDMA0_RST_LOGIC_RST);
-
-		mt76_set(dev, MT_WFDMA0_RST,
-			 MT_WFDMA0_RST_DMASHDL_ALL_RST |
-			 MT_WFDMA0_RST_LOGIC_RST);
-	}
-
-	/* disable dmashdl */
-	mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
-		   MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
-	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
-
 	/* disable WFDMA0 */
 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
 		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
@@ -149,6 +133,22 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
 				 MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
 		return -ETIMEDOUT;
 
+	/* disable dmashdl */
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
+		   MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
+	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
+
+	if (force) {
+		/* reset */
+		mt76_clear(dev, MT_WFDMA0_RST,
+			   MT_WFDMA0_RST_DMASHDL_ALL_RST |
+			   MT_WFDMA0_RST_LOGIC_RST);
+
+		mt76_set(dev, MT_WFDMA0_RST,
+			 MT_WFDMA0_RST_DMASHDL_ALL_RST |
+			 MT_WFDMA0_RST_LOGIC_RST);
+	}
+
 	return 0;
 }
 
@@ -354,6 +354,10 @@ void mt7921_dma_cleanup(struct mt7921_dev *dev)
 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
 
+	mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
+			    MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
+			    MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1);
+
 	/* reset */
 	mt76_clear(dev, MT_WFDMA0_RST,
 		   MT_WFDMA0_RST_DMASHDL_ALL_RST |



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux