Add NPU integration in MT7996 dma codebase for MT7996 chipset. This is a preliminary patch to enable NPU offload for MT7996 (7990-Eagle) chipset. Tested-by: Hui Ma Signed-off-by: Lorenzo Bianconi --- drivers/net/wireless/mediatek/mt76/mt7996/dma.c | 132 +++++++++++++++--------- 1 file changed, 86 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c index 274b273df1ee941e83db2bf2f9771cbdd4da8b6f..07212d93bc62df69720963f5ba04090bc82003fc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c @@ -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; -- 2.52.0