1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc.
3  *
4  * Author: Ryder Lee <ryder.lee@mediatek.com>
5  */
6 
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/pci.h>
10 
11 #include "mt7915.h"
12 #include "mac.h"
13 #include "../trace.h"
14 
15 static LIST_HEAD(hif_list);
16 static DEFINE_SPINLOCK(hif_lock);
17 static u32 hif_idx;
18 
19 static const struct pci_device_id mt7915_pci_device_table[] = {
20 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7915) },
21 	{ },
22 };
23 
24 static const struct pci_device_id mt7915_hif_device_table[] = {
25 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7916) },
26 	{ },
27 };
28 
29 void mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev, bool write_reg,
30 				  u32 clear, u32 set)
31 {
32 	struct mt76_dev *mdev = &dev->mt76;
33 	unsigned long flags;
34 
35 	spin_lock_irqsave(&mdev->mmio.irq_lock, flags);
36 
37 	mdev->mmio.irqmask &= ~clear;
38 	mdev->mmio.irqmask |= set;
39 
40 	if (write_reg) {
41 		mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
42 		mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
43 	}
44 
45 	spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
46 }
47 
48 static struct mt7915_hif *
49 mt7915_pci_get_hif2(struct mt7915_dev *dev)
50 {
51 	struct mt7915_hif *hif;
52 	u32 val;
53 
54 	spin_lock_bh(&hif_lock);
55 
56 	list_for_each_entry(hif, &hif_list, list) {
57 		val = readl(hif->regs + MT_PCIE_RECOG_ID);
58 		val &= MT_PCIE_RECOG_ID_MASK;
59 		if (val != dev->hif_idx)
60 			continue;
61 
62 		get_device(hif->dev);
63 		goto out;
64 	}
65 	hif = NULL;
66 
67 out:
68 	spin_unlock_bh(&hif_lock);
69 
70 	return hif;
71 }
72 
73 static void mt7915_put_hif2(struct mt7915_hif *hif)
74 {
75 	if (!hif)
76 		return;
77 
78 	put_device(hif->dev);
79 }
80 
81 static void
82 mt7915_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
83 {
84 	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
85 	static const u32 rx_irq_mask[] = {
86 		[MT_RXQ_MAIN] = MT_INT_RX_DONE_DATA0,
87 		[MT_RXQ_EXT] = MT_INT_RX_DONE_DATA1,
88 		[MT_RXQ_MCU] = MT_INT_RX_DONE_WM,
89 		[MT_RXQ_MCU_WA] = MT_INT_RX_DONE_WA,
90 		[MT_RXQ_EXT_WA] = MT_INT_RX_DONE_WA_EXT,
91 	};
92 
93 	mt7915_irq_enable(dev, rx_irq_mask[q]);
94 }
95 
96 /* TODO: support 2/4/6/8 MSI-X vectors */
97 static irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
98 {
99 	struct mt7915_dev *dev = dev_instance;
100 	u32 intr, intr1, mask;
101 
102 	intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
103 	intr &= dev->mt76.mmio.irqmask;
104 	mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
105 
106 	if (dev->hif2) {
107 		intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
108 		intr1 &= dev->mt76.mmio.irqmask;
109 		mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
110 
111 		intr |= intr1;
112 	}
113 
114 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
115 		return IRQ_NONE;
116 
117 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
118 
119 	mask = intr & MT_INT_RX_DONE_ALL;
120 	if (intr & MT_INT_TX_DONE_MCU)
121 		mask |= MT_INT_TX_DONE_MCU;
122 
123 	mt7915_irq_disable(dev, mask);
124 
125 	if (intr & MT_INT_TX_DONE_MCU)
126 		napi_schedule(&dev->mt76.tx_napi);
127 
128 	if (intr & MT_INT_RX_DONE_DATA0)
129 		napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]);
130 
131 	if (intr & MT_INT_RX_DONE_DATA1)
132 		napi_schedule(&dev->mt76.napi[MT_RXQ_EXT]);
133 
134 	if (intr & MT_INT_RX_DONE_WM)
135 		napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]);
136 
137 	if (intr & MT_INT_RX_DONE_WA)
138 		napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]);
139 
140 	if (intr & MT_INT_RX_DONE_WA_EXT)
141 		napi_schedule(&dev->mt76.napi[MT_RXQ_EXT_WA]);
142 
143 	if (intr & MT_INT_MCU_CMD) {
144 		u32 val = mt76_rr(dev, MT_MCU_CMD);
145 
146 		mt76_wr(dev, MT_MCU_CMD, val);
147 		if (val & MT_MCU_CMD_ERROR_MASK) {
148 			dev->reset_state = val;
149 			ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
150 			wake_up(&dev->reset_wait);
151 		}
152 	}
153 
154 	return IRQ_HANDLED;
155 }
156 
157 static void mt7915_pci_init_hif2(struct mt7915_dev *dev)
158 {
159 	struct mt7915_hif *hif;
160 
161 	dev->hif_idx = ++hif_idx;
162 	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL))
163 		return;
164 
165 	mt76_wr(dev, MT_PCIE_RECOG_ID, dev->hif_idx | MT_PCIE_RECOG_ID_SEM);
166 
167 	hif = mt7915_pci_get_hif2(dev);
168 	if (!hif)
169 		return;
170 
171 	dev->hif2 = hif;
172 
173 	mt76_wr(dev, MT_INT1_MASK_CSR, 0);
174 
175 	if (devm_request_irq(dev->mt76.dev, hif->irq, mt7915_irq_handler,
176 			     IRQF_SHARED, KBUILD_MODNAME "-hif", dev)) {
177 		mt7915_put_hif2(hif);
178 		hif = NULL;
179 	}
180 
181 	/* master switch of PCIe tnterrupt enable */
182 	mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
183 }
184 
185 static int mt7915_pci_hif2_probe(struct pci_dev *pdev)
186 {
187 	struct mt7915_hif *hif;
188 
189 	hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
190 	if (!hif)
191 		return -ENOMEM;
192 
193 	hif->dev = &pdev->dev;
194 	hif->regs = pcim_iomap_table(pdev)[0];
195 	hif->irq = pdev->irq;
196 	spin_lock_bh(&hif_lock);
197 	list_add(&hif->list, &hif_list);
198 	spin_unlock_bh(&hif_lock);
199 	pci_set_drvdata(pdev, hif);
200 
201 	return 0;
202 }
203 
204 static int mt7915_pci_probe(struct pci_dev *pdev,
205 			    const struct pci_device_id *id)
206 {
207 	static const struct mt76_driver_ops drv_ops = {
208 		/* txwi_size = txd size + txp size */
209 		.txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp),
210 		.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |
211 			     MT_DRV_AMSDU_OFFLOAD,
212 		.survey_flags = SURVEY_INFO_TIME_TX |
213 				SURVEY_INFO_TIME_RX |
214 				SURVEY_INFO_TIME_BSS_RX,
215 		.token_size = MT7915_TOKEN_SIZE,
216 		.tx_prepare_skb = mt7915_tx_prepare_skb,
217 		.tx_complete_skb = mt7915_tx_complete_skb,
218 		.rx_skb = mt7915_queue_rx_skb,
219 		.rx_poll_complete = mt7915_rx_poll_complete,
220 		.sta_ps = mt7915_sta_ps,
221 		.sta_add = mt7915_mac_sta_add,
222 		.sta_remove = mt7915_mac_sta_remove,
223 		.update_survey = mt7915_update_channel,
224 	};
225 	struct mt7915_dev *dev;
226 	struct mt76_dev *mdev;
227 	int ret;
228 
229 	ret = pcim_enable_device(pdev);
230 	if (ret)
231 		return ret;
232 
233 	ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
234 	if (ret)
235 		return ret;
236 
237 	pci_set_master(pdev);
238 
239 	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
240 	if (ret)
241 		return ret;
242 
243 	if (id->device == 0x7916)
244 		return mt7915_pci_hif2_probe(pdev);
245 
246 	mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7915_ops,
247 				 &drv_ops);
248 	if (!mdev)
249 		return -ENOMEM;
250 
251 	dev = container_of(mdev, struct mt7915_dev, mt76);
252 
253 	ret = mt7915_mmio_init(mdev, pcim_iomap_table(pdev)[0], pdev->irq);
254 	if (ret)
255 		goto error;
256 
257 	/* master switch of PCIe tnterrupt enable */
258 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
259 
260 	ret = devm_request_irq(mdev->dev, pdev->irq, mt7915_irq_handler,
261 			       IRQF_SHARED, KBUILD_MODNAME, dev);
262 	if (ret)
263 		goto error;
264 
265 	mt7915_pci_init_hif2(dev);
266 
267 	ret = mt7915_register_device(dev);
268 	if (ret)
269 		goto error;
270 
271 	return 0;
272 error:
273 	mt76_free_device(&dev->mt76);
274 
275 	return ret;
276 }
277 
278 static void mt7915_hif_remove(struct pci_dev *pdev)
279 {
280 	struct mt7915_hif *hif = pci_get_drvdata(pdev);
281 
282 	list_del(&hif->list);
283 }
284 
285 static void mt7915_pci_remove(struct pci_dev *pdev)
286 {
287 	struct mt76_dev *mdev;
288 	struct mt7915_dev *dev;
289 
290 	mdev = pci_get_drvdata(pdev);
291 	dev = container_of(mdev, struct mt7915_dev, mt76);
292 	mt7915_put_hif2(dev->hif2);
293 	mt7915_unregister_device(dev);
294 }
295 
296 static struct pci_driver mt7915_hif_driver = {
297 	.name		= KBUILD_MODNAME "_hif",
298 	.id_table	= mt7915_hif_device_table,
299 	.probe		= mt7915_pci_probe,
300 	.remove		= mt7915_hif_remove,
301 };
302 
303 static struct pci_driver mt7915_pci_driver = {
304 	.name		= KBUILD_MODNAME,
305 	.id_table	= mt7915_pci_device_table,
306 	.probe		= mt7915_pci_probe,
307 	.remove		= mt7915_pci_remove,
308 };
309 
310 static int __init mt7915_init(void)
311 {
312 	int ret;
313 
314 	ret = pci_register_driver(&mt7915_hif_driver);
315 	if (ret)
316 		return ret;
317 
318 	ret = pci_register_driver(&mt7915_pci_driver);
319 	if (ret)
320 		pci_unregister_driver(&mt7915_hif_driver);
321 
322 	return ret;
323 }
324 
325 static void __exit mt7915_exit(void)
326 {
327     pci_unregister_driver(&mt7915_pci_driver);
328     pci_unregister_driver(&mt7915_hif_driver);
329 }
330 
331 module_init(mt7915_init);
332 module_exit(mt7915_exit);
333 
334 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);
335 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);
336 MODULE_FIRMWARE(MT7915_FIRMWARE_WA);
337 MODULE_FIRMWARE(MT7915_FIRMWARE_WM);
338 MODULE_FIRMWARE(MT7915_ROM_PATCH);
339 MODULE_LICENSE("Dual BSD/GPL");
340