Commit 6d4b0d8e authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: slice the netdev spawning function

We want to be able to create a special vNIC for control messages.
This vNIC should be created before any netdev is registered to allow
nfp_app logic to exchange messages with the FW app before any netdev
is visible to user space.  Unfortunately we can't enable IRQs until
we know how many vNICs we will need to spawn.

Divide the function which spawns netdevs for vNICs into three parts:
 - vNIC/memory allocation;
 - IRQ allocation;
 - netdev init and register.

This will help us insert the initialization of the control channel
after IRQ allocation but before netdev init and register.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 21537bc7
...@@ -391,18 +391,10 @@ static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn) ...@@ -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); nfp_app_vnic_clean(pf->app, nn);
} }
static int static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
nfp_net_pf_spawn_vnics(struct nfp_pf *pf,
void __iomem *ctrl_bar, void __iomem *qc_bar, int stride)
{ {
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; 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 */ /* Get MSI-X vectors */
wanted_irqs = 0; wanted_irqs = 0;
...@@ -410,18 +402,16 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf, ...@@ -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; wanted_irqs += NFP_NET_NON_Q_VECTORS + nn->dp.num_r_vecs;
pf->irq_entries = kcalloc(wanted_irqs, sizeof(*pf->irq_entries), pf->irq_entries = kcalloc(wanted_irqs, sizeof(*pf->irq_entries),
GFP_KERNEL); GFP_KERNEL);
if (!pf->irq_entries) { if (!pf->irq_entries)
err = -ENOMEM; return -ENOMEM;
goto err_nn_free;
}
num_irqs = nfp_net_irqs_alloc(pf->pdev, pf->irq_entries, num_irqs = nfp_net_irqs_alloc(pf->pdev, pf->irq_entries,
NFP_NET_MIN_VNIC_IRQS * pf->num_vnics, NFP_NET_MIN_VNIC_IRQS * pf->num_vnics,
wanted_irqs); wanted_irqs);
if (!num_irqs) { if (!num_irqs) {
nn_warn(nn, "Unable to allocate MSI-X Vectors. Exiting\n"); nfp_warn(pf->cpp, "Unable to allocate MSI-X vectors\n");
err = -ENOMEM; kfree(pf->irq_entries);
goto err_vec_free; return -ENOMEM;
} }
/* Distribute IRQs to vNICs */ /* Distribute IRQs to vNICs */
...@@ -437,6 +427,21 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf, ...@@ -437,6 +427,21 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf,
vnics_left--; 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 */ /* Finish vNIC init and register */
id = 0; id = 0;
list_for_each_entry(nn, &pf->vnics, vnic_list) { list_for_each_entry(nn, &pf->vnics, vnic_list) {
...@@ -452,11 +457,6 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf, ...@@ -452,11 +457,6 @@ nfp_net_pf_spawn_vnics(struct nfp_pf *pf,
err_prev_deinit: err_prev_deinit:
list_for_each_entry_continue_reverse(nn, &pf->vnics, vnic_list) list_for_each_entry_continue_reverse(nn, &pf->vnics, vnic_list)
nfp_net_pf_clean_vnic(pf, nn); 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; return err;
} }
...@@ -489,8 +489,7 @@ static void nfp_net_pci_remove_finish(struct nfp_pf *pf) ...@@ -489,8 +489,7 @@ static void nfp_net_pci_remove_finish(struct nfp_pf *pf)
{ {
nfp_net_debugfs_dir_clean(&pf->ddir); nfp_net_debugfs_dir_clean(&pf->ddir);
nfp_net_irqs_disable(pf->pdev); nfp_net_pf_free_irqs(pf);
kfree(pf->irq_entries);
nfp_net_pf_app_clean(pf); nfp_net_pf_app_clean(pf);
...@@ -691,14 +690,27 @@ int nfp_net_pci_probe(struct nfp_pf *pf) ...@@ -691,14 +690,27 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
pf->ddir = nfp_net_debugfs_device_add(pf->pdev); 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) if (err)
goto err_clean_ddir; 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); mutex_unlock(&pf->lock);
return 0; return 0;
err_free_irqs:
nfp_net_pf_free_irqs(pf);
err_free_vnics:
nfp_net_pf_free_vnics(pf);
err_clean_ddir: err_clean_ddir:
nfp_net_debugfs_dir_clean(&pf->ddir); nfp_net_debugfs_dir_clean(&pf->ddir);
nfp_net_pf_app_clean(pf); nfp_net_pf_app_clean(pf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment