Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7915/pci.c
48525 views
// SPDX-License-Identifier: ISC1/* Copyright (C) 2020 MediaTek Inc.2*3* Author: Ryder Lee <[email protected]>4*/56#if defined(__FreeBSD__)7#define LINUXKPI_PARAM_PREFIX mt7915_pci_8#endif910#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/pci.h>1314#include "mt7915.h"15#include "mac.h"16#include "../trace.h"1718#if defined(__linux__)19static LIST_HEAD(hif_list);20#elif defined(__FreeBSD__)21static LINUX_LIST_HEAD(hif_list);22#endif23static DEFINE_SPINLOCK(hif_lock);24static u32 hif_idx;2526static const struct pci_device_id mt7915_pci_device_table[] = {27{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7915) },28{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7906) },29{ },30};3132static const struct pci_device_id mt7915_hif_device_table[] = {33{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7916) },34{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x790a) },35{ },36};3738static struct mt7915_hif *mt7915_pci_get_hif2(u32 idx)39{40struct mt7915_hif *hif;41u32 val;4243spin_lock_bh(&hif_lock);4445list_for_each_entry(hif, &hif_list, list) {46#if defined(__linux__)47val = readl(hif->regs + MT_PCIE_RECOG_ID);48#elif defined(__FreeBSD__)49val = readl((u8 *)hif->regs + MT_PCIE_RECOG_ID);50#endif51val &= MT_PCIE_RECOG_ID_MASK;52if (val != idx)53continue;5455get_device(hif->dev);56hif->index = idx;57goto out;58}59hif = NULL;6061out:62spin_unlock_bh(&hif_lock);6364return hif;65}6667static void mt7915_put_hif2(struct mt7915_hif *hif)68{69if (!hif)70return;7172put_device(hif->dev);73}7475static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev)76{77struct pci_dev *tmp_pdev;7879hif_idx++;8081#if defined(__linux__)82tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL);83#elif defined(__FreeBSD__)84tmp_pdev = linuxkpi_pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL);85#endif86if (!tmp_pdev) {87#if defined(__linux__)88tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL);89#elif defined(__FreeBSD__)90tmp_pdev = linuxkpi_pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL);91#endif92if (!tmp_pdev)93return NULL;94}95pci_dev_put(tmp_pdev);9697writel(hif_idx | MT_PCIE_RECOG_ID_SEM,98#if defined(__linux__)99pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);100#elif defined(__FreeBSD__)101(u8 *)(pcim_iomap_table(pdev)[0]) + MT_PCIE_RECOG_ID);102#endif103104return mt7915_pci_get_hif2(hif_idx);105}106107static int mt7915_pci_hif2_probe(struct pci_dev *pdev)108{109struct mt7915_hif *hif;110111hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);112if (!hif)113return -ENOMEM;114115hif->dev = &pdev->dev;116hif->regs = pcim_iomap_table(pdev)[0];117hif->irq = pdev->irq;118spin_lock_bh(&hif_lock);119list_add(&hif->list, &hif_list);120spin_unlock_bh(&hif_lock);121pci_set_drvdata(pdev, hif);122123return 0;124}125126static int mt7915_pci_probe(struct pci_dev *pdev,127const struct pci_device_id *id)128{129struct mt7915_hif *hif2 = NULL;130struct mt7915_dev *dev;131struct mt76_dev *mdev;132int irq;133int ret;134135ret = pcim_enable_device(pdev);136if (ret)137return ret;138139ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));140if (ret)141return ret;142143pci_set_master(pdev);144145ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));146if (ret)147return ret;148149mt76_pci_disable_aspm(pdev);150151if (id->device == 0x7916 || id->device == 0x790a)152return mt7915_pci_hif2_probe(pdev);153154dev = mt7915_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],155id->device);156if (IS_ERR(dev))157return PTR_ERR(dev);158159mdev = &dev->mt76;160mt7915_wfsys_reset(dev);161hif2 = mt7915_pci_init_hif2(pdev);162163ret = mt7915_mmio_wed_init(dev, pdev, true, &irq);164if (ret < 0)165goto free_wed_or_irq_vector;166167if (!ret) {168hif2 = mt7915_pci_init_hif2(pdev);169170ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);171if (ret < 0)172goto free_device;173174irq = pdev->irq;175}176177ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,178IRQF_SHARED, KBUILD_MODNAME, dev);179if (ret)180goto free_wed_or_irq_vector;181182/* master switch of PCIe tnterrupt enable */183mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);184185if (hif2) {186dev->hif2 = hif2;187188mt76_wr(dev, MT_INT1_MASK_CSR, 0);189/* master switch of PCIe tnterrupt enable */190if (is_mt7915(mdev))191mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);192else193mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff);194195ret = devm_request_irq(mdev->dev, dev->hif2->irq,196mt7915_irq_handler, IRQF_SHARED,197KBUILD_MODNAME "-hif", dev);198if (ret)199goto free_hif2;200}201202ret = mt7915_register_device(dev);203if (ret)204goto free_hif2_irq;205206return 0;207208free_hif2_irq:209if (dev->hif2)210devm_free_irq(mdev->dev, dev->hif2->irq, dev);211free_hif2:212if (dev->hif2)213put_device(dev->hif2->dev);214devm_free_irq(mdev->dev, irq, dev);215free_wed_or_irq_vector:216if (mtk_wed_device_active(&mdev->mmio.wed))217mtk_wed_device_detach(&mdev->mmio.wed);218else219pci_free_irq_vectors(pdev);220free_device:221mt76_free_device(&dev->mt76);222223return ret;224}225226static void mt7915_hif_remove(struct pci_dev *pdev)227{228struct mt7915_hif *hif = pci_get_drvdata(pdev);229230list_del(&hif->list);231}232233static void mt7915_pci_remove(struct pci_dev *pdev)234{235struct mt76_dev *mdev;236struct mt7915_dev *dev;237238mdev = pci_get_drvdata(pdev);239dev = container_of(mdev, struct mt7915_dev, mt76);240mt7915_put_hif2(dev->hif2);241mt7915_unregister_device(dev);242}243244struct pci_driver mt7915_hif_driver = {245.name = KBUILD_MODNAME "_hif",246.id_table = mt7915_hif_device_table,247.probe = mt7915_pci_probe,248.remove = mt7915_hif_remove,249};250251struct pci_driver mt7915_pci_driver = {252.name = KBUILD_MODNAME,253.id_table = mt7915_pci_device_table,254.probe = mt7915_pci_probe,255.remove = mt7915_pci_remove,256};257258MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);259MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);260MODULE_FIRMWARE(MT7915_FIRMWARE_WA);261MODULE_FIRMWARE(MT7915_FIRMWARE_WM);262MODULE_FIRMWARE(MT7915_ROM_PATCH);263MODULE_FIRMWARE(MT7916_FIRMWARE_WA);264MODULE_FIRMWARE(MT7916_FIRMWARE_WM);265MODULE_FIRMWARE(MT7916_ROM_PATCH);266#if defined(__FreeBSD__)267MODULE_VERSION(mt7915_pci, 1);268MODULE_DEPEND(mt7915_pci, linuxkpi, 1, 1, 1);269MODULE_DEPEND(mt7915_pci, linuxkpi_wlan, 1, 1, 1);270MODULE_DEPEND(mt7915_pci, mt76_core, 1, 1, 1);271#endif272273274