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 void mt7915_irq_tasklet(struct tasklet_struct *t) 98 { 99 struct mt7915_dev *dev = from_tasklet(dev, t, irq_tasklet); 100 u32 intr, intr1, mask; 101 102 mt76_wr(dev, MT_INT_MASK_CSR, 0); 103 if (dev->hif2) 104 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 105 106 intr = mt76_rr(dev, MT_INT_SOURCE_CSR); 107 intr &= dev->mt76.mmio.irqmask; 108 mt76_wr(dev, MT_INT_SOURCE_CSR, intr); 109 110 if (dev->hif2) { 111 intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR); 112 intr1 &= dev->mt76.mmio.irqmask; 113 mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1); 114 115 intr |= intr1; 116 } 117 118 trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask); 119 120 mask = intr & MT_INT_RX_DONE_ALL; 121 if (intr & MT_INT_TX_DONE_MCU) 122 mask |= MT_INT_TX_DONE_MCU; 123 124 mt7915_irq_disable(dev, mask); 125 126 if (intr & MT_INT_TX_DONE_MCU) 127 napi_schedule(&dev->mt76.tx_napi); 128 129 if (intr & MT_INT_RX_DONE_DATA0) 130 napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]); 131 132 if (intr & MT_INT_RX_DONE_DATA1) 133 napi_schedule(&dev->mt76.napi[MT_RXQ_EXT]); 134 135 if (intr & MT_INT_RX_DONE_WM) 136 napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]); 137 138 if (intr & MT_INT_RX_DONE_WA) 139 napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]); 140 141 if (intr & MT_INT_RX_DONE_WA_EXT) 142 napi_schedule(&dev->mt76.napi[MT_RXQ_EXT_WA]); 143 144 if (intr & MT_INT_MCU_CMD) { 145 u32 val = mt76_rr(dev, MT_MCU_CMD); 146 147 mt76_wr(dev, MT_MCU_CMD, val); 148 if (val & MT_MCU_CMD_ERROR_MASK) { 149 dev->reset_state = val; 150 ieee80211_queue_work(mt76_hw(dev), &dev->reset_work); 151 wake_up(&dev->reset_wait); 152 } 153 } 154 } 155 156 static irqreturn_t mt7915_irq_handler(int irq, void *dev_instance) 157 { 158 struct mt7915_dev *dev = dev_instance; 159 160 mt76_wr(dev, MT_INT_MASK_CSR, 0); 161 if (dev->hif2) 162 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 163 164 if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) 165 return IRQ_NONE; 166 167 tasklet_schedule(&dev->irq_tasklet); 168 169 return IRQ_HANDLED; 170 } 171 172 static void mt7915_pci_init_hif2(struct mt7915_dev *dev) 173 { 174 struct mt7915_hif *hif; 175 176 dev->hif_idx = ++hif_idx; 177 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL)) 178 return; 179 180 mt76_wr(dev, MT_PCIE_RECOG_ID, dev->hif_idx | MT_PCIE_RECOG_ID_SEM); 181 182 hif = mt7915_pci_get_hif2(dev); 183 if (!hif) 184 return; 185 186 dev->hif2 = hif; 187 188 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 189 190 if (devm_request_irq(dev->mt76.dev, hif->irq, mt7915_irq_handler, 191 IRQF_SHARED, KBUILD_MODNAME "-hif", dev)) { 192 mt7915_put_hif2(hif); 193 hif = NULL; 194 } 195 196 /* master switch of PCIe tnterrupt enable */ 197 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); 198 } 199 200 static int mt7915_pci_hif2_probe(struct pci_dev *pdev) 201 { 202 struct mt7915_hif *hif; 203 204 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL); 205 if (!hif) 206 return -ENOMEM; 207 208 hif->dev = &pdev->dev; 209 hif->regs = pcim_iomap_table(pdev)[0]; 210 hif->irq = pdev->irq; 211 spin_lock_bh(&hif_lock); 212 list_add(&hif->list, &hif_list); 213 spin_unlock_bh(&hif_lock); 214 pci_set_drvdata(pdev, hif); 215 216 return 0; 217 } 218 219 static int mt7915_pci_probe(struct pci_dev *pdev, 220 const struct pci_device_id *id) 221 { 222 static const struct mt76_driver_ops drv_ops = { 223 /* txwi_size = txd size + txp size */ 224 .txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp), 225 .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ, 226 .survey_flags = SURVEY_INFO_TIME_TX | 227 SURVEY_INFO_TIME_RX | 228 SURVEY_INFO_TIME_BSS_RX, 229 .token_size = MT7915_TOKEN_SIZE, 230 .tx_prepare_skb = mt7915_tx_prepare_skb, 231 .tx_complete_skb = mt7915_tx_complete_skb, 232 .rx_skb = mt7915_queue_rx_skb, 233 .rx_poll_complete = mt7915_rx_poll_complete, 234 .sta_ps = mt7915_sta_ps, 235 .sta_add = mt7915_mac_sta_add, 236 .sta_remove = mt7915_mac_sta_remove, 237 .update_survey = mt7915_update_channel, 238 }; 239 struct mt7915_dev *dev; 240 struct mt76_dev *mdev; 241 int ret; 242 243 ret = pcim_enable_device(pdev); 244 if (ret) 245 return ret; 246 247 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 248 if (ret) 249 return ret; 250 251 pci_set_master(pdev); 252 253 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 254 if (ret) 255 return ret; 256 257 mt76_pci_disable_aspm(pdev); 258 259 if (id->device == 0x7916) 260 return mt7915_pci_hif2_probe(pdev); 261 262 mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7915_ops, 263 &drv_ops); 264 if (!mdev) 265 return -ENOMEM; 266 267 dev = container_of(mdev, struct mt7915_dev, mt76); 268 269 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 270 if (ret < 0) 271 goto free; 272 273 ret = mt7915_mmio_init(mdev, pcim_iomap_table(pdev)[0], pdev->irq); 274 if (ret) 275 goto error; 276 277 tasklet_setup(&dev->irq_tasklet, mt7915_irq_tasklet); 278 279 mt76_wr(dev, MT_INT_MASK_CSR, 0); 280 281 /* master switch of PCIe tnterrupt enable */ 282 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 283 284 ret = devm_request_irq(mdev->dev, pdev->irq, mt7915_irq_handler, 285 IRQF_SHARED, KBUILD_MODNAME, dev); 286 if (ret) 287 goto error; 288 289 mt7915_pci_init_hif2(dev); 290 291 ret = mt7915_register_device(dev); 292 if (ret) 293 goto free_irq; 294 295 return 0; 296 free_irq: 297 devm_free_irq(mdev->dev, pdev->irq, dev); 298 error: 299 pci_free_irq_vectors(pdev); 300 free: 301 mt76_free_device(&dev->mt76); 302 303 return ret; 304 } 305 306 static void mt7915_hif_remove(struct pci_dev *pdev) 307 { 308 struct mt7915_hif *hif = pci_get_drvdata(pdev); 309 310 list_del(&hif->list); 311 } 312 313 static void mt7915_pci_remove(struct pci_dev *pdev) 314 { 315 struct mt76_dev *mdev; 316 struct mt7915_dev *dev; 317 318 mdev = pci_get_drvdata(pdev); 319 dev = container_of(mdev, struct mt7915_dev, mt76); 320 mt7915_put_hif2(dev->hif2); 321 mt7915_unregister_device(dev); 322 } 323 324 static struct pci_driver mt7915_hif_driver = { 325 .name = KBUILD_MODNAME "_hif", 326 .id_table = mt7915_hif_device_table, 327 .probe = mt7915_pci_probe, 328 .remove = mt7915_hif_remove, 329 }; 330 331 static struct pci_driver mt7915_pci_driver = { 332 .name = KBUILD_MODNAME, 333 .id_table = mt7915_pci_device_table, 334 .probe = mt7915_pci_probe, 335 .remove = mt7915_pci_remove, 336 }; 337 338 static int __init mt7915_init(void) 339 { 340 int ret; 341 342 ret = pci_register_driver(&mt7915_hif_driver); 343 if (ret) 344 return ret; 345 346 ret = pci_register_driver(&mt7915_pci_driver); 347 if (ret) 348 pci_unregister_driver(&mt7915_hif_driver); 349 350 return ret; 351 } 352 353 static void __exit mt7915_exit(void) 354 { 355 pci_unregister_driver(&mt7915_pci_driver); 356 pci_unregister_driver(&mt7915_hif_driver); 357 } 358 359 module_init(mt7915_init); 360 module_exit(mt7915_exit); 361 362 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table); 363 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table); 364 MODULE_FIRMWARE(MT7915_FIRMWARE_WA); 365 MODULE_FIRMWARE(MT7915_FIRMWARE_WM); 366 MODULE_FIRMWARE(MT7915_ROM_PATCH); 367 MODULE_LICENSE("Dual BSD/GPL"); 368