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 void mt7915_pci_init_hif2(struct mt7915_dev *dev) 158 { 159 struct mt7915_hif *hif; 160 161 dev->hif_idx = ++hif_idx; 162 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL)) 163 return; 164 165 mt76_wr(dev, MT_PCIE_RECOG_ID, dev->hif_idx | MT_PCIE_RECOG_ID_SEM); 166 167 hif = mt7915_pci_get_hif2(dev); 168 if (!hif) 169 return; 170 171 dev->hif2 = hif; 172 173 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 174 175 if (devm_request_irq(dev->mt76.dev, hif->irq, mt7915_irq_handler, 176 IRQF_SHARED, KBUILD_MODNAME "-hif", dev)) { 177 mt7915_put_hif2(hif); 178 hif = NULL; 179 } 180 181 /* master switch of PCIe tnterrupt enable */ 182 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); 183 } 184 185 static int mt7915_pci_hif2_probe(struct pci_dev *pdev) 186 { 187 struct mt7915_hif *hif; 188 189 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL); 190 if (!hif) 191 return -ENOMEM; 192 193 hif->dev = &pdev->dev; 194 hif->regs = pcim_iomap_table(pdev)[0]; 195 hif->irq = pdev->irq; 196 spin_lock_bh(&hif_lock); 197 list_add(&hif->list, &hif_list); 198 spin_unlock_bh(&hif_lock); 199 pci_set_drvdata(pdev, hif); 200 201 return 0; 202 } 203 204 static int mt7915_pci_probe(struct pci_dev *pdev, 205 const struct pci_device_id *id) 206 { 207 static const struct mt76_driver_ops drv_ops = { 208 /* txwi_size = txd size + txp size */ 209 .txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp), 210 .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ | 211 MT_DRV_AMSDU_OFFLOAD, 212 .survey_flags = SURVEY_INFO_TIME_TX | 213 SURVEY_INFO_TIME_RX | 214 SURVEY_INFO_TIME_BSS_RX, 215 .token_size = MT7915_TOKEN_SIZE, 216 .tx_prepare_skb = mt7915_tx_prepare_skb, 217 .tx_complete_skb = mt7915_tx_complete_skb, 218 .rx_skb = mt7915_queue_rx_skb, 219 .rx_poll_complete = mt7915_rx_poll_complete, 220 .sta_ps = mt7915_sta_ps, 221 .sta_add = mt7915_mac_sta_add, 222 .sta_remove = mt7915_mac_sta_remove, 223 .update_survey = mt7915_update_channel, 224 }; 225 struct mt7915_dev *dev; 226 struct mt76_dev *mdev; 227 int ret; 228 229 ret = pcim_enable_device(pdev); 230 if (ret) 231 return ret; 232 233 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 234 if (ret) 235 return ret; 236 237 pci_set_master(pdev); 238 239 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 240 if (ret) 241 return ret; 242 243 if (id->device == 0x7916) 244 return mt7915_pci_hif2_probe(pdev); 245 246 mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7915_ops, 247 &drv_ops); 248 if (!mdev) 249 return -ENOMEM; 250 251 dev = container_of(mdev, struct mt7915_dev, mt76); 252 253 ret = mt7915_mmio_init(mdev, pcim_iomap_table(pdev)[0], pdev->irq); 254 if (ret) 255 goto error; 256 257 /* master switch of PCIe tnterrupt enable */ 258 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 259 260 ret = devm_request_irq(mdev->dev, pdev->irq, mt7915_irq_handler, 261 IRQF_SHARED, KBUILD_MODNAME, dev); 262 if (ret) 263 goto error; 264 265 mt7915_pci_init_hif2(dev); 266 267 ret = mt7915_register_device(dev); 268 if (ret) 269 goto error; 270 271 return 0; 272 error: 273 mt76_free_device(&dev->mt76); 274 275 return ret; 276 } 277 278 static void mt7915_hif_remove(struct pci_dev *pdev) 279 { 280 struct mt7915_hif *hif = pci_get_drvdata(pdev); 281 282 list_del(&hif->list); 283 } 284 285 static void mt7915_pci_remove(struct pci_dev *pdev) 286 { 287 struct mt76_dev *mdev; 288 struct mt7915_dev *dev; 289 290 mdev = pci_get_drvdata(pdev); 291 dev = container_of(mdev, struct mt7915_dev, mt76); 292 mt7915_put_hif2(dev->hif2); 293 mt7915_unregister_device(dev); 294 } 295 296 static struct pci_driver mt7915_hif_driver = { 297 .name = KBUILD_MODNAME "_hif", 298 .id_table = mt7915_hif_device_table, 299 .probe = mt7915_pci_probe, 300 .remove = mt7915_hif_remove, 301 }; 302 303 static struct pci_driver mt7915_pci_driver = { 304 .name = KBUILD_MODNAME, 305 .id_table = mt7915_pci_device_table, 306 .probe = mt7915_pci_probe, 307 .remove = mt7915_pci_remove, 308 }; 309 310 static int __init mt7915_init(void) 311 { 312 int ret; 313 314 ret = pci_register_driver(&mt7915_hif_driver); 315 if (ret) 316 return ret; 317 318 ret = pci_register_driver(&mt7915_pci_driver); 319 if (ret) 320 pci_unregister_driver(&mt7915_hif_driver); 321 322 return ret; 323 } 324 325 static void __exit mt7915_exit(void) 326 { 327 pci_unregister_driver(&mt7915_pci_driver); 328 pci_unregister_driver(&mt7915_hif_driver); 329 } 330 331 module_init(mt7915_init); 332 module_exit(mt7915_exit); 333 334 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table); 335 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table); 336 MODULE_FIRMWARE(MT7915_FIRMWARE_WA); 337 MODULE_FIRMWARE(MT7915_FIRMWARE_WM); 338 MODULE_FIRMWARE(MT7915_ROM_PATCH); 339 MODULE_LICENSE("Dual BSD/GPL"); 340