diff options
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfp_main.c')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_main.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index 748e54cc885e..d67969d3e484 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -107,17 +107,18 @@ static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs) goto err_unlock; } - err = nfp_app_sriov_enable(pf->app, num_vfs); + err = pci_enable_sriov(pdev, num_vfs); if (err) { - dev_warn(&pdev->dev, "App specific PCI sriov configuration failed: %d\n", - err); + dev_warn(&pdev->dev, "Failed to enable PCI SR-IOV: %d\n", err); goto err_unlock; } - err = pci_enable_sriov(pdev, num_vfs); + err = nfp_app_sriov_enable(pf->app, num_vfs); if (err) { - dev_warn(&pdev->dev, "Failed to enable PCI sriov: %d\n", err); - goto err_app_sriov_disable; + dev_warn(&pdev->dev, + "App specific PCI SR-IOV configuration failed: %d\n", + err); + goto err_sriov_disable; } pf->num_vfs = num_vfs; @@ -127,8 +128,8 @@ static int nfp_pcie_sriov_enable(struct pci_dev *pdev, int num_vfs) mutex_unlock(&pf->lock); return num_vfs; -err_app_sriov_disable: - nfp_app_sriov_disable(pf->app); +err_sriov_disable: + pci_disable_sriov(pdev); err_unlock: mutex_unlock(&pf->lock); return err; @@ -136,17 +137,20 @@ err_unlock: return 0; } -static int __nfp_pcie_sriov_disable(struct pci_dev *pdev) +static int nfp_pcie_sriov_disable(struct pci_dev *pdev) { #ifdef CONFIG_PCI_IOV struct nfp_pf *pf = pci_get_drvdata(pdev); + mutex_lock(&pf->lock); + /* If the VFs are assigned we cannot shut down SR-IOV without * causing issues, so just leave the hardware available but * disabled */ if (pci_vfs_assigned(pdev)) { dev_warn(&pdev->dev, "Disabling while VFs assigned - VFs will not be deallocated\n"); + mutex_unlock(&pf->lock); return -EPERM; } @@ -156,20 +160,10 @@ static int __nfp_pcie_sriov_disable(struct pci_dev *pdev) pci_disable_sriov(pdev); dev_dbg(&pdev->dev, "Removed VFs.\n"); -#endif - return 0; -} - -static int nfp_pcie_sriov_disable(struct pci_dev *pdev) -{ - struct nfp_pf *pf = pci_get_drvdata(pdev); - int err; - mutex_lock(&pf->lock); - err = __nfp_pcie_sriov_disable(pdev); mutex_unlock(&pf->lock); - - return err; +#endif + return 0; } static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs) @@ -382,6 +376,12 @@ static int nfp_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, pf); pf->pdev = pdev; + pf->wq = alloc_workqueue("nfp-%s", 0, 2, pci_name(pdev)); + if (!pf->wq) { + err = -ENOMEM; + goto err_pci_priv_unset; + } + pf->cpp = nfp_cpp_from_nfp6000_pcie(pdev); if (IS_ERR_OR_NULL(pf->cpp)) { err = PTR_ERR(pf->cpp); @@ -414,6 +414,14 @@ static int nfp_pci_probe(struct pci_dev *pdev, if (err) goto err_fw_unload; + pf->num_vfs = pci_num_vf(pdev); + if (pf->num_vfs > pf->limit_vfs) { + dev_err(&pdev->dev, + "Error: %d VFs already enabled, but loaded FW can only support %d\n", + pf->num_vfs, pf->limit_vfs); + goto err_fw_unload; + } + err = nfp_net_pci_probe(pf); if (err) goto err_sriov_unlimit; @@ -443,6 +451,8 @@ err_hwinfo_free: kfree(pf->hwinfo); nfp_cpp_free(pf->cpp); err_disable_msix: + destroy_workqueue(pf->wq); +err_pci_priv_unset: pci_set_drvdata(pdev, NULL); mutex_destroy(&pf->lock); devlink_free(devlink); @@ -463,11 +473,11 @@ static void nfp_pci_remove(struct pci_dev *pdev) devlink = priv_to_devlink(pf); + nfp_net_pci_remove(pf); + nfp_pcie_sriov_disable(pdev); pci_sriov_set_totalvfs(pf->pdev, 0); - nfp_net_pci_remove(pf); - devlink_unregister(devlink); kfree(pf->rtbl); @@ -475,6 +485,7 @@ static void nfp_pci_remove(struct pci_dev *pdev) if (pf->fw_loaded) nfp_fw_unload(pf); + destroy_workqueue(pf->wq); pci_set_drvdata(pdev, NULL); kfree(pf->hwinfo); nfp_cpp_free(pf->cpp); |