]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerFelix Fietkau <nbd@nbd.name>
Mon, 24 Nov 2025 13:59:12 +0000 (14:59 +0100)
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>
drivers/net/wireless/mediatek/mt76/mt7996/dma.c
drivers/net/wireless/mediatek/mt76/mt7996/init.c

index 7ac4defca29db4d6ed117f8b05fc59f33b4e3e10..274b273df1ee941e83db2bf2f9771cbdd4da8b6f 100644 (file)
@@ -515,12 +515,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 bd7b720c64c5264fe6731b685a259fe3bf5e6353..00a8286bd136862d756706d6ad8098a2ddc3ca4e 100644 (file)
@@ -960,9 +960,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)
@@ -971,7 +972,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)
@@ -1037,6 +1038,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;