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 MT_DRV_AMSDU_OFFLOAD, 227 .survey_flags = SURVEY_INFO_TIME_TX | 228 SURVEY_INFO_TIME_RX | 229 SURVEY_INFO_TIME_BSS_RX, 230 .token_size = MT7915_TOKEN_SIZE, 231 .tx_prepare_skb = mt7915_tx_prepare_skb, 232 .tx_complete_skb = mt7915_tx_complete_skb, 233 .rx_skb = mt7915_queue_rx_skb, 234 .rx_poll_complete = mt7915_rx_poll_complete, 235 .sta_ps = mt7915_sta_ps, 236 .sta_add = mt7915_mac_sta_add, 237 .sta_remove = mt7915_mac_sta_remove, 238 .update_survey = mt7915_update_channel, 239 }; 240 struct mt7915_dev *dev; 241 struct mt76_dev *mdev; 242 int ret; 243 244 ret = pcim_enable_device(pdev); 245 if (ret) 246 return ret; 247 248 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 249 if (ret) 250 return ret; 251 252 pci_set_master(pdev); 253 254 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 255 if (ret) 256 return ret; 257 258 mt76_pci_disable_aspm(pdev); 259 260 if (id->device == 0x7916) 261 return mt7915_pci_hif2_probe(pdev); 262 263 mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7915_ops, 264 &drv_ops); 265 if (!mdev) 266 return -ENOMEM; 267 268 dev = container_of(mdev, struct mt7915_dev, mt76); 269 270 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 271 if (ret < 0) 272 goto free; 273 274 ret = mt7915_mmio_init(mdev, pcim_iomap_table(pdev)[0], pdev->irq); 275 if (ret) 276 goto error; 277 278 tasklet_setup(&dev->irq_tasklet, mt7915_irq_tasklet); 279 280 mt76_wr(dev, MT_INT_MASK_CSR, 0); 281 282 /* master switch of PCIe tnterrupt enable */ 283 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 284 285 ret = devm_request_irq(mdev->dev, pdev->irq, mt7915_irq_handler, 286 IRQF_SHARED, KBUILD_MODNAME, dev); 287 if (ret) 288 goto error; 289 290 mt7915_pci_init_hif2(dev); 291 292 ret = mt7915_register_device(dev); 293 if (ret) 294 goto free_irq; 295 296 return 0; 297 free_irq: 298 devm_free_irq(mdev->dev, pdev->irq, dev); 299 error: 300 pci_free_irq_vectors(pdev); 301 free: 302 mt76_free_device(&dev->mt76); 303 304 return ret; 305 } 306 307 static void mt7915_hif_remove(struct pci_dev *pdev) 308 { 309 struct mt7915_hif *hif = pci_get_drvdata(pdev); 310 311 list_del(&hif->list); 312 } 313 314 static void mt7915_pci_remove(struct pci_dev *pdev) 315 { 316 struct mt76_dev *mdev; 317 struct mt7915_dev *dev; 318 319 mdev = pci_get_drvdata(pdev); 320 dev = container_of(mdev, struct mt7915_dev, mt76); 321 mt7915_put_hif2(dev->hif2); 322 mt7915_unregister_device(dev); 323 } 324 325 static struct pci_driver mt7915_hif_driver = { 326 .name = KBUILD_MODNAME "_hif", 327 .id_table = mt7915_hif_device_table, 328 .probe = mt7915_pci_probe, 329 .remove = mt7915_hif_remove, 330 }; 331 332 static struct pci_driver mt7915_pci_driver = { 333 .name = KBUILD_MODNAME, 334 .id_table = mt7915_pci_device_table, 335 .probe = mt7915_pci_probe, 336 .remove = mt7915_pci_remove, 337 }; 338 339 static int __init mt7915_init(void) 340 { 341 int ret; 342 343 ret = pci_register_driver(&mt7915_hif_driver); 344 if (ret) 345 return ret; 346 347 ret = pci_register_driver(&mt7915_pci_driver); 348 if (ret) 349 pci_unregister_driver(&mt7915_hif_driver); 350 351 return ret; 352 } 353 354 static void __exit mt7915_exit(void) 355 { 356 pci_unregister_driver(&mt7915_pci_driver); 357 pci_unregister_driver(&mt7915_hif_driver); 358 } 359 360 module_init(mt7915_init); 361 module_exit(mt7915_exit); 362 363 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table); 364 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table); 365 MODULE_FIRMWARE(MT7915_FIRMWARE_WA); 366 MODULE_FIRMWARE(MT7915_FIRMWARE_WM); 367 MODULE_FIRMWARE(MT7915_ROM_PATCH); 368 MODULE_LICENSE("Dual BSD/GPL"); 369