diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index 82172665e023..98a99b199674 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c @@ -391,18 +391,10 @@ static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn) nfp_app_vnic_clean(pf->app, nn); } -static int -nfp_net_pf_spawn_vnics(struct nfp_pf *pf, - void __iomem *ctrl_bar, void __iomem *qc_bar, int stride) +static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf) { - unsigned int id, wanted_irqs, num_irqs, vnics_left, irqs_left; + unsigned int wanted_irqs, num_irqs, vnics_left, irqs_left; struct nfp_net *nn; - int err; - - /* Allocate the vnics and do basic init */ - err = nfp_net_pf_alloc_vnics(pf, ctrl_bar, qc_bar, stride); - if (err) - return err; /* Get MSI-X vectors */ wanted_irqs = 0; @@ -410,18 +402,16 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf, wanted_irqs += NFP_NET_NON_Q_VECTORS + nn->dp.num_r_vecs; pf->irq_entries = kcalloc(wanted_irqs, sizeof(*pf->irq_entries), GFP_KERNEL); - if (!pf->irq_entries) { - err = -ENOMEM; - goto err_nn_free; - } + if (!pf->irq_entries) + return -ENOMEM; num_irqs = nfp_net_irqs_alloc(pf->pdev, pf->irq_entries, NFP_NET_MIN_VNIC_IRQS * pf->num_vnics, wanted_irqs); if (!num_irqs) { - nn_warn(nn, "Unable to allocate MSI-X Vectors. Exiting\n"); - err = -ENOMEM; - goto err_vec_free; + nfp_warn(pf->cpp, "Unable to allocate MSI-X vectors\n"); + kfree(pf->irq_entries); + return -ENOMEM; } /* Distribute IRQs to vNICs */ @@ -437,6 +427,21 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf, vnics_left--; } + return 0; +} + +static void nfp_net_pf_free_irqs(struct nfp_pf *pf) +{ + nfp_net_irqs_disable(pf->pdev); + kfree(pf->irq_entries); +} + +static int nfp_net_pf_init_vnics(struct nfp_pf *pf) +{ + struct nfp_net *nn; + unsigned int id; + int err; + /* Finish vNIC init and register */ id = 0; list_for_each_entry(nn, &pf->vnics, vnic_list) { @@ -452,11 +457,6 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf, err_prev_deinit: list_for_each_entry_continue_reverse(nn, &pf->vnics, vnic_list) nfp_net_pf_clean_vnic(pf, nn); - nfp_net_irqs_disable(pf->pdev); -err_vec_free: - kfree(pf->irq_entries); -err_nn_free: - nfp_net_pf_free_vnics(pf); return err; } @@ -489,8 +489,7 @@ static void nfp_net_pci_remove_finish(struct nfp_pf *pf) { nfp_net_debugfs_dir_clean(&pf->ddir); - nfp_net_irqs_disable(pf->pdev); - kfree(pf->irq_entries); + nfp_net_pf_free_irqs(pf); nfp_net_pf_app_clean(pf); @@ -691,14 +690,27 @@ int nfp_net_pci_probe(struct nfp_pf *pf) pf->ddir = nfp_net_debugfs_device_add(pf->pdev); - err = nfp_net_pf_spawn_vnics(pf, ctrl_bar, qc_bar, stride); + /* Allocate the vnics and do basic init */ + err = nfp_net_pf_alloc_vnics(pf, ctrl_bar, qc_bar, stride); if (err) goto err_clean_ddir; + err = nfp_net_pf_alloc_irqs(pf); + if (err) + goto err_free_vnics; + + err = nfp_net_pf_init_vnics(pf); + if (err) + goto err_free_irqs; + mutex_unlock(&pf->lock); return 0; +err_free_irqs: + nfp_net_pf_free_irqs(pf); +err_free_vnics: + nfp_net_pf_free_vnics(pf); err_clean_ddir: nfp_net_debugfs_dir_clean(&pf->ddir); nfp_net_pf_app_clean(pf);