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