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