]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: mt7996: Integrate MT7990 dma configuration for NPU
authorLorenzo Bianconi <lorenzo@kernel.org>
Thu, 22 Jan 2026 10:39:55 +0000 (11:39 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 23 Mar 2026 09:23:00 +0000 (09:23 +0000)
Add NPU integration in MT7996 dma codebase for MT7990 chipset.
This is a preliminary patch to enable NPU offload for MT7996 (Eagle)
chipset.

Tested-by: Kang Yang <kang.yang@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260122-mt76-npu-eagle-offload-v2-11-2374614c0de6@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7996/dma.c

index 274b273df1ee941e83db2bf2f9771cbdd4da8b6f..07212d93bc62df69720963f5ba04090bc82003fc 100644 (file)
@@ -128,15 +128,27 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
 
        /* data tx queue */
        if (is_mt7996(&dev->mt76)) {
-               TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
                if (dev->hif2) {
-                       /* default bn1:ring19 bn2:ring21 */
-                       TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1,
-                                  MT7996_TXQ_BAND1);
-                       TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2,
-                                  MT7996_TXQ_BAND2);
+                       if (mt76_npu_device_active(&dev->mt76)) {
+                               TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND2,
+                                          MT7996_TXQ_BAND2);
+                               TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND0,
+                                          MT7996_TXQ_BAND0);
+                               TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND1,
+                                          MT7996_TXQ_BAND1);
+                       } else {
+                               /* default bn1:ring19 bn2:ring21 */
+                               TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,
+                                          MT7996_TXQ_BAND0);
+                               TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1,
+                                          MT7996_TXQ_BAND1);
+                               TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2,
+                                          MT7996_TXQ_BAND2);
+                       }
                } else {
                        /* single pcie bn0/1:ring18 bn2:ring19 */
+                       TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,
+                                  MT7996_TXQ_BAND0);
                        TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND1,
                                   MT7996_TXQ_BAND1);
                }
@@ -350,6 +362,9 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
        if (!mt7996_has_wa(dev) || mt76_npu_device_active(&dev->mt76))
                irq_mask &= ~(MT_INT_RX(MT_RXQ_MAIN_WA) |
                              MT_INT_RX(MT_RXQ_BAND1_WA));
+       if (is_mt7996(&dev->mt76) && mt76_npu_device_active(&dev->mt76))
+               irq_mask &= ~(MT_INT_RX(MT_RXQ_TXFREE_BAND0) |
+                             MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND2));
        irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
 
        mt7996_irq_enable(dev, irq_mask);
@@ -430,39 +445,48 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
                           MT_WFDMA_HOST_CONFIG_BAND1_PCIE1 |
                           MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
 
-               if (is_mt7996(&dev->mt76))
-                       mt76_set(dev, MT_WFDMA_HOST_CONFIG,
-                                MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
-               else
+               if (is_mt7996(&dev->mt76)) {
+                       if (mt76_npu_device_active(&dev->mt76))
+                               mt76_set(dev, MT_WFDMA_HOST_CONFIG,
+                                        MT_WFDMA_HOST_CONFIG_BAND0_PCIE1);
+                       else
+                               mt76_set(dev, MT_WFDMA_HOST_CONFIG,
+                                        MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
+               } else {
                        mt76_set(dev, MT_WFDMA_HOST_CONFIG,
                                 MT_WFDMA_HOST_CONFIG_BAND1_PCIE1);
+               }
 
                /* AXI read outstanding number */
                mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL,
                         MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK, 0x14);
 
-               if (dev->hif2->speed < PCIE_SPEED_5_0GT ||
-                   (dev->hif2->speed == PCIE_SPEED_5_0GT &&
-                    dev->hif2->width < PCIE_LNK_X2)) {
-                       mt76_rmw(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
-                                WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
-                                FIELD_PREP(WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
-                                           0x1));
-                       mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL2,
-                                MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
-                                FIELD_PREP(MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
-                                           0x1));
-               } else if (dev->hif2->speed < PCIE_SPEED_8_0GT ||
-                          (dev->hif2->speed == PCIE_SPEED_8_0GT &&
-                           dev->hif2->width < PCIE_LNK_X2)) {
-                       mt76_rmw(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
-                                WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
-                                FIELD_PREP(WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
-                                           0x2));
-                       mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL2,
-                                MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
-                                FIELD_PREP(MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
-                                           0x2));
+               if (!is_mt7996(&dev->mt76) ||
+                   !mt76_npu_device_active(&dev->mt76)) {
+                       if (dev->hif2->speed < PCIE_SPEED_5_0GT ||
+                           (dev->hif2->speed == PCIE_SPEED_5_0GT &&
+                            dev->hif2->width < PCIE_LNK_X2)) {
+                               mt76_rmw(dev,
+                                        WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
+                                        WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
+                                        FIELD_PREP(WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
+                                                   0x1));
+                               mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL2,
+                                        MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
+                                        FIELD_PREP(MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
+                                                   0x1));
+                       } else if (dev->hif2->speed < PCIE_SPEED_8_0GT ||
+                                  (dev->hif2->speed == PCIE_SPEED_8_0GT &&
+                                   dev->hif2->width < PCIE_LNK_X2)) {
+                               mt76_rmw(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
+                                        WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
+                                        FIELD_PREP(WF_WFDMA0_GLO_CFG_EXT0_OUTSTAND_MASK,
+                                                   0x2));
+                               mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL2,
+                                        MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
+                                        FIELD_PREP(MT_WFDMA_AXI_R2A_CTRL2_OUTSTAND_MASK,
+                                                   0x2));
+                       }
                }
 
                /* WFDMA rx threshold */
@@ -497,7 +521,7 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
 int mt7996_dma_rro_init(struct mt7996_dev *dev)
 {
        struct mt76_dev *mdev = &dev->mt76;
-       u32 irq_mask;
+       u32 irq_mask, size;
        int ret;
 
        if (dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) {
@@ -545,10 +569,12 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
        if (mtk_wed_device_active(&mdev->mmio.wed) &&
            mtk_wed_get_rx_capa(&mdev->mmio.wed))
                mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].wed = &mdev->mmio.wed;
+
+       size = is_mt7996(mdev) && mt76_npu_device_active(mdev)
+              ? MT7996_NPU_RX_RING_SIZE / 4 : MT7996_RX_RING_SIZE;
        ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0],
                               MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),
-                              MT7996_RX_RING_SIZE,
-                              MT7996_RX_MSDU_PAGE_SIZE,
+                              size, MT7996_RX_MSDU_PAGE_SIZE,
                               MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));
        if (ret)
                return ret;
@@ -560,10 +586,12 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
                if (mtk_wed_device_active(&mdev->mmio.wed) &&
                    mtk_wed_get_rx_capa(&mdev->mmio.wed))
                        mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].wed = &mdev->mmio.wed;
+
+               size = is_mt7996(mdev) && mt76_npu_device_active(mdev)
+                      ? MT7996_NPU_RX_RING_SIZE / 2 : MT7996_RX_RING_SIZE;
                ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1],
                                       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),
-                                      MT7996_RX_RING_SIZE,
-                                      MT7996_RX_MSDU_PAGE_SIZE,
+                                      size, MT7996_RX_MSDU_PAGE_SIZE,
                                       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));
                if (ret)
                        return ret;
@@ -576,10 +604,12 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
                if (mtk_wed_device_active(&mdev->mmio.wed) &&
                    mtk_wed_get_rx_capa(&mdev->mmio.wed))
                        mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].wed = &mdev->mmio.wed;
+
+               size = is_mt7996(mdev) && mt76_npu_device_active(mdev)
+                      ? MT7996_NPU_RX_RING_SIZE : MT7996_RX_RING_SIZE;
                ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2],
                                       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),
-                                      MT7996_RX_RING_SIZE,
-                                      MT7996_RX_MSDU_PAGE_SIZE,
+                                      size, MT7996_RX_MSDU_PAGE_SIZE,
                                       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));
                if (ret)
                        return ret;
@@ -642,11 +672,16 @@ int mt7996_dma_init(struct mt7996_dev *dev)
        mt7996_dma_disable(dev, true);
 
        /* init tx queue */
-       ret = mt7996_init_tx_queues(&dev->phy,
-                                   MT_TXQ_ID(dev->mphy.band_idx),
-                                   MT7996_TX_RING_SIZE,
-                                   MT_TXQ_RING_BASE(0),
-                                   wed);
+       if (is_mt7996(&dev->mt76) && mt76_npu_device_active(&dev->mt76))
+               ret = mt7996_init_tx_queues(&dev->phy, MT_TXQ_ID(0),
+                                           MT7996_NPU_TX_RING_SIZE,
+                                           MT_TXQ_RING_BASE(0) + hif1_ofs,
+                                           NULL);
+       else
+               ret = mt7996_init_tx_queues(&dev->phy,
+                                           MT_TXQ_ID(dev->mphy.band_idx),
+                                           MT7996_TX_RING_SIZE,
+                                           MT_TXQ_RING_BASE(0), wed);
        if (ret)
                return ret;
 
@@ -859,16 +894,21 @@ int mt7996_dma_init(struct mt7996_dev *dev)
                }
 
                if (mt7996_band_valid(dev, MT_BAND2)) {
+                       u32 size;
+
                        /* rx rro data queue for band2 */
                        dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags =
                                MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
                        if (mtk_wed_device_active(wed) &&
                            mtk_wed_get_rx_capa(wed))
                                dev->mt76.q_rx[MT_RXQ_RRO_BAND2].wed = wed;
+
+                       size = is_mt7996(&dev->mt76) &&
+                              mt76_npu_device_active(&dev->mt76)
+                              ? MT7996_NPU_RX_RING_SIZE : MT7996_RX_RING_SIZE;
                        ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
                                               MT_RXQ_ID(MT_RXQ_RRO_BAND2),
-                                              MT7996_RX_RING_SIZE,
-                                              MT7996_RX_BUF_SIZE,
+                                              size, MT7996_RX_BUF_SIZE,
                                               MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND2) + hif1_ofs);
                        if (ret)
                                return ret;