xref: /freebsd/sys/contrib/dev/mediatek/mt76/mt792x_dma.c (revision 8ba4d145d351db26e07695b8e90697398c5dfec2)
1cbb3ec25SBjoern A. Zeeb // SPDX-License-Identifier: ISC
2cbb3ec25SBjoern A. Zeeb /* Copyright (C) 2023 MediaTek Inc. */
3cbb3ec25SBjoern A. Zeeb 
4cbb3ec25SBjoern A. Zeeb #include <linux/module.h>
5cbb3ec25SBjoern A. Zeeb #include <linux/firmware.h>
6cbb3ec25SBjoern A. Zeeb #if defined(__FreeBSD__)
7cbb3ec25SBjoern A. Zeeb #include <linux/delay.h>
8cbb3ec25SBjoern A. Zeeb #endif
9cbb3ec25SBjoern A. Zeeb 
10cbb3ec25SBjoern A. Zeeb #include "mt792x.h"
11cbb3ec25SBjoern A. Zeeb #include "dma.h"
12cbb3ec25SBjoern A. Zeeb #include "trace.h"
13cbb3ec25SBjoern A. Zeeb 
mt792x_irq_handler(int irq,void * dev_instance)14cbb3ec25SBjoern A. Zeeb irqreturn_t mt792x_irq_handler(int irq, void *dev_instance)
15cbb3ec25SBjoern A. Zeeb {
16cbb3ec25SBjoern A. Zeeb 	struct mt792x_dev *dev = dev_instance;
17cbb3ec25SBjoern A. Zeeb 
18*8ba4d145SBjoern A. Zeeb 	if (test_bit(MT76_REMOVED, &dev->mt76.phy.state))
19*8ba4d145SBjoern A. Zeeb 		return IRQ_NONE;
20cbb3ec25SBjoern A. Zeeb 	mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
21cbb3ec25SBjoern A. Zeeb 
22cbb3ec25SBjoern A. Zeeb 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
23cbb3ec25SBjoern A. Zeeb 		return IRQ_NONE;
24cbb3ec25SBjoern A. Zeeb 
25cbb3ec25SBjoern A. Zeeb 	tasklet_schedule(&dev->mt76.irq_tasklet);
26cbb3ec25SBjoern A. Zeeb 
27cbb3ec25SBjoern A. Zeeb 	return IRQ_HANDLED;
28cbb3ec25SBjoern A. Zeeb }
29cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_irq_handler);
30cbb3ec25SBjoern A. Zeeb 
mt792x_irq_tasklet(unsigned long data)31cbb3ec25SBjoern A. Zeeb void mt792x_irq_tasklet(unsigned long data)
32cbb3ec25SBjoern A. Zeeb {
33cbb3ec25SBjoern A. Zeeb 	struct mt792x_dev *dev = (struct mt792x_dev *)data;
34cbb3ec25SBjoern A. Zeeb 	const struct mt792x_irq_map *irq_map = dev->irq_map;
35cbb3ec25SBjoern A. Zeeb 	u32 intr, mask = 0;
36cbb3ec25SBjoern A. Zeeb 
37cbb3ec25SBjoern A. Zeeb 	mt76_wr(dev, irq_map->host_irq_enable, 0);
38cbb3ec25SBjoern A. Zeeb 
39cbb3ec25SBjoern A. Zeeb 	intr = mt76_rr(dev, MT_WFDMA0_HOST_INT_STA);
40cbb3ec25SBjoern A. Zeeb 	intr &= dev->mt76.mmio.irqmask;
41cbb3ec25SBjoern A. Zeeb 	mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, intr);
42cbb3ec25SBjoern A. Zeeb 
43cbb3ec25SBjoern A. Zeeb 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
44cbb3ec25SBjoern A. Zeeb 
45cbb3ec25SBjoern A. Zeeb 	mask |= intr & (irq_map->rx.data_complete_mask |
46cbb3ec25SBjoern A. Zeeb 			irq_map->rx.wm_complete_mask |
47cbb3ec25SBjoern A. Zeeb 			irq_map->rx.wm2_complete_mask);
48cbb3ec25SBjoern A. Zeeb 	if (intr & dev->irq_map->tx.mcu_complete_mask)
49cbb3ec25SBjoern A. Zeeb 		mask |= dev->irq_map->tx.mcu_complete_mask;
50cbb3ec25SBjoern A. Zeeb 
51cbb3ec25SBjoern A. Zeeb 	if (intr & MT_INT_MCU_CMD) {
52cbb3ec25SBjoern A. Zeeb 		u32 intr_sw;
53cbb3ec25SBjoern A. Zeeb 
54cbb3ec25SBjoern A. Zeeb 		intr_sw = mt76_rr(dev, MT_MCU_CMD);
55cbb3ec25SBjoern A. Zeeb 		/* ack MCU2HOST_SW_INT_STA */
56cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_MCU_CMD, intr_sw);
57cbb3ec25SBjoern A. Zeeb 		if (intr_sw & MT_MCU_CMD_WAKE_RX_PCIE) {
58cbb3ec25SBjoern A. Zeeb 			mask |= irq_map->rx.data_complete_mask;
59cbb3ec25SBjoern A. Zeeb 			intr |= irq_map->rx.data_complete_mask;
60cbb3ec25SBjoern A. Zeeb 		}
61cbb3ec25SBjoern A. Zeeb 	}
62cbb3ec25SBjoern A. Zeeb 
63cbb3ec25SBjoern A. Zeeb 	mt76_set_irq_mask(&dev->mt76, irq_map->host_irq_enable, mask, 0);
64cbb3ec25SBjoern A. Zeeb 
65cbb3ec25SBjoern A. Zeeb 	if (intr & dev->irq_map->tx.all_complete_mask)
66cbb3ec25SBjoern A. Zeeb 		napi_schedule(&dev->mt76.tx_napi);
67cbb3ec25SBjoern A. Zeeb 
68cbb3ec25SBjoern A. Zeeb 	if (intr & irq_map->rx.wm_complete_mask)
69cbb3ec25SBjoern A. Zeeb 		napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]);
70cbb3ec25SBjoern A. Zeeb 
71cbb3ec25SBjoern A. Zeeb 	if (intr & irq_map->rx.wm2_complete_mask)
72cbb3ec25SBjoern A. Zeeb 		napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]);
73cbb3ec25SBjoern A. Zeeb 
74cbb3ec25SBjoern A. Zeeb 	if (intr & irq_map->rx.data_complete_mask)
75cbb3ec25SBjoern A. Zeeb 		napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]);
76cbb3ec25SBjoern A. Zeeb }
77cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_irq_tasklet);
78cbb3ec25SBjoern A. Zeeb 
mt792x_rx_poll_complete(struct mt76_dev * mdev,enum mt76_rxq_id q)79cbb3ec25SBjoern A. Zeeb void mt792x_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
80cbb3ec25SBjoern A. Zeeb {
81cbb3ec25SBjoern A. Zeeb 	struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
82cbb3ec25SBjoern A. Zeeb 	const struct mt792x_irq_map *irq_map = dev->irq_map;
83cbb3ec25SBjoern A. Zeeb 
84cbb3ec25SBjoern A. Zeeb 	if (q == MT_RXQ_MAIN)
85cbb3ec25SBjoern A. Zeeb 		mt76_connac_irq_enable(mdev, irq_map->rx.data_complete_mask);
86cbb3ec25SBjoern A. Zeeb 	else if (q == MT_RXQ_MCU_WA)
87cbb3ec25SBjoern A. Zeeb 		mt76_connac_irq_enable(mdev, irq_map->rx.wm2_complete_mask);
88cbb3ec25SBjoern A. Zeeb 	else
89cbb3ec25SBjoern A. Zeeb 		mt76_connac_irq_enable(mdev, irq_map->rx.wm_complete_mask);
90cbb3ec25SBjoern A. Zeeb }
91cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_rx_poll_complete);
92cbb3ec25SBjoern A. Zeeb 
93cbb3ec25SBjoern A. Zeeb #define PREFETCH(base, depth)	((base) << 16 | (depth))
mt792x_dma_prefetch(struct mt792x_dev * dev)94cbb3ec25SBjoern A. Zeeb static void mt792x_dma_prefetch(struct mt792x_dev *dev)
95cbb3ec25SBjoern A. Zeeb {
96*8ba4d145SBjoern A. Zeeb 	if (is_mt7925(&dev->mt76)) {
97*8ba4d145SBjoern A. Zeeb 		/* rx ring */
98*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0000, 0x4));
99*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING1_EXT_CTRL, PREFETCH(0x0040, 0x4));
100*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x0080, 0x4));
101*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING3_EXT_CTRL, PREFETCH(0x00c0, 0x4));
102*8ba4d145SBjoern A. Zeeb 		/* tx ring */
103*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, PREFETCH(0x0100, 0x10));
104*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING1_EXT_CTRL, PREFETCH(0x0200, 0x10));
105*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING2_EXT_CTRL, PREFETCH(0x0300, 0x10));
106*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING3_EXT_CTRL, PREFETCH(0x0400, 0x10));
107*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING15_EXT_CTRL, PREFETCH(0x0500, 0x4));
108*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING16_EXT_CTRL, PREFETCH(0x0540, 0x4));
109*8ba4d145SBjoern A. Zeeb 	} else {
110*8ba4d145SBjoern A. Zeeb 		/* rx ring */
111cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0, 0x4));
112cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x40, 0x4));
113cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING3_EXT_CTRL, PREFETCH(0x80, 0x4));
114cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING4_EXT_CTRL, PREFETCH(0xc0, 0x4));
115cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RX_RING5_EXT_CTRL, PREFETCH(0x100, 0x4));
116*8ba4d145SBjoern A. Zeeb 		/* tx ring */
117cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, PREFETCH(0x140, 0x4));
118cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING1_EXT_CTRL, PREFETCH(0x180, 0x4));
119cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING2_EXT_CTRL, PREFETCH(0x1c0, 0x4));
120cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING3_EXT_CTRL, PREFETCH(0x200, 0x4));
121cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING4_EXT_CTRL, PREFETCH(0x240, 0x4));
122cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING5_EXT_CTRL, PREFETCH(0x280, 0x4));
123cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING6_EXT_CTRL, PREFETCH(0x2c0, 0x4));
124cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING16_EXT_CTRL, PREFETCH(0x340, 0x4));
125cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4));
126cbb3ec25SBjoern A. Zeeb 	}
127*8ba4d145SBjoern A. Zeeb }
128cbb3ec25SBjoern A. Zeeb 
mt792x_dma_enable(struct mt792x_dev * dev)129cbb3ec25SBjoern A. Zeeb int mt792x_dma_enable(struct mt792x_dev *dev)
130cbb3ec25SBjoern A. Zeeb {
131cbb3ec25SBjoern A. Zeeb 	/* configure perfetch settings */
132cbb3ec25SBjoern A. Zeeb 	mt792x_dma_prefetch(dev);
133cbb3ec25SBjoern A. Zeeb 
134cbb3ec25SBjoern A. Zeeb 	/* reset dma idx */
135cbb3ec25SBjoern A. Zeeb 	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
136*8ba4d145SBjoern A. Zeeb 	if (is_mt7925(&dev->mt76))
137*8ba4d145SBjoern A. Zeeb 		mt76_wr(dev, MT_WFDMA0_RST_DRX_PTR, ~0);
138cbb3ec25SBjoern A. Zeeb 
139cbb3ec25SBjoern A. Zeeb 	/* configure delay interrupt */
140cbb3ec25SBjoern A. Zeeb 	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
141cbb3ec25SBjoern A. Zeeb 
142cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
143cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
144cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
145cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
146cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
147*8ba4d145SBjoern A. Zeeb 		 FIELD_PREP(MT_WFDMA0_GLO_CFG_DMA_SIZE, 3) |
148*8ba4d145SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_FIFO_DIS_CHECK |
149*8ba4d145SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_RX_WB_DDONE |
150cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
151cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
152cbb3ec25SBjoern A. Zeeb 
153cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
154cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
155cbb3ec25SBjoern A. Zeeb 
156*8ba4d145SBjoern A. Zeeb 	if (is_mt7925(&dev->mt76)) {
157*8ba4d145SBjoern A. Zeeb 		mt76_rmw(dev, MT_UWFDMA0_GLO_CFG_EXT1, BIT(28), BIT(28));
158*8ba4d145SBjoern A. Zeeb 		mt76_set(dev, MT_WFDMA0_INT_RX_PRI, 0x0F00);
159*8ba4d145SBjoern A. Zeeb 		mt76_set(dev, MT_WFDMA0_INT_TX_PRI, 0x7F00);
160*8ba4d145SBjoern A. Zeeb 	}
161cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
162cbb3ec25SBjoern A. Zeeb 
163cbb3ec25SBjoern A. Zeeb 	/* enable interrupts for TX/RX rings */
164cbb3ec25SBjoern A. Zeeb 	mt76_connac_irq_enable(&dev->mt76,
165cbb3ec25SBjoern A. Zeeb 			       dev->irq_map->tx.all_complete_mask |
166cbb3ec25SBjoern A. Zeeb 			       dev->irq_map->rx.data_complete_mask |
167cbb3ec25SBjoern A. Zeeb 			       dev->irq_map->rx.wm2_complete_mask |
168cbb3ec25SBjoern A. Zeeb 			       dev->irq_map->rx.wm_complete_mask |
169cbb3ec25SBjoern A. Zeeb 			       MT_INT_MCU_CMD);
170cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
171cbb3ec25SBjoern A. Zeeb 
172cbb3ec25SBjoern A. Zeeb 	return 0;
173cbb3ec25SBjoern A. Zeeb }
174cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_dma_enable);
175cbb3ec25SBjoern A. Zeeb 
176cbb3ec25SBjoern A. Zeeb static int
mt792x_dma_reset(struct mt792x_dev * dev,bool force)177cbb3ec25SBjoern A. Zeeb mt792x_dma_reset(struct mt792x_dev *dev, bool force)
178cbb3ec25SBjoern A. Zeeb {
179cbb3ec25SBjoern A. Zeeb 	int i, err;
180cbb3ec25SBjoern A. Zeeb 
181cbb3ec25SBjoern A. Zeeb 	err = mt792x_dma_disable(dev, force);
182cbb3ec25SBjoern A. Zeeb 	if (err)
183cbb3ec25SBjoern A. Zeeb 		return err;
184cbb3ec25SBjoern A. Zeeb 
185cbb3ec25SBjoern A. Zeeb 	/* reset hw queues */
186cbb3ec25SBjoern A. Zeeb 	for (i = 0; i < __MT_TXQ_MAX; i++)
187cbb3ec25SBjoern A. Zeeb 		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
188cbb3ec25SBjoern A. Zeeb 
189cbb3ec25SBjoern A. Zeeb 	for (i = 0; i < __MT_MCUQ_MAX; i++)
190cbb3ec25SBjoern A. Zeeb 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
191cbb3ec25SBjoern A. Zeeb 
192cbb3ec25SBjoern A. Zeeb 	mt76_for_each_q_rx(&dev->mt76, i)
193cbb3ec25SBjoern A. Zeeb 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
194cbb3ec25SBjoern A. Zeeb 
195cbb3ec25SBjoern A. Zeeb 	mt76_tx_status_check(&dev->mt76, true);
196cbb3ec25SBjoern A. Zeeb 
197cbb3ec25SBjoern A. Zeeb 	return mt792x_dma_enable(dev);
198cbb3ec25SBjoern A. Zeeb }
199cbb3ec25SBjoern A. Zeeb 
mt792x_wpdma_reset(struct mt792x_dev * dev,bool force)200cbb3ec25SBjoern A. Zeeb int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force)
201cbb3ec25SBjoern A. Zeeb {
202cbb3ec25SBjoern A. Zeeb 	int i, err;
203cbb3ec25SBjoern A. Zeeb 
204cbb3ec25SBjoern A. Zeeb 	/* clean up hw queues */
205cbb3ec25SBjoern A. Zeeb 	for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++)
206cbb3ec25SBjoern A. Zeeb 		mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true);
207cbb3ec25SBjoern A. Zeeb 
208cbb3ec25SBjoern A. Zeeb 	for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++)
209cbb3ec25SBjoern A. Zeeb 		mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true);
210cbb3ec25SBjoern A. Zeeb 
211cbb3ec25SBjoern A. Zeeb 	mt76_for_each_q_rx(&dev->mt76, i)
212cbb3ec25SBjoern A. Zeeb 		mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
213cbb3ec25SBjoern A. Zeeb 
214cbb3ec25SBjoern A. Zeeb 	if (force) {
215cbb3ec25SBjoern A. Zeeb 		err = mt792x_wfsys_reset(dev);
216cbb3ec25SBjoern A. Zeeb 		if (err)
217cbb3ec25SBjoern A. Zeeb 			return err;
218cbb3ec25SBjoern A. Zeeb 	}
219cbb3ec25SBjoern A. Zeeb 	err = mt792x_dma_reset(dev, force);
220cbb3ec25SBjoern A. Zeeb 	if (err)
221cbb3ec25SBjoern A. Zeeb 		return err;
222cbb3ec25SBjoern A. Zeeb 
223cbb3ec25SBjoern A. Zeeb 	mt76_for_each_q_rx(&dev->mt76, i)
224cbb3ec25SBjoern A. Zeeb 		mt76_queue_rx_reset(dev, i);
225cbb3ec25SBjoern A. Zeeb 
226cbb3ec25SBjoern A. Zeeb 	return 0;
227cbb3ec25SBjoern A. Zeeb }
228cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_wpdma_reset);
229cbb3ec25SBjoern A. Zeeb 
mt792x_wpdma_reinit_cond(struct mt792x_dev * dev)230cbb3ec25SBjoern A. Zeeb int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev)
231cbb3ec25SBjoern A. Zeeb {
232cbb3ec25SBjoern A. Zeeb 	struct mt76_connac_pm *pm = &dev->pm;
233cbb3ec25SBjoern A. Zeeb 	int err;
234cbb3ec25SBjoern A. Zeeb 
235cbb3ec25SBjoern A. Zeeb 	/* check if the wpdma must be reinitialized */
236cbb3ec25SBjoern A. Zeeb 	if (mt792x_dma_need_reinit(dev)) {
237cbb3ec25SBjoern A. Zeeb 		/* disable interrutpts */
238cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
239cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
240cbb3ec25SBjoern A. Zeeb 
241cbb3ec25SBjoern A. Zeeb 		err = mt792x_wpdma_reset(dev, false);
242cbb3ec25SBjoern A. Zeeb 		if (err) {
243cbb3ec25SBjoern A. Zeeb 			dev_err(dev->mt76.dev, "wpdma reset failed\n");
244cbb3ec25SBjoern A. Zeeb 			return err;
245cbb3ec25SBjoern A. Zeeb 		}
246cbb3ec25SBjoern A. Zeeb 
247cbb3ec25SBjoern A. Zeeb 		/* enable interrutpts */
248cbb3ec25SBjoern A. Zeeb 		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
249cbb3ec25SBjoern A. Zeeb 		pm->stats.lp_wake++;
250cbb3ec25SBjoern A. Zeeb 	}
251cbb3ec25SBjoern A. Zeeb 
252cbb3ec25SBjoern A. Zeeb 	return 0;
253cbb3ec25SBjoern A. Zeeb }
254cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_wpdma_reinit_cond);
255cbb3ec25SBjoern A. Zeeb 
mt792x_dma_disable(struct mt792x_dev * dev,bool force)256cbb3ec25SBjoern A. Zeeb int mt792x_dma_disable(struct mt792x_dev *dev, bool force)
257cbb3ec25SBjoern A. Zeeb {
258cbb3ec25SBjoern A. Zeeb 	/* disable WFDMA0 */
259cbb3ec25SBjoern A. Zeeb 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
260cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
261cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
262cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
263cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
264cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
265cbb3ec25SBjoern A. Zeeb 
266cbb3ec25SBjoern A. Zeeb 	if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
267cbb3ec25SBjoern A. Zeeb 				 MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
268cbb3ec25SBjoern A. Zeeb 				 MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
269cbb3ec25SBjoern A. Zeeb 		return -ETIMEDOUT;
270cbb3ec25SBjoern A. Zeeb 
271cbb3ec25SBjoern A. Zeeb 	/* disable dmashdl */
272cbb3ec25SBjoern A. Zeeb 	mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
273cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
274cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
275cbb3ec25SBjoern A. Zeeb 
276cbb3ec25SBjoern A. Zeeb 	if (force) {
277cbb3ec25SBjoern A. Zeeb 		/* reset */
278cbb3ec25SBjoern A. Zeeb 		mt76_clear(dev, MT_WFDMA0_RST,
279cbb3ec25SBjoern A. Zeeb 			   MT_WFDMA0_RST_DMASHDL_ALL_RST |
280cbb3ec25SBjoern A. Zeeb 			   MT_WFDMA0_RST_LOGIC_RST);
281cbb3ec25SBjoern A. Zeeb 
282cbb3ec25SBjoern A. Zeeb 		mt76_set(dev, MT_WFDMA0_RST,
283cbb3ec25SBjoern A. Zeeb 			 MT_WFDMA0_RST_DMASHDL_ALL_RST |
284cbb3ec25SBjoern A. Zeeb 			 MT_WFDMA0_RST_LOGIC_RST);
285cbb3ec25SBjoern A. Zeeb 	}
286cbb3ec25SBjoern A. Zeeb 
287cbb3ec25SBjoern A. Zeeb 	return 0;
288cbb3ec25SBjoern A. Zeeb }
289cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_dma_disable);
290cbb3ec25SBjoern A. Zeeb 
mt792x_dma_cleanup(struct mt792x_dev * dev)291cbb3ec25SBjoern A. Zeeb void mt792x_dma_cleanup(struct mt792x_dev *dev)
292cbb3ec25SBjoern A. Zeeb {
293cbb3ec25SBjoern A. Zeeb 	/* disable */
294cbb3ec25SBjoern A. Zeeb 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
295cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_TX_DMA_EN |
296cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_RX_DMA_EN |
297cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
298cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
299cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
300cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
301cbb3ec25SBjoern A. Zeeb 
302cbb3ec25SBjoern A. Zeeb 	mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
303cbb3ec25SBjoern A. Zeeb 			    MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
304cbb3ec25SBjoern A. Zeeb 			    MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1);
305cbb3ec25SBjoern A. Zeeb 
306cbb3ec25SBjoern A. Zeeb 	/* reset */
307cbb3ec25SBjoern A. Zeeb 	mt76_clear(dev, MT_WFDMA0_RST,
308cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_RST_DMASHDL_ALL_RST |
309cbb3ec25SBjoern A. Zeeb 		   MT_WFDMA0_RST_LOGIC_RST);
310cbb3ec25SBjoern A. Zeeb 
311cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, MT_WFDMA0_RST,
312cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_RST_DMASHDL_ALL_RST |
313cbb3ec25SBjoern A. Zeeb 		 MT_WFDMA0_RST_LOGIC_RST);
314cbb3ec25SBjoern A. Zeeb 
315cbb3ec25SBjoern A. Zeeb 	mt76_dma_cleanup(&dev->mt76);
316cbb3ec25SBjoern A. Zeeb }
317cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_dma_cleanup);
318cbb3ec25SBjoern A. Zeeb 
mt792x_poll_tx(struct napi_struct * napi,int budget)319cbb3ec25SBjoern A. Zeeb int mt792x_poll_tx(struct napi_struct *napi, int budget)
320cbb3ec25SBjoern A. Zeeb {
321cbb3ec25SBjoern A. Zeeb 	struct mt792x_dev *dev;
322cbb3ec25SBjoern A. Zeeb 
323cbb3ec25SBjoern A. Zeeb 	dev = container_of(napi, struct mt792x_dev, mt76.tx_napi);
324cbb3ec25SBjoern A. Zeeb 
325cbb3ec25SBjoern A. Zeeb 	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
326cbb3ec25SBjoern A. Zeeb 		napi_complete(napi);
327cbb3ec25SBjoern A. Zeeb 		queue_work(dev->mt76.wq, &dev->pm.wake_work);
328cbb3ec25SBjoern A. Zeeb 		return 0;
329cbb3ec25SBjoern A. Zeeb 	}
330cbb3ec25SBjoern A. Zeeb 
331cbb3ec25SBjoern A. Zeeb 	mt76_connac_tx_cleanup(&dev->mt76);
332cbb3ec25SBjoern A. Zeeb 	if (napi_complete(napi))
333cbb3ec25SBjoern A. Zeeb 		mt76_connac_irq_enable(&dev->mt76,
334cbb3ec25SBjoern A. Zeeb 				       dev->irq_map->tx.all_complete_mask);
335cbb3ec25SBjoern A. Zeeb 	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
336cbb3ec25SBjoern A. Zeeb 
337cbb3ec25SBjoern A. Zeeb 	return 0;
338cbb3ec25SBjoern A. Zeeb }
339cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_poll_tx);
340cbb3ec25SBjoern A. Zeeb 
mt792x_poll_rx(struct napi_struct * napi,int budget)341cbb3ec25SBjoern A. Zeeb int mt792x_poll_rx(struct napi_struct *napi, int budget)
342cbb3ec25SBjoern A. Zeeb {
343cbb3ec25SBjoern A. Zeeb 	struct mt792x_dev *dev;
344cbb3ec25SBjoern A. Zeeb 	int done;
345cbb3ec25SBjoern A. Zeeb 
346*8ba4d145SBjoern A. Zeeb 	dev = mt76_priv(napi->dev);
347cbb3ec25SBjoern A. Zeeb 
348cbb3ec25SBjoern A. Zeeb 	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
349cbb3ec25SBjoern A. Zeeb 		napi_complete(napi);
350cbb3ec25SBjoern A. Zeeb 		queue_work(dev->mt76.wq, &dev->pm.wake_work);
351cbb3ec25SBjoern A. Zeeb 		return 0;
352cbb3ec25SBjoern A. Zeeb 	}
353cbb3ec25SBjoern A. Zeeb 	done = mt76_dma_rx_poll(napi, budget);
354cbb3ec25SBjoern A. Zeeb 	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
355cbb3ec25SBjoern A. Zeeb 
356cbb3ec25SBjoern A. Zeeb 	return done;
357cbb3ec25SBjoern A. Zeeb }
358cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_poll_rx);
359cbb3ec25SBjoern A. Zeeb 
mt792x_wfsys_reset(struct mt792x_dev * dev)360cbb3ec25SBjoern A. Zeeb int mt792x_wfsys_reset(struct mt792x_dev *dev)
361cbb3ec25SBjoern A. Zeeb {
362cbb3ec25SBjoern A. Zeeb 	u32 addr = is_mt7921(&dev->mt76) ? 0x18000140 : 0x7c000140;
363cbb3ec25SBjoern A. Zeeb 
364cbb3ec25SBjoern A. Zeeb 	mt76_clear(dev, addr, WFSYS_SW_RST_B);
365cbb3ec25SBjoern A. Zeeb 	msleep(50);
366cbb3ec25SBjoern A. Zeeb 	mt76_set(dev, addr, WFSYS_SW_RST_B);
367cbb3ec25SBjoern A. Zeeb 
368cbb3ec25SBjoern A. Zeeb 	if (!__mt76_poll_msec(&dev->mt76, addr, WFSYS_SW_INIT_DONE,
369cbb3ec25SBjoern A. Zeeb 			      WFSYS_SW_INIT_DONE, 500))
370cbb3ec25SBjoern A. Zeeb 		return -ETIMEDOUT;
371cbb3ec25SBjoern A. Zeeb 
372cbb3ec25SBjoern A. Zeeb 	return 0;
373cbb3ec25SBjoern A. Zeeb }
374cbb3ec25SBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt792x_wfsys_reset);
375cbb3ec25SBjoern A. Zeeb 
376