]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: mt76: mt7996: fix EMI rings for RRO
authorShayne Chen <shayne.chen@mediatek.com>
Thu, 6 Nov 2025 06:42:03 +0000 (14:42 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Dec 2025 13:03:15 +0000 (14:03 +0100)
[ Upstream commit a4031fec9d0d230224a7edcefa3368c06c317148 ]

The RRO EMI rings only need to be allocated when WED is not active.
This patch fixes command timeout issue for the setting of WED off and
RRO on.

Fixes: 3a29164425e9 ("wifi: mt76: mt7996: Add SW path for HW-RRO v3.1")
Co-developed-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20251106064203.1000505-12-shayne.chen@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/mediatek/mt76/mt7996/dma.c
drivers/net/wireless/mediatek/mt76/mt7996/init.c

index 659015f93d3238ba3b3c3779f4baa8f4b46b22e7..7ed2f21b0e6db44e226d39d1551db793c1cfe71d 100644 (file)
@@ -512,12 +512,15 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
                if (ret)
                        return ret;
 
-               /* We need to set cpu idx pointer before resetting the EMI
-                * queues.
-                */
-               mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].emi_cpu_idx =
-                       &dev->wed_rro.emi_rings_cpu.ptr->ring[0].idx;
-               mt76_queue_reset(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C], true);
+               if (!mtk_wed_device_active(&mdev->mmio.wed)) {
+                       /* We need to set cpu idx pointer before resetting the
+                        * EMI queues.
+                        */
+                       mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].emi_cpu_idx =
+                               &dev->wed_rro.emi_rings_cpu.ptr->ring[0].idx;
+                       mt76_queue_reset(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C],
+                                        true);
+               }
                goto start_hw_rro;
        }
 
index 5e95a36b42d1645dbf63d8bf6717ac6a29a91a5c..b136b9a6697690fa3e80b3f878cdcb85d65a0e37 100644 (file)
@@ -959,9 +959,10 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
                       MT7996_RRO_MSDU_PG_SIZE_PER_CR);
        }
 
-       if (dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) {
+       if (!mtk_wed_device_active(&dev->mt76.mmio.wed) &&
+           dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) {
                ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
-                                         sizeof(dev->wed_rro.emi_rings_cpu.ptr),
+                                         sizeof(*dev->wed_rro.emi_rings_cpu.ptr),
                                          &dev->wed_rro.emi_rings_cpu.phy_addr,
                                          GFP_KERNEL);
                if (!ptr)
@@ -970,7 +971,7 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
                dev->wed_rro.emi_rings_cpu.ptr = ptr;
 
                ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
-                                         sizeof(dev->wed_rro.emi_rings_dma.ptr),
+                                         sizeof(*dev->wed_rro.emi_rings_dma.ptr),
                                          &dev->wed_rro.emi_rings_dma.phy_addr,
                                          GFP_KERNEL);
                if (!ptr)
@@ -1036,6 +1037,18 @@ static void mt7996_wed_rro_free(struct mt7996_dev *dev)
                                   dev->wed_rro.msdu_pg[i].phy_addr);
        }
 
+       if (dev->wed_rro.emi_rings_cpu.ptr)
+               dmam_free_coherent(dev->mt76.dma_dev,
+                                  sizeof(*dev->wed_rro.emi_rings_cpu.ptr),
+                                  dev->wed_rro.emi_rings_cpu.ptr,
+                                  dev->wed_rro.emi_rings_cpu.phy_addr);
+
+       if (dev->wed_rro.emi_rings_dma.ptr)
+               dmam_free_coherent(dev->mt76.dma_dev,
+                                  sizeof(*dev->wed_rro.emi_rings_dma.ptr),
+                                  dev->wed_rro.emi_rings_dma.ptr,
+                                  dev->wed_rro.emi_rings_dma.phy_addr);
+
        if (!dev->wed_rro.session.ptr)
                return;