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