Commit 3bc2f02f authored by Rex Lu's avatar Rex Lu Committed by Felix Fietkau
Browse files

wifi: mt76: mt7996: Initial DMA configuration for MT7992 WED support



Manage differences in DMA and RX queues configuration for MT7992 and
MT7996.
This is a preliminary patch to enable WED support for MT7992 Kite
chipset supported by MT7996 driver.

Co-developed-by: default avatarSujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: default avatarSujuan Chen <sujuan.chen@mediatek.com>
Co-developed-by: default avatarBenjamin Lin <benjamin-jw.lin@mediatek.com>
Signed-off-by: default avatarBenjamin Lin <benjamin-jw.lin@mediatek.com>
Signed-off-by: default avatarRex Lu <rex.lu@mediatek.com>
Co-developed-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20250909-mt7996-rro-rework-v5-5-7d66f6eb7795@kernel.org


Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent d77f77ff
Loading
Loading
Loading
Loading
+129 −40
Original line number Diff line number Diff line
@@ -89,30 +89,60 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
			   MT7996_RXQ_RRO_BAND0);
		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
			   MT7996_RXQ_MSDU_PG_BAND0);
		RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
			   MT7996_RXQ_TXFREE0);
		if (is_mt7996(&dev->mt76)) {
			RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0,
				   MT_INT_RX_TXFREE_MAIN, MT7996_RXQ_TXFREE0);
			/* band1 */
		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
			RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0,
				   MT_INT_RX_DONE_MSDU_PG_BAND1,
				   MT7996_RXQ_MSDU_PG_BAND1);
			/* band2 */
		RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
			RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0,
				   MT_INT_RX_DONE_RRO_BAND2,
				   MT7996_RXQ_RRO_BAND2);
		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
			RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0,
				   MT_INT_RX_DONE_MSDU_PG_BAND2,
				   MT7996_RXQ_MSDU_PG_BAND2);
		RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
			   MT7996_RXQ_TXFREE2);
			RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0,
				   MT_INT_RX_TXFREE_TRI, MT7996_RXQ_TXFREE2);
		} else {
			RXQ_CONFIG(MT_RXQ_RRO_BAND1, WFDMA0,
				   MT_INT_RX_DONE_RRO_BAND1,
				   MT7996_RXQ_RRO_BAND1);
		}

		RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
			   MT7996_RXQ_RRO_IND);
	}

	/* data tx queue */
	TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
	if (is_mt7996(&dev->mt76)) {
		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
		TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
		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);
		} else {
		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
			/* single pcie bn0/1:ring18 bn2:ring19 */
			TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND1,
				   MT7996_TXQ_BAND1);
		}
	} else {
		if (dev->hif2) {
			/*  bn0:ring18 bn1:ring21 */
			TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,
				   MT7996_TXQ_BAND0);
			TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND2,
				   MT7996_TXQ_BAND2);
		} else {
			/* single pcie bn0:ring18 bn1:ring19 */
			TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0,
				   MT7996_TXQ_BAND0);
			TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1,
				   MT7996_TXQ_BAND1);
		}
	}

	/* mcu tx queue */
@@ -288,8 +318,11 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
	if (mt7996_band_valid(dev, MT_BAND0))
		irq_mask |= MT_INT_BAND0_RX_DONE;

	if (mt7996_band_valid(dev, MT_BAND1))
	if (mt7996_band_valid(dev, MT_BAND1)) {
		irq_mask |= MT_INT_BAND1_RX_DONE;
		if (is_mt7992(&dev->mt76) && dev->hif2)
			irq_mask |= MT_INT_RX_TXFREE_BAND1_EXT;
	}

	if (mt7996_band_valid(dev, MT_BAND2))
		irq_mask |= MT_INT_BAND2_RX_DONE;
@@ -378,9 +411,20 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
			 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);

		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
			 MT_WFDMA_HOST_CONFIG_PDMA_BAND |
			 MT_WFDMA_HOST_CONFIG_PDMA_BAND);

		mt76_clear(dev, MT_WFDMA_HOST_CONFIG,
			   MT_WFDMA_HOST_CONFIG_BAND0_PCIE1 |
			   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
			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);
@@ -397,13 +441,19 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
		 * so, redirect pcie0 rx ring3 interrupt to pcie1
		 */
		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
		    dev->has_rro)
		    dev->has_rro) {
			u32 intr = is_mt7996(&dev->mt76) ?
				   MT_WFDMA0_RX_INT_SEL_RING6 :
				   MT_WFDMA0_RX_INT_SEL_RING9 |
				   MT_WFDMA0_RX_INT_SEL_RING5;

			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
				 MT_WFDMA0_RX_INT_SEL_RING6);
		else
				 intr);
		} else {
			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
				 MT_WFDMA0_RX_INT_SEL_RING3);
		}
	}

	mt7996_dma_start(dev, reset, true);
}
@@ -437,7 +487,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
	if (ret)
		return ret;

	if (mt7996_band_valid(dev, MT_BAND1)) {
	if (mt7996_band_valid(dev, MT_BAND1) && is_mt7996(&dev->mt76)) {
		/* rx msdu page queue for band1 */
		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
			MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
@@ -560,7 +610,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
		return ret;

	/* tx free notify event from WA for band0 */
	if (mtk_wed_device_active(wed) && !dev->has_rro) {
	if (mtk_wed_device_active(wed) &&
	    ((is_mt7996(&dev->mt76) && !dev->has_rro) ||
	     (is_mt7992(&dev->mt76)))) {
		dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
		dev->mt76.q_rx[MT_RXQ_MAIN_WA].wed = wed;
	}
@@ -630,6 +682,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
	} else if (mt7996_band_valid(dev, MT_BAND1)) {
		/* rx data queue for mt7992 band1 */
		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1) + hif1_ofs;
		if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
			dev->mt76.q_rx[MT_RXQ_BAND1].flags = MT_WED_Q_RX(1);
			dev->mt76.q_rx[MT_RXQ_BAND1].wed = wed;
		}

		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1],
				       MT_RXQ_ID(MT_RXQ_BAND1),
				       MT7996_RX_RING_SIZE,
@@ -641,6 +698,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
		/* tx free notify event from WA for mt7992 band1 */
		if (mt7996_has_wa(dev)) {
			rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1_WA) + hif1_ofs;
			if (mtk_wed_device_active(wed_hif2)) {
				dev->mt76.q_rx[MT_RXQ_BAND1_WA].flags =
					MT_WED_Q_TXFREE;
				dev->mt76.q_rx[MT_RXQ_BAND1_WA].wed = wed_hif2;
			}

			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1_WA],
					       MT_RXQ_ID(MT_RXQ_BAND1_WA),
					       MT7996_RX_MCU_RING_SIZE,
@@ -665,17 +728,32 @@ int mt7996_dma_init(struct mt7996_dev *dev)
		if (ret)
			return ret;

		if (is_mt7992(&dev->mt76)) {
			dev->mt76.q_rx[MT_RXQ_RRO_BAND1].flags =
				MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
			dev->mt76.q_rx[MT_RXQ_RRO_BAND1].wed = wed;
			ret = mt76_queue_alloc(dev,
					       &dev->mt76.q_rx[MT_RXQ_RRO_BAND1],
					       MT_RXQ_ID(MT_RXQ_RRO_BAND1),
					       MT7996_RX_RING_SIZE,
					       MT7996_RX_BUF_SIZE,
					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND1) + hif1_ofs);
			if (ret)
				return ret;
		} else {
			/* tx free notify event from WA for band0 */
			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;

		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
			ret = mt76_queue_alloc(dev,
					       &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
					       MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
					       MT7996_RX_MCU_RING_SIZE,
					       MT7996_RX_BUF_SIZE,
					       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
			if (ret)
				return ret;
		}

		if (mt7996_band_valid(dev, MT_BAND2)) {
			/* rx rro data queue for band2 */
@@ -778,18 +856,29 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
		mt76_queue_reset(dev, dev->mt76.q_mcu[i], true);

	mt76_for_each_q_rx(&dev->mt76, i) {
		if (mtk_wed_device_active(&dev->mt76.mmio.wed))
			if (mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]) ||
			    mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
				continue;
		struct mt76_queue *q = &dev->mt76.q_rx[i];

		mt76_queue_reset(dev, &dev->mt76.q_rx[i], true);
		if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
			if (mt76_queue_is_wed_rro(q) ||
			    mt76_queue_is_wed_tx_free(q)) {
				if (force && mt76_queue_is_wed_rro_data(q))
					mt76_queue_reset(dev, q, false);
				continue;
			}
		}
		mt76_queue_reset(dev, q, true);
	}

	mt76_tx_status_check(&dev->mt76, true);

	mt76_for_each_q_rx(&dev->mt76, i)
	mt76_for_each_q_rx(&dev->mt76, i) {
		if (mtk_wed_device_active(&dev->mt76.mmio.wed) && force &&
		    (mt76_queue_is_wed_rro_ind(&dev->mt76.q_rx[i]) ||
		     mt76_queue_is_wed_rro_msdu_pg(&dev->mt76.q_rx[i])))
			continue;

		mt76_queue_rx_reset(dev, i);
	}

	mt7996_dma_enable(dev, !force);
}
+7 −1
Original line number Diff line number Diff line
@@ -690,12 +690,18 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
					       dev->mt76.mmio.irqmask);
		if (intr1 & MT_INT_RX_TXFREE_EXT)
			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);

		if (intr1 & MT_INT_RX_DONE_BAND2_EXT)
			napi_schedule(&dev->mt76.napi[MT_RXQ_BAND2]);

		if (intr1 & MT_INT_RX_TXFREE_BAND1_EXT)
			napi_schedule(&dev->mt76.napi[MT_RXQ_BAND1_WA]);
	}

	if (mtk_wed_device_active(wed)) {
		mtk_wed_device_irq_set_mask(wed, 0);
		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
		intr |= (intr1 & ~MT_INT_TX_RX_DONE_EXT);
	} else {
		mt76_wr(dev, MT_INT_MASK_CSR, 0);
		if (dev->hif2)
+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ enum mt7996_rxq_id {
	MT7996_RXQ_BAND1 = 5, /* for mt7992 */
	MT7996_RXQ_BAND2 = 5,
	MT7996_RXQ_RRO_BAND0 = 8,
	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
	MT7996_RXQ_RRO_BAND1 = 9,
	MT7996_RXQ_RRO_BAND2 = 6,
	MT7996_RXQ_MSDU_PG_BAND0 = 10,
	MT7996_RXQ_MSDU_PG_BAND1 = 11,
+7 −1
Original line number Diff line number Diff line
@@ -412,7 +412,9 @@ enum offs_rev {

#define MT_WFDMA0_RX_INT_PCIE_SEL		MT_WFDMA0(0x154)
#define MT_WFDMA0_RX_INT_SEL_RING3		BIT(3)
#define MT_WFDMA0_RX_INT_SEL_RING5		BIT(5)
#define MT_WFDMA0_RX_INT_SEL_RING6		BIT(6)
#define MT_WFDMA0_RX_INT_SEL_RING9		BIT(9)

#define MT_WFDMA0_MCU_HOST_INT_ENA		MT_WFDMA0(0x1f4)

@@ -451,6 +453,8 @@ enum offs_rev {

#define MT_WFDMA_HOST_CONFIG			MT_WFDMA_EXT_CSR(0x30)
#define MT_WFDMA_HOST_CONFIG_PDMA_BAND		BIT(0)
#define MT_WFDMA_HOST_CONFIG_BAND0_PCIE1	BIT(20)
#define MT_WFDMA_HOST_CONFIG_BAND1_PCIE1	BIT(21)
#define MT_WFDMA_HOST_CONFIG_BAND2_PCIE1	BIT(22)

#define MT_WFDMA_EXT_CSR_HIF_MISC		MT_WFDMA_EXT_CSR(0x44)
@@ -514,7 +518,9 @@ enum offs_rev {
#define MT_INT_RX_DONE_WA_EXT			BIT(3) /* for mt7992 */
#define MT_INT_RX_DONE_WA_TRI			BIT(3)
#define MT_INT_RX_TXFREE_MAIN			BIT(17)
#define MT_INT_RX_TXFREE_BAND1			BIT(15)
#define MT_INT_RX_TXFREE_TRI			BIT(15)
#define MT_INT_RX_TXFREE_BAND1_EXT		BIT(19) /* for mt7992 two PCIE*/
#define MT_INT_RX_TXFREE_BAND0_MT7990		BIT(14)
#define MT_INT_RX_TXFREE_BAND1_MT7990		BIT(15)
#define MT_INT_RX_DONE_BAND2_EXT		BIT(23)
@@ -522,7 +528,7 @@ enum offs_rev {
#define MT_INT_MCU_CMD				BIT(29)

#define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
#define MT_INT_RX_DONE_RRO_BAND1		BIT(16)
#define MT_INT_RX_DONE_RRO_BAND1		BIT(17)
#define MT_INT_RX_DONE_RRO_BAND2		BIT(14)
#define MT_INT_RX_DONE_RRO_IND			BIT(11)
#define MT_INT_RX_DONE_MSDU_PG_BAND0		BIT(18)