1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3 * Copyright (C) 2022 MediaTek Inc.
4 */
5
6 #if defined(__FreeBSD__)
7 #define LINUXKPI_PARAM_PREFIX mt7996_pci_
8 #endif
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/pci.h>
13
14 #include "mt7996.h"
15 #include "mac.h"
16 #include "../trace.h"
17
18 static LIST_HEAD(hif_list);
19 static DEFINE_SPINLOCK(hif_lock);
20 static u32 hif_idx;
21
22 static const struct pci_device_id mt7996_pci_device_table[] = {
23 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7996_DEVICE_ID) },
24 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7992_DEVICE_ID) },
25 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7990_DEVICE_ID) },
26 { },
27 };
28
29 static const struct pci_device_id mt7996_hif_device_table[] = {
30 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7996_DEVICE_ID_2) },
31 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7992_DEVICE_ID_2) },
32 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, MT7990_DEVICE_ID_2) },
33 { },
34 };
35
mt7996_pci_get_hif2(u32 idx)36 static struct mt7996_hif *mt7996_pci_get_hif2(u32 idx)
37 {
38 struct mt7996_hif *hif;
39 u32 val;
40
41 spin_lock_bh(&hif_lock);
42
43 list_for_each_entry(hif, &hif_list, list) {
44 #if defined(__linux__)
45 val = readl(hif->regs + MT_PCIE_RECOG_ID);
46 #elif defined(__FreeBSD__)
47 val = readl((u8 *)hif->regs + MT_PCIE_RECOG_ID);
48 #endif
49 val &= MT_PCIE_RECOG_ID_MASK;
50 if (val != idx)
51 continue;
52
53 get_device(hif->dev);
54 goto out;
55 }
56 hif = NULL;
57
58 out:
59 spin_unlock_bh(&hif_lock);
60
61 return hif;
62 }
63
mt7996_put_hif2(struct mt7996_hif * hif)64 static void mt7996_put_hif2(struct mt7996_hif *hif)
65 {
66 if (!hif)
67 return;
68
69 put_device(hif->dev);
70 }
71
mt7996_pci_init_hif2(struct pci_dev * pdev)72 static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev)
73 {
74 hif_idx++;
75
76 #if defined(__linux__)
77 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, MT7996_DEVICE_ID_2, NULL) &&
78 !pci_get_device(PCI_VENDOR_ID_MEDIATEK, MT7992_DEVICE_ID_2, NULL) &&
79 !pci_get_device(PCI_VENDOR_ID_MEDIATEK, MT7990_DEVICE_ID_2, NULL))
80 #elif defined(__FreeBSD__)
81 if (!linuxkpi_pci_get_device(PCI_VENDOR_ID_MEDIATEK, MT7996_DEVICE_ID_2, NULL) &&
82 !linuxkpi_pci_get_device(PCI_VENDOR_ID_MEDIATEK, MT7992_DEVICE_ID_2, NULL) &&
83 !linuxkpi_pci_get_device(PCI_VENDOR_ID_MEDIATEK, MT7990_DEVICE_ID_2, NULL))
84 #endif
85 return NULL;
86
87 writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
88 #if defined(__linux__)
89 pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);
90 #elif defined(__FreeBSD__)
91 (u8 *)(pcim_iomap_table(pdev)[0]) + MT_PCIE_RECOG_ID);
92 #endif
93
94 return mt7996_pci_get_hif2(hif_idx);
95 }
96
mt7996_pci_hif2_probe(struct pci_dev * pdev)97 static int mt7996_pci_hif2_probe(struct pci_dev *pdev)
98 {
99 struct mt7996_hif *hif;
100
101 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
102 if (!hif)
103 return -ENOMEM;
104
105 hif->dev = &pdev->dev;
106 hif->regs = pcim_iomap_table(pdev)[0];
107 hif->irq = pdev->irq;
108 pcie_bandwidth_available(pdev, NULL, &hif->speed, &hif->width);
109 spin_lock_bh(&hif_lock);
110 list_add(&hif->list, &hif_list);
111 spin_unlock_bh(&hif_lock);
112 pci_set_drvdata(pdev, hif);
113
114 return 0;
115 }
116
mt7996_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)117 static int mt7996_pci_probe(struct pci_dev *pdev,
118 const struct pci_device_id *id)
119 {
120 struct pci_dev *hif2_dev;
121 struct mt7996_hif *hif2;
122 struct mt7996_dev *dev;
123 int irq, hif2_irq, ret;
124 struct mt76_dev *mdev;
125
126 ret = pcim_enable_device(pdev);
127 if (ret)
128 return ret;
129
130 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
131 if (ret)
132 return ret;
133
134 pci_set_master(pdev);
135
136 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
137 if (ret)
138 return ret;
139
140 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
141 if (ret)
142 return ret;
143
144 mt76_pci_disable_aspm(pdev);
145
146 if (id->device == MT7996_DEVICE_ID_2 ||
147 id->device == MT7992_DEVICE_ID_2 ||
148 id->device == MT7990_DEVICE_ID_2)
149 return mt7996_pci_hif2_probe(pdev);
150
151 dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
152 id->device);
153 if (IS_ERR(dev))
154 return PTR_ERR(dev);
155
156 mdev = &dev->mt76;
157 mt7996_wfsys_reset(dev);
158 hif2 = mt7996_pci_init_hif2(pdev);
159 dev->hif2 = hif2;
160
161 mt76_npu_init(mdev, pci_resource_start(pdev, 0),
162 pdev->bus && pci_domain_nr(pdev->bus) ? 3 : 2);
163
164 ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
165 if (ret < 0)
166 goto free_wed_or_irq_vector;
167
168 if (!ret) {
169 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
170 if (ret < 0)
171 goto free_device;
172
173 irq = pdev->irq;
174 }
175
176 ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
177 IRQF_SHARED, KBUILD_MODNAME, dev);
178 if (ret)
179 goto free_wed_or_irq_vector;
180
181 mt76_wr(dev, MT_INT_MASK_CSR, 0);
182 /* master switch of PCIe interrupt enable */
183 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
184
185 if (hif2) {
186 hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
187
188 ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &hif2_irq);
189 if (ret < 0)
190 goto free_hif2_wed_irq_vector;
191
192 if (!ret) {
193 ret = pci_alloc_irq_vectors(hif2_dev, 1, 1,
194 PCI_IRQ_ALL_TYPES);
195 if (ret < 0)
196 goto free_hif2;
197
198 dev->hif2->irq = hif2_dev->irq;
199 hif2_irq = dev->hif2->irq;
200 }
201
202 ret = devm_request_irq(mdev->dev, hif2_irq, mt7996_irq_handler,
203 IRQF_SHARED, KBUILD_MODNAME "-hif",
204 dev);
205 if (ret)
206 goto free_hif2_wed_irq_vector;
207
208 mt76_wr(dev, MT_INT1_MASK_CSR, 0);
209 /* master switch of PCIe tnterrupt enable */
210 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
211 }
212
213 ret = mt7996_register_device(dev);
214 if (ret)
215 goto free_hif2_irq;
216
217 return 0;
218
219 free_hif2_irq:
220 if (dev->hif2)
221 devm_free_irq(mdev->dev, hif2_irq, dev);
222 free_hif2_wed_irq_vector:
223 if (dev->hif2) {
224 if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
225 mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2);
226 else
227 pci_free_irq_vectors(hif2_dev);
228 }
229 free_hif2:
230 if (dev->hif2)
231 put_device(dev->hif2->dev);
232 devm_free_irq(mdev->dev, irq, dev);
233 free_wed_or_irq_vector:
234 if (mtk_wed_device_active(&dev->mt76.mmio.wed))
235 mtk_wed_device_detach(&dev->mt76.mmio.wed);
236 else
237 pci_free_irq_vectors(pdev);
238 free_device:
239 mt76_free_device(&dev->mt76);
240
241 return ret;
242 }
243
mt7996_hif_remove(struct pci_dev * pdev)244 static void mt7996_hif_remove(struct pci_dev *pdev)
245 {
246 struct mt7996_hif *hif = pci_get_drvdata(pdev);
247
248 list_del(&hif->list);
249 }
250
mt7996_pci_remove(struct pci_dev * pdev)251 static void mt7996_pci_remove(struct pci_dev *pdev)
252 {
253 struct mt76_dev *mdev;
254 struct mt7996_dev *dev;
255
256 mdev = pci_get_drvdata(pdev);
257 dev = container_of(mdev, struct mt7996_dev, mt76);
258 mt7996_put_hif2(dev->hif2);
259 mt7996_unregister_device(dev);
260 }
261
262 struct pci_driver mt7996_hif_driver = {
263 .name = KBUILD_MODNAME "_hif",
264 .id_table = mt7996_hif_device_table,
265 .probe = mt7996_pci_probe,
266 .remove = mt7996_hif_remove,
267 };
268
269 struct pci_driver mt7996_pci_driver = {
270 .name = KBUILD_MODNAME,
271 .id_table = mt7996_pci_device_table,
272 .probe = mt7996_pci_probe,
273 .remove = mt7996_pci_remove,
274 };
275
276 MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);
277 MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);
278 MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
279 MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
280 MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
281 MODULE_FIRMWARE(MT7996_ROM_PATCH);
282 MODULE_FIRMWARE(MT7992_FIRMWARE_WA);
283 MODULE_FIRMWARE(MT7992_FIRMWARE_WM);
284 MODULE_FIRMWARE(MT7992_FIRMWARE_DSP);
285 MODULE_FIRMWARE(MT7992_ROM_PATCH);
286 MODULE_FIRMWARE(MT7990_FIRMWARE_WM);
287 MODULE_FIRMWARE(MT7990_ROM_PATCH);
288 #if defined(__FreeBSD__)
289 MODULE_VERSION(mt7996_pci, 1);
290 MODULE_DEPEND(mt7996_pci, mt76_core, 1, 1, 1);
291 MODULE_DEPEND(mt7996_pci, linuxkpi, 1, 1, 1);
292 MODULE_DEPEND(mt7996_pci, linuxkpi_wlan, 1, 1, 1);
293 #endif
294