1 // SPDX-License-Identifier: ISC 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 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 64 static void mt7996_put_hif2(struct mt7996_hif *hif) 65 { 66 if (!hif) 67 return; 68 69 put_device(hif->dev); 70 } 71 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 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 spin_lock_bh(&hif_lock); 109 list_add(&hif->list, &hif_list); 110 spin_unlock_bh(&hif_lock); 111 pci_set_drvdata(pdev, hif); 112 113 return 0; 114 } 115 116 static int mt7996_pci_probe(struct pci_dev *pdev, 117 const struct pci_device_id *id) 118 { 119 struct pci_dev *hif2_dev; 120 struct mt7996_hif *hif2; 121 struct mt7996_dev *dev; 122 int irq, hif2_irq, ret; 123 struct mt76_dev *mdev; 124 125 ret = pcim_enable_device(pdev); 126 if (ret) 127 return ret; 128 129 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 130 if (ret) 131 return ret; 132 133 pci_set_master(pdev); 134 135 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); 136 if (ret) 137 return ret; 138 139 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 140 if (ret) 141 return ret; 142 143 mt76_pci_disable_aspm(pdev); 144 145 if (id->device == MT7996_DEVICE_ID_2 || 146 id->device == MT7992_DEVICE_ID_2 || 147 id->device == MT7990_DEVICE_ID_2) 148 return mt7996_pci_hif2_probe(pdev); 149 150 dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0], 151 id->device); 152 if (IS_ERR(dev)) 153 return PTR_ERR(dev); 154 155 mdev = &dev->mt76; 156 mt7996_wfsys_reset(dev); 157 hif2 = mt7996_pci_init_hif2(pdev); 158 159 ret = mt7996_mmio_wed_init(dev, pdev, false, &irq); 160 if (ret < 0) 161 goto free_wed_or_irq_vector; 162 163 if (!ret) { 164 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 165 if (ret < 0) 166 goto free_device; 167 168 irq = pdev->irq; 169 } 170 171 ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler, 172 IRQF_SHARED, KBUILD_MODNAME, dev); 173 if (ret) 174 goto free_wed_or_irq_vector; 175 176 mt76_wr(dev, MT_INT_MASK_CSR, 0); 177 /* master switch of PCIe tnterrupt enable */ 178 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 179 180 if (hif2) { 181 hif2_dev = container_of(hif2->dev, struct pci_dev, dev); 182 dev->hif2 = hif2; 183 184 ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &hif2_irq); 185 if (ret < 0) 186 goto free_hif2_wed_irq_vector; 187 188 if (!ret) { 189 ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, 190 PCI_IRQ_ALL_TYPES); 191 if (ret < 0) 192 goto free_hif2; 193 194 dev->hif2->irq = hif2_dev->irq; 195 hif2_irq = dev->hif2->irq; 196 } 197 198 ret = devm_request_irq(mdev->dev, hif2_irq, mt7996_irq_handler, 199 IRQF_SHARED, KBUILD_MODNAME "-hif", 200 dev); 201 if (ret) 202 goto free_hif2_wed_irq_vector; 203 204 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 205 /* master switch of PCIe tnterrupt enable */ 206 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); 207 } 208 209 ret = mt7996_register_device(dev); 210 if (ret) 211 goto free_hif2_irq; 212 213 return 0; 214 215 free_hif2_irq: 216 if (dev->hif2) 217 devm_free_irq(mdev->dev, hif2_irq, dev); 218 free_hif2_wed_irq_vector: 219 if (dev->hif2) { 220 if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) 221 mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2); 222 else 223 pci_free_irq_vectors(hif2_dev); 224 } 225 free_hif2: 226 if (dev->hif2) 227 put_device(dev->hif2->dev); 228 devm_free_irq(mdev->dev, irq, dev); 229 free_wed_or_irq_vector: 230 if (mtk_wed_device_active(&dev->mt76.mmio.wed)) 231 mtk_wed_device_detach(&dev->mt76.mmio.wed); 232 else 233 pci_free_irq_vectors(pdev); 234 free_device: 235 mt76_free_device(&dev->mt76); 236 237 return ret; 238 } 239 240 static void mt7996_hif_remove(struct pci_dev *pdev) 241 { 242 struct mt7996_hif *hif = pci_get_drvdata(pdev); 243 244 list_del(&hif->list); 245 } 246 247 static void mt7996_pci_remove(struct pci_dev *pdev) 248 { 249 struct mt76_dev *mdev; 250 struct mt7996_dev *dev; 251 252 mdev = pci_get_drvdata(pdev); 253 dev = container_of(mdev, struct mt7996_dev, mt76); 254 mt7996_put_hif2(dev->hif2); 255 mt7996_unregister_device(dev); 256 } 257 258 struct pci_driver mt7996_hif_driver = { 259 .name = KBUILD_MODNAME "_hif", 260 .id_table = mt7996_hif_device_table, 261 .probe = mt7996_pci_probe, 262 .remove = mt7996_hif_remove, 263 }; 264 265 struct pci_driver mt7996_pci_driver = { 266 .name = KBUILD_MODNAME, 267 .id_table = mt7996_pci_device_table, 268 .probe = mt7996_pci_probe, 269 .remove = mt7996_pci_remove, 270 }; 271 272 MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table); 273 MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table); 274 MODULE_FIRMWARE(MT7996_FIRMWARE_WA); 275 MODULE_FIRMWARE(MT7996_FIRMWARE_WM); 276 MODULE_FIRMWARE(MT7996_FIRMWARE_DSP); 277 MODULE_FIRMWARE(MT7996_ROM_PATCH); 278 MODULE_FIRMWARE(MT7992_FIRMWARE_WA); 279 MODULE_FIRMWARE(MT7992_FIRMWARE_WM); 280 MODULE_FIRMWARE(MT7992_FIRMWARE_DSP); 281 MODULE_FIRMWARE(MT7992_ROM_PATCH); 282 MODULE_FIRMWARE(MT7990_FIRMWARE_WM); 283 MODULE_FIRMWARE(MT7990_ROM_PATCH); 284 #if defined(__FreeBSD__) 285 MODULE_VERSION(mt7996_pci, 1); 286 MODULE_DEPEND(mt7996_pci, linuxkpi, 1, 1, 1); 287 MODULE_DEPEND(mt7996_pci, linuxkpi_wlan, 1, 1, 1); 288 MODULE_DEPEND(mt7996_pci, mt76_core, 1, 1, 1); 289 #endif 290