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 bool wed_enable = false;
16 module_param(wed_enable, bool, 0644);
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 mt7915_pci_device_table[] = {
23 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7915) },
24 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7906) },
25 { },
26 };
27
28 static const struct pci_device_id mt7915_hif_device_table[] = {
29 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7916) },
30 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x790a) },
31 { },
32 };
33
mt7915_pci_get_hif2(u32 idx)34 static struct mt7915_hif *mt7915_pci_get_hif2(u32 idx)
35 {
36 struct mt7915_hif *hif;
37 u32 val;
38
39 spin_lock_bh(&hif_lock);
40
41 list_for_each_entry(hif, &hif_list, list) {
42 val = readl(hif->regs + MT_PCIE_RECOG_ID);
43 val &= MT_PCIE_RECOG_ID_MASK;
44 if (val != idx)
45 continue;
46
47 get_device(hif->dev);
48 goto out;
49 }
50 hif = NULL;
51
52 out:
53 spin_unlock_bh(&hif_lock);
54
55 return hif;
56 }
57
mt7915_put_hif2(struct mt7915_hif * hif)58 static void mt7915_put_hif2(struct mt7915_hif *hif)
59 {
60 if (!hif)
61 return;
62
63 put_device(hif->dev);
64 }
65
mt7915_pci_init_hif2(struct pci_dev * pdev)66 static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev)
67 {
68 struct pci_dev *tmp_pdev;
69
70 hif_idx++;
71
72 tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL);
73 if (!tmp_pdev) {
74 tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL);
75 if (!tmp_pdev)
76 return NULL;
77 }
78 pci_dev_put(tmp_pdev);
79
80 writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
81 pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);
82
83 return mt7915_pci_get_hif2(hif_idx);
84 }
85
mt7915_pci_hif2_probe(struct pci_dev * pdev)86 static int mt7915_pci_hif2_probe(struct pci_dev *pdev)
87 {
88 struct mt7915_hif *hif;
89
90 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
91 if (!hif)
92 return -ENOMEM;
93
94 hif->dev = &pdev->dev;
95 hif->regs = pcim_iomap_table(pdev)[0];
96 hif->irq = pdev->irq;
97 spin_lock_bh(&hif_lock);
98 list_add(&hif->list, &hif_list);
99 spin_unlock_bh(&hif_lock);
100 pci_set_drvdata(pdev, hif);
101
102 return 0;
103 }
104
105 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
mt7915_wed_offload_enable(struct mtk_wed_device * wed)106 static int mt7915_wed_offload_enable(struct mtk_wed_device *wed)
107 {
108 struct mt7915_dev *dev;
109 struct mt7915_phy *phy;
110 int ret;
111
112 dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
113
114 spin_lock_bh(&dev->mt76.token_lock);
115 dev->mt76.token_size = wed->wlan.token_start;
116 spin_unlock_bh(&dev->mt76.token_lock);
117
118 ret = wait_event_timeout(dev->mt76.tx_wait,
119 !dev->mt76.wed_token_count, HZ);
120 if (!ret)
121 return -EAGAIN;
122
123 phy = &dev->phy;
124 mt76_set(dev, MT_AGG_ACR4(phy->band_idx), MT_AGG_ACR_PPDU_TXS2H);
125
126 phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
127 if (phy)
128 mt76_set(dev, MT_AGG_ACR4(phy->band_idx),
129 MT_AGG_ACR_PPDU_TXS2H);
130
131 return 0;
132 }
133
mt7915_wed_offload_disable(struct mtk_wed_device * wed)134 static void mt7915_wed_offload_disable(struct mtk_wed_device *wed)
135 {
136 struct mt7915_dev *dev;
137 struct mt7915_phy *phy;
138
139 dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
140
141 spin_lock_bh(&dev->mt76.token_lock);
142 dev->mt76.token_size = MT7915_TOKEN_SIZE;
143 spin_unlock_bh(&dev->mt76.token_lock);
144
145 /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
146 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
147 */
148 phy = &dev->phy;
149 mt76_clear(dev, MT_AGG_ACR4(phy->band_idx), MT_AGG_ACR_PPDU_TXS2H);
150
151 phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
152 if (phy)
153 mt76_clear(dev, MT_AGG_ACR4(phy->band_idx),
154 MT_AGG_ACR_PPDU_TXS2H);
155 }
156 #endif
157
158 static int
mt7915_pci_wed_init(struct mt7915_dev * dev,struct pci_dev * pdev,int * irq)159 mt7915_pci_wed_init(struct mt7915_dev *dev, struct pci_dev *pdev, int *irq)
160 {
161 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
162 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
163 int ret;
164
165 if (!wed_enable)
166 return 0;
167
168 wed->wlan.pci_dev = pdev;
169 wed->wlan.wpdma_phys = pci_resource_start(pdev, 0) +
170 MT_WFDMA_EXT_CSR_BASE;
171 wed->wlan.nbuf = 4096;
172 wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf;
173 wed->wlan.init_buf = mt7915_wed_init_buf;
174 wed->wlan.offload_enable = mt7915_wed_offload_enable;
175 wed->wlan.offload_disable = mt7915_wed_offload_disable;
176
177 if (mtk_wed_device_attach(wed) != 0)
178 return 0;
179
180 *irq = wed->irq;
181 dev->mt76.dma_dev = wed->dev;
182
183 ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
184 if (ret)
185 return ret;
186
187 return 1;
188 #else
189 return 0;
190 #endif
191 }
192
mt7915_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)193 static int mt7915_pci_probe(struct pci_dev *pdev,
194 const struct pci_device_id *id)
195 {
196 struct mt7915_hif *hif2 = NULL;
197 struct mt7915_dev *dev;
198 struct mt76_dev *mdev;
199 int irq;
200 int ret;
201
202 ret = pcim_enable_device(pdev);
203 if (ret)
204 return ret;
205
206 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
207 if (ret)
208 return ret;
209
210 pci_set_master(pdev);
211
212 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
213 if (ret)
214 return ret;
215
216 mt76_pci_disable_aspm(pdev);
217
218 if (id->device == 0x7916 || id->device == 0x790a)
219 return mt7915_pci_hif2_probe(pdev);
220
221 dev = mt7915_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
222 id->device);
223 if (IS_ERR(dev))
224 return PTR_ERR(dev);
225
226 mdev = &dev->mt76;
227 mt7915_wfsys_reset(dev);
228 hif2 = mt7915_pci_init_hif2(pdev);
229
230 ret = mt7915_pci_wed_init(dev, pdev, &irq);
231 if (ret < 0)
232 goto free_wed_or_irq_vector;
233
234 if (!ret) {
235 hif2 = mt7915_pci_init_hif2(pdev);
236
237 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
238 if (ret < 0)
239 goto free_device;
240
241 irq = pdev->irq;
242 }
243
244 ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
245 IRQF_SHARED, KBUILD_MODNAME, dev);
246 if (ret)
247 goto free_wed_or_irq_vector;
248
249 /* master switch of PCIe tnterrupt enable */
250 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
251
252 if (hif2) {
253 dev->hif2 = hif2;
254
255 mt76_wr(dev, MT_INT1_MASK_CSR, 0);
256 /* master switch of PCIe tnterrupt enable */
257 if (is_mt7915(mdev))
258 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
259 else
260 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff);
261
262 ret = devm_request_irq(mdev->dev, dev->hif2->irq,
263 mt7915_irq_handler, IRQF_SHARED,
264 KBUILD_MODNAME "-hif", dev);
265 if (ret)
266 goto free_hif2;
267 }
268
269 ret = mt7915_register_device(dev);
270 if (ret)
271 goto free_hif2_irq;
272
273 return 0;
274
275 free_hif2_irq:
276 if (dev->hif2)
277 devm_free_irq(mdev->dev, dev->hif2->irq, dev);
278 free_hif2:
279 if (dev->hif2)
280 put_device(dev->hif2->dev);
281 devm_free_irq(mdev->dev, irq, dev);
282 free_wed_or_irq_vector:
283 if (mtk_wed_device_active(&mdev->mmio.wed))
284 mtk_wed_device_detach(&mdev->mmio.wed);
285 else
286 pci_free_irq_vectors(pdev);
287 free_device:
288 mt76_free_device(&dev->mt76);
289
290 return ret;
291 }
292
mt7915_hif_remove(struct pci_dev * pdev)293 static void mt7915_hif_remove(struct pci_dev *pdev)
294 {
295 struct mt7915_hif *hif = pci_get_drvdata(pdev);
296
297 list_del(&hif->list);
298 }
299
mt7915_pci_remove(struct pci_dev * pdev)300 static void mt7915_pci_remove(struct pci_dev *pdev)
301 {
302 struct mt76_dev *mdev;
303 struct mt7915_dev *dev;
304
305 mdev = pci_get_drvdata(pdev);
306 dev = container_of(mdev, struct mt7915_dev, mt76);
307 mt7915_put_hif2(dev->hif2);
308 mt7915_unregister_device(dev);
309 }
310
311 struct pci_driver mt7915_hif_driver = {
312 .name = KBUILD_MODNAME "_hif",
313 .id_table = mt7915_hif_device_table,
314 .probe = mt7915_pci_probe,
315 .remove = mt7915_hif_remove,
316 };
317
318 struct pci_driver mt7915_pci_driver = {
319 .name = KBUILD_MODNAME,
320 .id_table = mt7915_pci_device_table,
321 .probe = mt7915_pci_probe,
322 .remove = mt7915_pci_remove,
323 };
324
325 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);
326 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);
327 MODULE_FIRMWARE(MT7915_FIRMWARE_WA);
328 MODULE_FIRMWARE(MT7915_FIRMWARE_WM);
329 MODULE_FIRMWARE(MT7915_ROM_PATCH);
330 MODULE_FIRMWARE(MT7916_FIRMWARE_WA);
331 MODULE_FIRMWARE(MT7916_FIRMWARE_WM);
332 MODULE_FIRMWARE(MT7916_ROM_PATCH);
333