static int qtnf_pcie_init_memory(struct qtnf_pcie_bus_priv *priv) { int ret = -ENOMEM; priv->sysctl_bar = qtnf_map_bar(priv, QTN_SYSCTL_BAR); if (IS_ERR(priv->sysctl_bar)) { pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR); return ret; } priv->dmareg_bar = qtnf_map_bar(priv, QTN_DMA_BAR); if (IS_ERR(priv->dmareg_bar)) { pr_err("failed to map BAR%u\n", QTN_DMA_BAR); return ret; } priv->epmem_bar = qtnf_map_bar(priv, QTN_SHMEM_BAR); if (IS_ERR(priv->epmem_bar)) { pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR); return ret; } priv->pcie_reg_base = priv->dmareg_bar; priv->bda = priv->epmem_bar; writel(priv->msi_enabled, &priv->bda->bda_rc_msi_enabled); return 0; }
static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct qtnf_pcie_bus_priv *pcie_priv; struct qtnf_bus *bus; void __iomem *sysctl_bar; void __iomem *epmem_bar; void __iomem *dmareg_bar; unsigned int chipid; int ret; if (!pci_is_pcie(pdev)) { pr_err("device %s is not PCI Express\n", pci_name(pdev)); return -EIO; } qtnf_tune_pcie_mps(pdev); ret = pcim_enable_device(pdev); if (ret) { pr_err("failed to init PCI device %x\n", pdev->device); return ret; } pci_set_master(pdev); sysctl_bar = qtnf_map_bar(pdev, QTN_SYSCTL_BAR); if (IS_ERR(sysctl_bar)) { pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR); return ret; } dmareg_bar = qtnf_map_bar(pdev, QTN_DMA_BAR); if (IS_ERR(dmareg_bar)) { pr_err("failed to map BAR%u\n", QTN_DMA_BAR); return ret; } epmem_bar = qtnf_map_bar(pdev, QTN_SHMEM_BAR); if (IS_ERR(epmem_bar)) { pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR); return ret; } chipid = qtnf_chip_id_get(sysctl_bar); pr_info("identified device: %s\n", qtnf_chipid_to_string(chipid)); switch (chipid) { case QTN_CHIP_ID_PEARL: case QTN_CHIP_ID_PEARL_B: case QTN_CHIP_ID_PEARL_C: bus = qtnf_pcie_pearl_alloc(pdev); break; case QTN_CHIP_ID_TOPAZ: bus = qtnf_pcie_topaz_alloc(pdev); break; default: pr_err("unsupported chip ID 0x%x\n", chipid); return -ENOTSUPP; } if (!bus) return -ENOMEM; pcie_priv = get_bus_priv(bus); pci_set_drvdata(pdev, bus); bus->dev = &pdev->dev; bus->fw_state = QTNF_FW_STATE_RESET; pcie_priv->pdev = pdev; pcie_priv->tx_stopped = 0; pcie_priv->rx_bd_num = rx_bd_size_param; pcie_priv->flashboot = flashboot; if (fw_blksize_param > QTN_PCIE_MAX_FW_BUFSZ) pcie_priv->fw_blksize = QTN_PCIE_MAX_FW_BUFSZ; else pcie_priv->fw_blksize = fw_blksize_param; mutex_init(&bus->bus_lock); spin_lock_init(&pcie_priv->tx_lock); spin_lock_init(&pcie_priv->tx_reclaim_lock); pcie_priv->tx_full_count = 0; pcie_priv->tx_done_count = 0; pcie_priv->pcie_irq_count = 0; pcie_priv->tx_reclaim_done = 0; pcie_priv->tx_reclaim_req = 0; pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PCIE"); if (!pcie_priv->workqueue) { pr_err("failed to alloc bus workqueue\n"); return -ENODEV; } ret = dma_set_mask_and_coherent(&pdev->dev, pcie_priv->dma_mask_get_cb()); if (ret) { pr_err("PCIE DMA coherent mask init failed 0x%llx\n", pcie_priv->dma_mask_get_cb()); goto error; } init_dummy_netdev(&bus->mux_dev); qtnf_pcie_init_irq(pcie_priv, use_msi); pcie_priv->sysctl_bar = sysctl_bar; pcie_priv->dmareg_bar = dmareg_bar; pcie_priv->epmem_bar = epmem_bar; pci_save_state(pdev); ret = pcie_priv->probe_cb(bus, tx_bd_size_param); if (ret) goto error; qtnf_pcie_bringup_fw_async(bus); return 0; error: flush_workqueue(pcie_priv->workqueue); destroy_workqueue(pcie_priv->workqueue); pci_set_drvdata(pdev, NULL); return ret; }