1// SPDX-License-Identifier: ISC
2/*
3 * Copyright (C) 2022 MediaTek Inc.
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/pci.h>
9#include <linux/rtnetlink.h>
10
11#include "mt7996.h"
12#include "mac.h"
13#include "mcu.h"
14#include "../trace.h"
15#include "../dma.h"
16
17static bool wed_enable;
18module_param(wed_enable, bool, 0644);
19
20static const struct __base mt7996_reg_base[] = {
21	[WF_AGG_BASE]		= { { 0x820e2000, 0x820f2000, 0x830e2000 } },
22	[WF_ARB_BASE]		= { { 0x820e3000, 0x820f3000, 0x830e3000 } },
23	[WF_TMAC_BASE]		= { { 0x820e4000, 0x820f4000, 0x830e4000 } },
24	[WF_RMAC_BASE]		= { { 0x820e5000, 0x820f5000, 0x830e5000 } },
25	[WF_DMA_BASE]		= { { 0x820e7000, 0x820f7000, 0x830e7000 } },
26	[WF_WTBLOFF_BASE]	= { { 0x820e9000, 0x820f9000, 0x830e9000 } },
27	[WF_ETBF_BASE]		= { { 0x820ea000, 0x820fa000, 0x830ea000 } },
28	[WF_LPON_BASE]		= { { 0x820eb000, 0x820fb000, 0x830eb000 } },
29	[WF_MIB_BASE]		= { { 0x820ed000, 0x820fd000, 0x830ed000 } },
30	[WF_RATE_BASE]		= { { 0x820ee000, 0x820fe000, 0x830ee000 } },
31};
32
33static const u32 mt7996_offs[] = {
34	[MIB_RVSR0]		= 0x720,
35	[MIB_RVSR1]		= 0x724,
36	[MIB_BTSCR5]		= 0x788,
37	[MIB_BTSCR6]		= 0x798,
38	[MIB_RSCR1]		= 0x7ac,
39	[MIB_RSCR27]		= 0x954,
40	[MIB_RSCR28]		= 0x958,
41	[MIB_RSCR29]		= 0x95c,
42	[MIB_RSCR30]		= 0x960,
43	[MIB_RSCR31]		= 0x964,
44	[MIB_RSCR33]		= 0x96c,
45	[MIB_RSCR35]		= 0x974,
46	[MIB_RSCR36]		= 0x978,
47	[MIB_BSCR0]		= 0x9cc,
48	[MIB_BSCR1]		= 0x9d0,
49	[MIB_BSCR2]		= 0x9d4,
50	[MIB_BSCR3]		= 0x9d8,
51	[MIB_BSCR4]		= 0x9dc,
52	[MIB_BSCR5]		= 0x9e0,
53	[MIB_BSCR6]		= 0x9e4,
54	[MIB_BSCR7]		= 0x9e8,
55	[MIB_BSCR17]		= 0xa10,
56	[MIB_TRDR1]		= 0xa28,
57};
58
59static const u32 mt7992_offs[] = {
60	[MIB_RVSR0]		= 0x760,
61	[MIB_RVSR1]		= 0x764,
62	[MIB_BTSCR5]		= 0x7c8,
63	[MIB_BTSCR6]		= 0x7d8,
64	[MIB_RSCR1]		= 0x7f0,
65	[MIB_RSCR27]		= 0x998,
66	[MIB_RSCR28]		= 0x99c,
67	[MIB_RSCR29]		= 0x9a0,
68	[MIB_RSCR30]		= 0x9a4,
69	[MIB_RSCR31]		= 0x9a8,
70	[MIB_RSCR33]		= 0x9b0,
71	[MIB_RSCR35]		= 0x9b8,
72	[MIB_RSCR36]		= 0x9bc,
73	[MIB_BSCR0]		= 0xac8,
74	[MIB_BSCR1]		= 0xacc,
75	[MIB_BSCR2]		= 0xad0,
76	[MIB_BSCR3]		= 0xad4,
77	[MIB_BSCR4]		= 0xad8,
78	[MIB_BSCR5]		= 0xadc,
79	[MIB_BSCR6]		= 0xae0,
80	[MIB_BSCR7]		= 0xae4,
81	[MIB_BSCR17]		= 0xb0c,
82	[MIB_TRDR1]		= 0xb24,
83};
84
85static const struct __map mt7996_reg_map[] = {
86	{ 0x54000000, 0x02000, 0x1000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */
87	{ 0x55000000, 0x03000, 0x1000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */
88	{ 0x56000000, 0x04000, 0x1000 }, /* WFDMA reserved */
89	{ 0x57000000, 0x05000, 0x1000 }, /* WFDMA MCU wrap CR */
90	{ 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */
91	{ 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */
92	{ 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */
93	{ 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */
94	{ 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */
95	{ 0x74030000, 0x10000, 0x1000 }, /* PCIe MAC */
96	{ 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */
97	{ 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */
98	{ 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */
99	{ 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */
100	{ 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */
101	{ 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */
102	{ 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */
103	{ 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */
104	{ 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */
105	{ 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */
106	{ 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */
107	{ 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */
108	{ 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */
109	{ 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */
110	{ 0x820ca000, 0x26000, 0x2000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */
111	{ 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */
112	{ 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */
113	{ 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */
114	{ 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */
115	{ 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */
116	{ 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */
117	{ 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */
118	{ 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */
119	{ 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */
120	{ 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */
121	{ 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */
122	{ 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */
123	{ 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */
124	{ 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */
125	{ 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */
126	{ 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */
127	{ 0x820cc000, 0xa5000, 0x2000 }, /* WF_LMAC_TOP BN1 (WF_MUCOP) */
128	{ 0x820c4000, 0xa8000, 0x4000 }, /* WF_LMAC_TOP BN1 (WF_MUCOP) */
129	{ 0x820b0000, 0xae000, 0x1000 }, /* [APB2] WFSYS_ON */
130	{ 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */
131	{ 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */
132	{ 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, wfdma */
133	{ 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */
134	{ 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */
135	{ 0x0, 0x0, 0x0 }, /* imply end of search */
136};
137
138static u32 mt7996_reg_map_l1(struct mt7996_dev *dev, u32 addr)
139{
140	u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);
141	u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);
142
143	dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,
144			  MT_HIF_REMAP_L1_MASK,
145			  FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));
146	/* use read to push write */
147	dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L1);
148
149	return MT_HIF_REMAP_BASE_L1 + offset;
150}
151
152static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
153{
154	u32 offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr);
155	u32 base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr);
156
157	dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2,
158			  MT_HIF_REMAP_L2_MASK,
159			  FIELD_PREP(MT_HIF_REMAP_L2_MASK, base));
160	/* use read to push write */
161	dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2);
162
163	return MT_HIF_REMAP_BASE_L2 + offset;
164}
165
166static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
167{
168	int i;
169
170	if (addr < 0x100000)
171		return addr;
172
173	for (i = 0; i < dev->reg.map_size; i++) {
174		u32 ofs;
175
176		if (addr < dev->reg.map[i].phys)
177			continue;
178
179		ofs = addr - dev->reg.map[i].phys;
180		if (ofs > dev->reg.map[i].size)
181			continue;
182
183		return dev->reg.map[i].mapped + ofs;
184	}
185
186	return 0;
187}
188
189static u32 __mt7996_reg_remap_addr(struct mt7996_dev *dev, u32 addr)
190{
191	if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) ||
192	    (addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) ||
193	    (addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END))
194		return mt7996_reg_map_l1(dev, addr);
195
196	if (dev_is_pci(dev->mt76.dev) &&
197	    ((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||
198	    addr >= MT_CBTOP2_PHY_START))
199		return mt7996_reg_map_l1(dev, addr);
200
201	/* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */
202	if (addr >= MT_INFRA_MCU_START && addr <= MT_INFRA_MCU_END) {
203		addr = addr - MT_INFRA_MCU_START + MT_INFRA_BASE;
204		return mt7996_reg_map_l1(dev, addr);
205	}
206
207	return mt7996_reg_map_l2(dev, addr);
208}
209
210void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
211			  size_t len)
212{
213	u32 addr = __mt7996_reg_addr(dev, offset);
214
215	if (addr) {
216		memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
217		return;
218	}
219
220	spin_lock_bh(&dev->reg_lock);
221	memcpy_fromio(buf, dev->mt76.mmio.regs +
222			   __mt7996_reg_remap_addr(dev, offset), len);
223	spin_unlock_bh(&dev->reg_lock);
224}
225
226static u32 mt7996_rr(struct mt76_dev *mdev, u32 offset)
227{
228	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
229	u32 addr = __mt7996_reg_addr(dev, offset), val;
230
231	if (addr)
232		return dev->bus_ops->rr(mdev, addr);
233
234	spin_lock_bh(&dev->reg_lock);
235	val = dev->bus_ops->rr(mdev, __mt7996_reg_remap_addr(dev, offset));
236	spin_unlock_bh(&dev->reg_lock);
237
238	return val;
239}
240
241static void mt7996_wr(struct mt76_dev *mdev, u32 offset, u32 val)
242{
243	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
244	u32 addr = __mt7996_reg_addr(dev, offset);
245
246	if (addr) {
247		dev->bus_ops->wr(mdev, addr, val);
248		return;
249	}
250
251	spin_lock_bh(&dev->reg_lock);
252	dev->bus_ops->wr(mdev, __mt7996_reg_remap_addr(dev, offset), val);
253	spin_unlock_bh(&dev->reg_lock);
254}
255
256static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
257{
258	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
259	u32 addr = __mt7996_reg_addr(dev, offset);
260
261	if (addr)
262		return dev->bus_ops->rmw(mdev, addr, mask, val);
263
264	spin_lock_bh(&dev->reg_lock);
265	val = dev->bus_ops->rmw(mdev, __mt7996_reg_remap_addr(dev, offset), mask, val);
266	spin_unlock_bh(&dev->reg_lock);
267
268	return val;
269}
270
271#ifdef CONFIG_NET_MEDIATEK_SOC_WED
272static int mt7996_mmio_wed_reset(struct mtk_wed_device *wed)
273{
274	struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed);
275	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
276	struct mt76_phy *mphy = &dev->mphy;
277	int ret;
278
279	ASSERT_RTNL();
280
281	if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state))
282		return -EBUSY;
283
284	ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_TRIGGER, UNI_CMD_SER_SET_RECOVER_L1,
285				 mphy->band_idx);
286	if (ret)
287		goto out;
288
289	rtnl_unlock();
290	if (!wait_for_completion_timeout(&mdev->mmio.wed_reset, 20 * HZ)) {
291		dev_err(mdev->dev, "wed reset timeout\n");
292		ret = -ETIMEDOUT;
293	}
294	rtnl_lock();
295out:
296	clear_bit(MT76_STATE_WED_RESET, &mphy->state);
297
298	return ret;
299}
300#endif
301
302int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
303			 bool hif2, int *irq)
304{
305#ifdef CONFIG_NET_MEDIATEK_SOC_WED
306	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
307	struct pci_dev *pci_dev = pdev_ptr;
308	u32 hif1_ofs = 0;
309
310	if (!wed_enable)
311		return 0;
312
313	dev->has_rro = true;
314
315	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
316
317	if (hif2)
318		wed = &dev->mt76.mmio.wed_hif2;
319
320	wed->wlan.pci_dev = pci_dev;
321	wed->wlan.bus_type = MTK_WED_BUS_PCIE;
322
323	wed->wlan.base = devm_ioremap(dev->mt76.dev,
324				      pci_resource_start(pci_dev, 0),
325				      pci_resource_len(pci_dev, 0));
326	wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
327
328	if (hif2) {
329		wed->wlan.wpdma_int = wed->wlan.phy_base +
330				      MT_INT_PCIE1_SOURCE_CSR_EXT;
331		wed->wlan.wpdma_mask = wed->wlan.phy_base +
332				       MT_INT_PCIE1_MASK_CSR;
333		wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
334					     MT_TXQ_RING_BASE(0) +
335					     MT7996_TXQ_BAND2 * MT_RING_SIZE;
336		if (dev->has_rro) {
337			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
338						 MT_RXQ_RING_BASE(0) +
339						 MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
340			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
341		} else {
342			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
343						 MT_RXQ_RING_BASE(0) +
344						 MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
345			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
346		}
347
348		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
349		wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
350				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
351				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
352
353		wed->wlan.id = 0x7991;
354		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
355	} else {
356		wed->wlan.hw_rro = dev->has_rro; /* default on */
357		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
358		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
359		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
360				     MT7996_TXQ_BAND0 * MT_RING_SIZE;
361
362		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
363
364		wed->wlan.wpdma_rx = wed->wlan.phy_base +
365				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
366				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
367
368		wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
369					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
370					    MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
371		wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
372					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
373					    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
374		wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
375					MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
376					MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
377
378		wed->wlan.rx_nbuf = 65536;
379		wed->wlan.rx_npkt = dev->hif2 ? 32768 : 24576;
380		wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
381
382		wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
383		wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
384
385		wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
386		wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
387
388		wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
389		wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
390		wed->wlan.rx_pg_tbit[2] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND2) - 1;
391
392		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
393		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
394		if (dev->has_rro) {
395			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
396						 MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
397			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
398		} else {
399			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
400			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
401						  MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
402		}
403		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
404	}
405
406	wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
407	wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
408
409	wed->wlan.amsdu_max_subframes = 8;
410	wed->wlan.amsdu_max_len = 1536;
411
412	wed->wlan.init_buf = mt7996_wed_init_buf;
413	wed->wlan.init_rx_buf = mt76_wed_init_rx_buf;
414	wed->wlan.release_rx_buf = mt76_wed_release_rx_buf;
415	wed->wlan.offload_enable = mt76_wed_offload_enable;
416	wed->wlan.offload_disable = mt76_wed_offload_disable;
417	if (!hif2) {
418		wed->wlan.reset = mt7996_mmio_wed_reset;
419		wed->wlan.reset_complete = mt76_wed_reset_complete;
420	}
421
422	if (mtk_wed_device_attach(wed))
423		return 0;
424
425	*irq = wed->irq;
426	dev->mt76.dma_dev = wed->dev;
427
428	return 1;
429#else
430	return 0;
431#endif
432}
433
434static int mt7996_mmio_init(struct mt76_dev *mdev,
435			    void __iomem *mem_base,
436			    u32 device_id)
437{
438	struct mt76_bus_ops *bus_ops;
439	struct mt7996_dev *dev;
440
441	dev = container_of(mdev, struct mt7996_dev, mt76);
442	mt76_mmio_init(&dev->mt76, mem_base);
443	spin_lock_init(&dev->reg_lock);
444
445	switch (device_id) {
446	case 0x7990:
447		dev->reg.base = mt7996_reg_base;
448		dev->reg.offs_rev = mt7996_offs;
449		dev->reg.map = mt7996_reg_map;
450		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
451		break;
452	case 0x7992:
453		dev->reg.base = mt7996_reg_base;
454		dev->reg.offs_rev = mt7992_offs;
455		dev->reg.map = mt7996_reg_map;
456		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
457		break;
458	default:
459		return -EINVAL;
460	}
461
462	dev->bus_ops = dev->mt76.bus;
463	bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
464			       GFP_KERNEL);
465	if (!bus_ops)
466		return -ENOMEM;
467
468	bus_ops->rr = mt7996_rr;
469	bus_ops->wr = mt7996_wr;
470	bus_ops->rmw = mt7996_rmw;
471	dev->mt76.bus = bus_ops;
472
473	mdev->rev = (device_id << 16) | (mt76_rr(dev, MT_HW_REV) & 0xff);
474
475	dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
476
477	return 0;
478}
479
480void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
481				  u32 clear, u32 set)
482{
483	struct mt76_dev *mdev = &dev->mt76;
484	unsigned long flags;
485
486	spin_lock_irqsave(&mdev->mmio.irq_lock, flags);
487
488	mdev->mmio.irqmask &= ~clear;
489	mdev->mmio.irqmask |= set;
490
491	if (write_reg) {
492		if (mtk_wed_device_active(&mdev->mmio.wed)) {
493			mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
494						    mdev->mmio.irqmask);
495			if (mtk_wed_device_active(&mdev->mmio.wed_hif2)) {
496				mtk_wed_device_irq_set_mask(&mdev->mmio.wed_hif2,
497							    mdev->mmio.irqmask);
498			}
499		} else {
500			mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
501			mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
502		}
503	}
504
505	spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
506}
507
508static void mt7996_rx_poll_complete(struct mt76_dev *mdev,
509				    enum mt76_rxq_id q)
510{
511	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
512
513	mt7996_irq_enable(dev, MT_INT_RX(q));
514}
515
516/* TODO: support 2/4/6/8 MSI-X vectors */
517static void mt7996_irq_tasklet(struct tasklet_struct *t)
518{
519	struct mt7996_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);
520	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
521	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
522	u32 i, intr, mask, intr1;
523
524	if (dev->hif2 && mtk_wed_device_active(wed_hif2)) {
525		mtk_wed_device_irq_set_mask(wed_hif2, 0);
526		intr1 = mtk_wed_device_irq_get(wed_hif2,
527					       dev->mt76.mmio.irqmask);
528		if (intr1 & MT_INT_RX_TXFREE_EXT)
529			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
530	}
531
532	if (mtk_wed_device_active(wed)) {
533		mtk_wed_device_irq_set_mask(wed, 0);
534		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
535		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
536	} else {
537		mt76_wr(dev, MT_INT_MASK_CSR, 0);
538		if (dev->hif2)
539			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
540
541		intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
542		intr &= dev->mt76.mmio.irqmask;
543		mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
544		if (dev->hif2) {
545			intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
546			intr1 &= dev->mt76.mmio.irqmask;
547			mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
548			intr |= intr1;
549		}
550	}
551
552	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
553
554	mask = intr & MT_INT_RX_DONE_ALL;
555	if (intr & MT_INT_TX_DONE_MCU)
556		mask |= MT_INT_TX_DONE_MCU;
557	mt7996_irq_disable(dev, mask);
558
559	if (intr & MT_INT_TX_DONE_MCU)
560		napi_schedule(&dev->mt76.tx_napi);
561
562	for (i = 0; i < __MT_RXQ_MAX; i++) {
563		if ((intr & MT_INT_RX(i)))
564			napi_schedule(&dev->mt76.napi[i]);
565	}
566
567	if (intr & MT_INT_MCU_CMD) {
568		u32 val = mt76_rr(dev, MT_MCU_CMD);
569
570		mt76_wr(dev, MT_MCU_CMD, val);
571		if (val & (MT_MCU_CMD_ERROR_MASK | MT_MCU_CMD_WDT_MASK)) {
572			dev->recovery.state = val;
573			mt7996_reset(dev);
574		}
575	}
576}
577
578irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
579{
580	struct mt7996_dev *dev = dev_instance;
581
582	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
583		mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed, 0);
584	else
585		mt76_wr(dev, MT_INT_MASK_CSR, 0);
586
587	if (dev->hif2) {
588		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
589			mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_hif2, 0);
590		else
591			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
592	}
593
594	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
595		return IRQ_NONE;
596
597	tasklet_schedule(&dev->mt76.irq_tasklet);
598
599	return IRQ_HANDLED;
600}
601
602struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
603				     void __iomem *mem_base, u32 device_id)
604{
605	static const struct mt76_driver_ops drv_ops = {
606		/* txwi_size = txd size + txp size */
607		.txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_fw_txp),
608		.drv_flags = MT_DRV_TXWI_NO_FREE |
609			     MT_DRV_AMSDU_OFFLOAD |
610			     MT_DRV_HW_MGMT_TXQ,
611		.survey_flags = SURVEY_INFO_TIME_TX |
612				SURVEY_INFO_TIME_RX |
613				SURVEY_INFO_TIME_BSS_RX,
614		.token_size = MT7996_TOKEN_SIZE,
615		.tx_prepare_skb = mt7996_tx_prepare_skb,
616		.tx_complete_skb = mt76_connac_tx_complete_skb,
617		.rx_skb = mt7996_queue_rx_skb,
618		.rx_check = mt7996_rx_check,
619		.rx_poll_complete = mt7996_rx_poll_complete,
620		.sta_add = mt7996_mac_sta_add,
621		.sta_remove = mt7996_mac_sta_remove,
622		.update_survey = mt7996_update_channel,
623	};
624	struct mt7996_dev *dev;
625	struct mt76_dev *mdev;
626	int ret;
627
628	mdev = mt76_alloc_device(pdev, sizeof(*dev), &mt7996_ops, &drv_ops);
629	if (!mdev)
630		return ERR_PTR(-ENOMEM);
631
632	dev = container_of(mdev, struct mt7996_dev, mt76);
633
634	ret = mt7996_mmio_init(mdev, mem_base, device_id);
635	if (ret)
636		goto error;
637
638	tasklet_setup(&mdev->irq_tasklet, mt7996_irq_tasklet);
639
640	mt76_wr(dev, MT_INT_MASK_CSR, 0);
641
642	return dev;
643
644error:
645	mt76_free_device(&dev->mt76);
646
647	return ERR_PTR(ret);
648}
649
650static int __init mt7996_init(void)
651{
652	int ret;
653
654	ret = pci_register_driver(&mt7996_hif_driver);
655	if (ret)
656		return ret;
657
658	ret = pci_register_driver(&mt7996_pci_driver);
659	if (ret)
660		pci_unregister_driver(&mt7996_hif_driver);
661
662	return ret;
663}
664
665static void __exit mt7996_exit(void)
666{
667	pci_unregister_driver(&mt7996_pci_driver);
668	pci_unregister_driver(&mt7996_hif_driver);
669}
670
671module_init(mt7996_init);
672module_exit(mt7996_exit);
673MODULE_DESCRIPTION("MediaTek MT7996 MMIO helpers");
674MODULE_LICENSE("Dual BSD/GPL");
675