Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2020 MediaTek Inc.
0003  *
0004  * Author: Ryder Lee <ryder.lee@mediatek.com>
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     /* master switch of PCIe tnterrupt enable */
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         /* master switch of PCIe tnterrupt enable */
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);