Commit eebb7097 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

wifi: mt76: mt7915: enable wed for mt7986-wmac chipset



Enable WED tx support for mt7986-wmac chipset available on mt7986 board.

Tested-by: default avatarDaniel Golle <daniel@makrotopia.org>
Co-developed-by: default avatarBo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: default avatarBo Jiao <Bo.Jiao@mediatek.com>
Co-developed-by: default avatarSujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: default avatarSujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent b7ebf46e
Loading
Loading
Loading
Loading
+54 −20
Original line number Diff line number Diff line
@@ -11,7 +11,11 @@ mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base
	struct mt7915_dev *dev = phy->dev;

	if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
		if (is_mt7986(&dev->mt76))
			ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
		else
			ring_base = MT_WED_TX_RING_BASE;

		idx -= MT_TXQ_ID(0);
	}

@@ -58,17 +62,32 @@ static void mt7915_dma_config(struct mt7915_dev *dev)
		MCUQ_CONFIG(MT_MCUQ_WA, WFDMA1, MT_INT_TX_DONE_MCU_WA, MT7915_TXQ_MCU_WA);
		MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA1, MT_INT_TX_DONE_FWDL, MT7915_TXQ_FWDL);
	} else {
		RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0_MT7916, MT7916_RXQ_BAND0);
		RXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, MT7916_RXQ_MCU_WM);
		RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7916_RXQ_MCU_WA);
		RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1_MT7916, MT7916_RXQ_BAND1);
		RXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA0, MT_INT_RX_DONE_WA_EXT_MT7916, MT7916_RXQ_MCU_WA_EXT);
		RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN_MT7916, MT7916_RXQ_MCU_WA_MAIN);
		TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7915_TXQ_BAND0);
		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7915_TXQ_BAND1);
		MCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, MT7915_TXQ_MCU_WM);
		MCUQ_CONFIG(MT_MCUQ_WA, WFDMA0, MT_INT_TX_DONE_MCU_WA_MT7916, MT7915_TXQ_MCU_WA);
		MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7915_TXQ_FWDL);

		if (is_mt7916(&dev->mt76) && mtk_wed_device_active(&dev->mt76.mmio.wed)) {
			RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_WED_RX_DONE_BAND0_MT7916,
				   MT7916_RXQ_BAND0);
			RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_WED_RX_DONE_WA_MT7916,
				   MT7916_RXQ_MCU_WA);
			RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_WED_RX_DONE_BAND1_MT7916,
				   MT7916_RXQ_BAND1);
			RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_WED_RX_DONE_WA_MAIN_MT7916,
				   MT7916_RXQ_MCU_WA_MAIN);
			TXQ_CONFIG(0, WFDMA0, MT_INT_WED_TX_DONE_BAND0, MT7915_TXQ_BAND0);
			TXQ_CONFIG(1, WFDMA0, MT_INT_WED_TX_DONE_BAND1, MT7915_TXQ_BAND1);
		} else {
			RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0_MT7916, MT7916_RXQ_BAND0);
			RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7916_RXQ_MCU_WA);
			RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1_MT7916, MT7916_RXQ_BAND1);
			RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN_MT7916,
				   MT7916_RXQ_MCU_WA_MAIN);
			TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7915_TXQ_BAND0);
			TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7915_TXQ_BAND1);
		}
	}
}

@@ -323,6 +342,7 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
		u32 wed_irq_mask = irq_mask;

		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
		if (!is_mt7986(&dev->mt76))
			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
@@ -349,13 +369,18 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)

	mt7915_dma_disable(dev, true);

	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
		mt76_set(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED);
	if (mtk_wed_device_active(&mdev->mmio.wed)) {
		if (!is_mt7986(mdev)) {
			u8 wed_control_rx1 = is_mt7915(mdev) ? 1 : 2;

			mt76_set(dev, MT_WFDMA_HOST_CONFIG,
				 MT_WFDMA_HOST_CONFIG_WED);
			mt76_wr(dev, MT_WFDMA_WED_RING_CONTROL,
				FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_TX0, 18) |
				FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_TX1, 19) |
			FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_RX1, 1));
				FIELD_PREP(MT_WFDMA_WED_RING_CONTROL_RX1,
					   wed_control_rx1));
		}
	} else {
		mt76_clear(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED);
	}
@@ -411,7 +436,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
		return ret;

	/* event from WA */
	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
	if (mtk_wed_device_active(&mdev->mmio.wed) && is_mt7915(mdev)) {
		wa_rx_base = MT_WED_RX_RING_BASE;
		wa_rx_idx = MT7915_RXQ_MCU_WA;
		dev->mt76.q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
@@ -438,11 +463,20 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)

	/* tx free notify event from WA for band0 */
	if (!is_mt7915(mdev)) {
		wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MAIN_WA);
		wa_rx_idx = MT_RXQ_ID(MT_RXQ_MAIN_WA);

		if (mtk_wed_device_active(&mdev->mmio.wed)) {
			mdev->q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
			if (is_mt7916(mdev)) {
				wa_rx_base =  MT_WED_RX_RING_BASE;
				wa_rx_idx = MT7915_RXQ_MCU_WA;
			}
		}

		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA],
				       MT_RXQ_ID(MT_RXQ_MAIN_WA),
				       MT7915_RX_MCU_RING_SIZE,
				       MT_RX_BUF_SIZE,
				       MT_RXQ_RING_BASE(MT_RXQ_MAIN_WA));
				       wa_rx_idx, MT7915_RX_MCU_RING_SIZE,
				       MT_RX_BUF_SIZE, wa_rx_base);
		if (ret)
			return ret;
	}
+1 −1
Original line number Diff line number Diff line
@@ -1429,7 +1429,7 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
	path->dev = ctx->dev;
	path->mtk_wdma.wdma_idx = wed->wdma_idx;
	path->mtk_wdma.bss = mvif->mt76.idx;
	path->mtk_wdma.wcid = msta->wcid.idx;
	path->mtk_wdma.wcid = is_mt7915(&dev->mt76) ? msta->wcid.idx : 0x3ff;
	path->mtk_wdma.queue = phy != &dev->phy;

	ctx->dev = NULL;
+1 −1
Original line number Diff line number Diff line
@@ -2289,7 +2289,7 @@ int mt7915_mcu_init(struct mt7915_dev *dev)
	if (ret)
		return ret;

	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && is_mt7915(&dev->mt76))
		mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0);

	ret = mt7915_mcu_set_mwds(dev, 1);
+49 −18
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ static const u32 mt7915_reg[] = {
	[INFRA_MCU_ADDR_END]	= 0x7c3fffff,
	[FW_EXCEPTION_ADDR]	= 0x219848,
	[SWDEF_BASE_ADDR]	= 0x41f200,
	[TXQ_WED_RING_BASE]	= 0xd7300,
	[RXQ_WED_RING_BASE]	= 0xd7410,
};

static const u32 mt7916_reg[] = {
@@ -43,6 +45,8 @@ static const u32 mt7916_reg[] = {
	[INFRA_MCU_ADDR_END]	= 0x7c085fff,
	[FW_EXCEPTION_ADDR]	= 0x022050bc,
	[SWDEF_BASE_ADDR]	= 0x411400,
	[TXQ_WED_RING_BASE]	= 0xd7300,
	[RXQ_WED_RING_BASE]	= 0xd7410,
};

static const u32 mt7986_reg[] = {
@@ -59,6 +63,8 @@ static const u32 mt7986_reg[] = {
	[INFRA_MCU_ADDR_END]	= 0x7c085fff,
	[FW_EXCEPTION_ADDR]	= 0x02204ffc,
	[SWDEF_BASE_ADDR]	= 0x411400,
	[TXQ_WED_RING_BASE]	= 0x24420,
	[RXQ_WED_RING_BASE]	= 0x24520,
};

static const u32 mt7915_offs[] = {
@@ -528,8 +534,8 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
}
#endif

int mt7915_mmio_wed_init(struct mt7915_dev *dev, struct pci_dev *pdev,
			 int *irq)
int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
			 bool pci, int *irq)
{
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
@@ -538,27 +544,46 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, struct pci_dev *pdev,
	if (!wed_enable)
		return 0;

	wed->wlan.pci_dev = pdev;
	wed->wlan.wpdma_phys = pci_resource_start(pdev, 0) +
			       MT_WFDMA_EXT_CSR_BASE;
	wed->wlan.wpdma_int = pci_resource_start(pdev, 0) +
	if (pci) {
		struct pci_dev *pci_dev = pdev_ptr;

		wed->wlan.pci_dev = pci_dev;
		wed->wlan.bus_type = MTK_WED_BUS_PCIE;
		wed->wlan.wpdma_int = pci_resource_start(pci_dev, 0) +
				      MT_INT_WED_SOURCE_CSR;
	wed->wlan.wpdma_mask = pci_resource_start(pdev, 0) +
		wed->wlan.wpdma_mask = pci_resource_start(pci_dev, 0) +
				       MT_INT_WED_MASK_CSR;
	wed->wlan.wpdma_tx = pci_resource_start(pdev, 0) +
		wed->wlan.wpdma_phys = pci_resource_start(pci_dev, 0) +
				       MT_WFDMA_EXT_CSR_BASE;
		wed->wlan.wpdma_tx = pci_resource_start(pci_dev, 0) +
				     MT_TXQ_WED_RING_BASE;
	wed->wlan.wpdma_txfree = pci_resource_start(pdev, 0) +
		wed->wlan.wpdma_txfree = pci_resource_start(pci_dev, 0) +
					 MT_RXQ_WED_RING_BASE;
	} else {
		struct platform_device *plat_dev = pdev_ptr;
		struct resource *res;

		res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
		if (!res)
			return -ENOMEM;

		wed->wlan.platform_dev = plat_dev;
		wed->wlan.bus_type = MTK_WED_BUS_AXI;
		wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR;
		wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR;
		wed->wlan.wpdma_tx = res->start + MT_TXQ_WED_RING_BASE;
		wed->wlan.wpdma_txfree = res->start + MT_RXQ_WED_RING_BASE;
	}
	wed->wlan.nbuf = 4096;
	wed->wlan.tx_tbit[0] = MT_WED_TX_DONE_BAND0;
	wed->wlan.tx_tbit[1] = MT_WED_TX_DONE_BAND1;
	wed->wlan.txfree_tbit = MT_WED_TX_FREE_DONE;
	wed->wlan.tx_tbit[0] = is_mt7915(&dev->mt76) ? 4 : 30;
	wed->wlan.tx_tbit[1] = is_mt7915(&dev->mt76) ? 5 : 31;
	wed->wlan.txfree_tbit = is_mt7915(&dev->mt76) ? 1 : 2;
	wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf;
	wed->wlan.init_buf = mt7915_wed_init_buf;
	wed->wlan.offload_enable = mt7915_mmio_wed_offload_enable;
	wed->wlan.offload_disable = mt7915_mmio_wed_offload_disable;

	if (mtk_wed_device_attach(wed) != 0)
	if (mtk_wed_device_attach(wed))
		return 0;

	*irq = wed->irq;
@@ -638,6 +663,10 @@ void mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev,
	mdev->mmio.irqmask |= set;

	if (write_reg) {
		if (mtk_wed_device_active(&mdev->mmio.wed))
			mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
						    mdev->mmio.irqmask);
		else
			mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
		mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
	}
@@ -662,6 +691,8 @@ static void mt7915_irq_tasklet(struct tasklet_struct *t)

	if (mtk_wed_device_active(wed)) {
		mtk_wed_device_irq_set_mask(wed, 0);
		if (dev->hif2)
			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
	} else {
		mt76_wr(dev, MT_INT_MASK_CSR, 0);
+2 −2
Original line number Diff line number Diff line
@@ -591,7 +591,7 @@ bool mt7915_debugfs_rx_log(struct mt7915_dev *dev, const void *data, int len);
void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
			    struct ieee80211_sta *sta, struct dentry *dir);
#endif
int mt7915_mmio_wed_init(struct mt7915_dev *dev, struct pci_dev *pdev,
			 int *irq);
int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
			 bool pci, int *irq);

#endif
Loading