0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/pci.h>
0010
0011 #include "mt7915.h"
0012 #include "mac.h"
0013 #include "../trace.h"
0014
0015 static bool wed_enable = false;
0016 module_param(wed_enable, bool, 0644);
0017
0018 static LIST_HEAD(hif_list);
0019 static DEFINE_SPINLOCK(hif_lock);
0020 static u32 hif_idx;
0021
0022 static const struct pci_device_id mt7915_pci_device_table[] = {
0023 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7915) },
0024 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7906) },
0025 { },
0026 };
0027
0028 static const struct pci_device_id mt7915_hif_device_table[] = {
0029 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7916) },
0030 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x790a) },
0031 { },
0032 };
0033
0034 static struct mt7915_hif *mt7915_pci_get_hif2(u32 idx)
0035 {
0036 struct mt7915_hif *hif;
0037 u32 val;
0038
0039 spin_lock_bh(&hif_lock);
0040
0041 list_for_each_entry(hif, &hif_list, list) {
0042 val = readl(hif->regs + MT_PCIE_RECOG_ID);
0043 val &= MT_PCIE_RECOG_ID_MASK;
0044 if (val != idx)
0045 continue;
0046
0047 get_device(hif->dev);
0048 goto out;
0049 }
0050 hif = NULL;
0051
0052 out:
0053 spin_unlock_bh(&hif_lock);
0054
0055 return hif;
0056 }
0057
0058 static void mt7915_put_hif2(struct mt7915_hif *hif)
0059 {
0060 if (!hif)
0061 return;
0062
0063 put_device(hif->dev);
0064 }
0065
0066 static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev)
0067 {
0068 hif_idx++;
0069 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL) &&
0070 !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL))
0071 return NULL;
0072
0073 writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
0074 pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);
0075
0076 return mt7915_pci_get_hif2(hif_idx);
0077 }
0078
0079 static int mt7915_pci_hif2_probe(struct pci_dev *pdev)
0080 {
0081 struct mt7915_hif *hif;
0082
0083 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
0084 if (!hif)
0085 return -ENOMEM;
0086
0087 hif->dev = &pdev->dev;
0088 hif->regs = pcim_iomap_table(pdev)[0];
0089 hif->irq = pdev->irq;
0090 spin_lock_bh(&hif_lock);
0091 list_add(&hif->list, &hif_list);
0092 spin_unlock_bh(&hif_lock);
0093 pci_set_drvdata(pdev, hif);
0094
0095 return 0;
0096 }
0097
0098 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
0099 static int mt7915_wed_offload_enable(struct mtk_wed_device *wed)
0100 {
0101 struct mt7915_dev *dev;
0102 int ret;
0103
0104 dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
0105
0106 spin_lock_bh(&dev->mt76.token_lock);
0107 dev->mt76.token_size = wed->wlan.token_start;
0108 spin_unlock_bh(&dev->mt76.token_lock);
0109
0110 ret = wait_event_timeout(dev->mt76.tx_wait,
0111 !dev->mt76.wed_token_count, HZ);
0112 if (!ret)
0113 return -EAGAIN;
0114
0115 return 0;
0116 }
0117
0118 static void mt7915_wed_offload_disable(struct mtk_wed_device *wed)
0119 {
0120 struct mt7915_dev *dev;
0121
0122 dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
0123
0124 spin_lock_bh(&dev->mt76.token_lock);
0125 dev->mt76.token_size = MT7915_TOKEN_SIZE;
0126 spin_unlock_bh(&dev->mt76.token_lock);
0127 }
0128 #endif
0129
0130 static int
0131 mt7915_pci_wed_init(struct mt7915_dev *dev, struct pci_dev *pdev, int *irq)
0132 {
0133 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
0134 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
0135 int ret;
0136
0137 if (!wed_enable)
0138 return 0;
0139
0140 wed->wlan.pci_dev = pdev;
0141 wed->wlan.wpdma_phys = pci_resource_start(pdev, 0) +
0142 MT_WFDMA_EXT_CSR_BASE;
0143 wed->wlan.nbuf = 4096;
0144 wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf;
0145 wed->wlan.init_buf = mt7915_wed_init_buf;
0146 wed->wlan.offload_enable = mt7915_wed_offload_enable;
0147 wed->wlan.offload_disable = mt7915_wed_offload_disable;
0148
0149 if (mtk_wed_device_attach(wed) != 0)
0150 return 0;
0151
0152 *irq = wed->irq;
0153 dev->mt76.dma_dev = wed->dev;
0154
0155 ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
0156 if (ret)
0157 return ret;
0158
0159 return 1;
0160 #else
0161 return 0;
0162 #endif
0163 }
0164
0165 static int mt7915_pci_probe(struct pci_dev *pdev,
0166 const struct pci_device_id *id)
0167 {
0168 struct mt7915_hif *hif2 = NULL;
0169 struct mt7915_dev *dev;
0170 struct mt76_dev *mdev;
0171 int irq;
0172 int ret;
0173
0174 ret = pcim_enable_device(pdev);
0175 if (ret)
0176 return ret;
0177
0178 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
0179 if (ret)
0180 return ret;
0181
0182 pci_set_master(pdev);
0183
0184 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0185 if (ret)
0186 return ret;
0187
0188 mt76_pci_disable_aspm(pdev);
0189
0190 if (id->device == 0x7916 || id->device == 0x790a)
0191 return mt7915_pci_hif2_probe(pdev);
0192
0193 dev = mt7915_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
0194 id->device);
0195 if (IS_ERR(dev))
0196 return PTR_ERR(dev);
0197
0198 mdev = &dev->mt76;
0199 mt7915_wfsys_reset(dev);
0200 hif2 = mt7915_pci_init_hif2(pdev);
0201
0202 ret = mt7915_pci_wed_init(dev, pdev, &irq);
0203 if (ret < 0)
0204 goto free_wed_or_irq_vector;
0205
0206 if (!ret) {
0207 hif2 = mt7915_pci_init_hif2(pdev);
0208
0209 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
0210 if (ret < 0)
0211 goto free_device;
0212
0213 irq = pdev->irq;
0214 }
0215
0216 ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
0217 IRQF_SHARED, KBUILD_MODNAME, dev);
0218 if (ret)
0219 goto free_wed_or_irq_vector;
0220
0221
0222 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
0223
0224 if (hif2) {
0225 dev->hif2 = hif2;
0226
0227 mt76_wr(dev, MT_INT1_MASK_CSR, 0);
0228
0229 if (is_mt7915(mdev))
0230 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
0231 else
0232 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff);
0233
0234 ret = devm_request_irq(mdev->dev, dev->hif2->irq,
0235 mt7915_irq_handler, IRQF_SHARED,
0236 KBUILD_MODNAME "-hif", dev);
0237 if (ret)
0238 goto free_hif2;
0239 }
0240
0241 ret = mt7915_register_device(dev);
0242 if (ret)
0243 goto free_hif2_irq;
0244
0245 return 0;
0246
0247 free_hif2_irq:
0248 if (dev->hif2)
0249 devm_free_irq(mdev->dev, dev->hif2->irq, dev);
0250 free_hif2:
0251 if (dev->hif2)
0252 put_device(dev->hif2->dev);
0253 devm_free_irq(mdev->dev, irq, dev);
0254 free_wed_or_irq_vector:
0255 if (mtk_wed_device_active(&mdev->mmio.wed))
0256 mtk_wed_device_detach(&mdev->mmio.wed);
0257 else
0258 pci_free_irq_vectors(pdev);
0259 free_device:
0260 mt76_free_device(&dev->mt76);
0261
0262 return ret;
0263 }
0264
0265 static void mt7915_hif_remove(struct pci_dev *pdev)
0266 {
0267 struct mt7915_hif *hif = pci_get_drvdata(pdev);
0268
0269 list_del(&hif->list);
0270 }
0271
0272 static void mt7915_pci_remove(struct pci_dev *pdev)
0273 {
0274 struct mt76_dev *mdev;
0275 struct mt7915_dev *dev;
0276
0277 mdev = pci_get_drvdata(pdev);
0278 dev = container_of(mdev, struct mt7915_dev, mt76);
0279 mt7915_put_hif2(dev->hif2);
0280 mt7915_unregister_device(dev);
0281 }
0282
0283 struct pci_driver mt7915_hif_driver = {
0284 .name = KBUILD_MODNAME "_hif",
0285 .id_table = mt7915_hif_device_table,
0286 .probe = mt7915_pci_probe,
0287 .remove = mt7915_hif_remove,
0288 };
0289
0290 struct pci_driver mt7915_pci_driver = {
0291 .name = KBUILD_MODNAME,
0292 .id_table = mt7915_pci_device_table,
0293 .probe = mt7915_pci_probe,
0294 .remove = mt7915_pci_remove,
0295 };
0296
0297 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);
0298 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);
0299 MODULE_FIRMWARE(MT7915_FIRMWARE_WA);
0300 MODULE_FIRMWARE(MT7915_FIRMWARE_WM);
0301 MODULE_FIRMWARE(MT7915_ROM_PATCH);
0302 MODULE_FIRMWARE(MT7916_FIRMWARE_WA);
0303 MODULE_FIRMWARE(MT7916_FIRMWARE_WM);
0304 MODULE_FIRMWARE(MT7916_ROM_PATCH);