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

nfp: disallow mixing vNICs with and without NSP port entry

We only support core NIC apps which have vNICs for each physical port/
split and no representors right now.  Enforce that either each vNIC has
a NSP eth_table entry or if NSP port table is not available none do.

One scenario this will prevent from happening is user force-loading
wrong firmware file if FW app requires different firmwares per media
config.

While at it move some code to nfp_net_pf_alloc_vnic() to make it
counter-match nfp_net_pf_free_vnic() better.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7ac9ebd5
...@@ -289,7 +289,7 @@ static struct nfp_net * ...@@ -289,7 +289,7 @@ static struct nfp_net *
nfp_net_pf_alloc_vnic(struct nfp_pf *pf, void __iomem *ctrl_bar, nfp_net_pf_alloc_vnic(struct nfp_pf *pf, void __iomem *ctrl_bar,
void __iomem *tx_bar, void __iomem *rx_bar, void __iomem *tx_bar, void __iomem *rx_bar,
int stride, struct nfp_net_fw_version *fw_ver, int stride, struct nfp_net_fw_version *fw_ver,
struct nfp_eth_table_port *eth_port) unsigned int eth_id)
{ {
u32 n_tx_rings, n_rx_rings; u32 n_tx_rings, n_rx_rings;
struct nfp_net *nn; struct nfp_net *nn;
...@@ -310,7 +310,10 @@ nfp_net_pf_alloc_vnic(struct nfp_pf *pf, void __iomem *ctrl_bar, ...@@ -310,7 +310,10 @@ nfp_net_pf_alloc_vnic(struct nfp_pf *pf, void __iomem *ctrl_bar,
nn->dp.is_vf = 0; nn->dp.is_vf = 0;
nn->stride_rx = stride; nn->stride_rx = stride;
nn->stride_tx = stride; nn->stride_tx = stride;
nn->eth_port = eth_port; nn->eth_port = nfp_net_find_port(pf->eth_tbl, eth_id);
pf->num_vnics++;
list_add_tail(&nn->vnic_list, &pf->vnics);
return nn; return nn;
} }
...@@ -346,11 +349,16 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar, ...@@ -346,11 +349,16 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
int stride, struct nfp_net_fw_version *fw_ver) int stride, struct nfp_net_fw_version *fw_ver)
{ {
u32 prev_tx_base, prev_rx_base, tgt_tx_base, tgt_rx_base; u32 prev_tx_base, prev_rx_base, tgt_tx_base, tgt_rx_base;
struct nfp_eth_table_port *eth_port;
struct nfp_net *nn; struct nfp_net *nn;
unsigned int i; unsigned int i;
int err; int err;
if (pf->eth_tbl && pf->max_data_vnics != pf->eth_tbl->count) {
nfp_err(pf->cpp, "ETH entries don't match vNICs (%d vs %d)\n",
pf->max_data_vnics, pf->eth_tbl->count);
return -EINVAL;
}
prev_tx_base = readl(ctrl_bar + NFP_NET_CFG_START_TXQ); prev_tx_base = readl(ctrl_bar + NFP_NET_CFG_START_TXQ);
prev_rx_base = readl(ctrl_bar + NFP_NET_CFG_START_RXQ); prev_rx_base = readl(ctrl_bar + NFP_NET_CFG_START_RXQ);
...@@ -362,21 +370,26 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar, ...@@ -362,21 +370,26 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
prev_tx_base = tgt_tx_base; prev_tx_base = tgt_tx_base;
prev_rx_base = tgt_rx_base; prev_rx_base = tgt_rx_base;
eth_port = nfp_net_find_port(pf->eth_tbl, i); nn = nfp_net_pf_alloc_vnic(pf, ctrl_bar, tx_bar, rx_bar,
if (eth_port && eth_port->override_changed) { stride, fw_ver, i);
nfp_warn(pf->cpp, "Config changed for port #%d, reboot required before port will be operational\n", i); if (IS_ERR(nn)) {
} else { err = PTR_ERR(nn);
nn = nfp_net_pf_alloc_vnic(pf, ctrl_bar, tx_bar, rx_bar, goto err_free_prev;
stride, fw_ver, eth_port);
if (IS_ERR(nn)) {
err = PTR_ERR(nn);
goto err_free_prev;
}
list_add_tail(&nn->vnic_list, &pf->vnics);
pf->num_vnics++;
} }
ctrl_bar += NFP_PF_CSR_SLICE_SIZE; ctrl_bar += NFP_PF_CSR_SLICE_SIZE;
/* Check if vNIC has external port associated and cfg is OK */
if (pf->eth_tbl && !nn->eth_port) {
nfp_err(pf->cpp, "NSP port entries don't match vNICs (no entry for port #%d)\n", i);
err = -EINVAL;
goto err_free_prev;
}
if (nn->eth_port && nn->eth_port->override_changed) {
nfp_warn(pf->cpp, "Config changed for port #%d, reboot required before port will be operational\n", i);
nfp_net_pf_free_vnic(pf, nn);
continue;
}
} }
if (list_empty(&pf->vnics)) if (list_empty(&pf->vnics))
...@@ -517,6 +530,9 @@ static void nfp_net_refresh_vnics(struct work_struct *work) ...@@ -517,6 +530,9 @@ static void nfp_net_refresh_vnics(struct work_struct *work)
continue; continue;
nn->eth_port = nfp_net_find_port(eth_table, nn->eth_port = nfp_net_find_port(eth_table,
nn->eth_port->eth_index); nn->eth_port->eth_index);
if (!nn->eth_port)
nfp_err(pf->cpp,
"Warning: port disappeared after reconfig\n");
} }
rtnl_unlock(); rtnl_unlock();
...@@ -524,11 +540,7 @@ static void nfp_net_refresh_vnics(struct work_struct *work) ...@@ -524,11 +540,7 @@ static void nfp_net_refresh_vnics(struct work_struct *work)
pf->eth_tbl = eth_table; pf->eth_tbl = eth_table;
list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) { list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
if (!nn->eth_port) { if (nn->eth_port && !nn->eth_port->override_changed)
nfp_warn(pf->cpp, "Warning: port not present after reconfig\n");
continue;
}
if (!nn->eth_port->override_changed)
continue; continue;
nn_warn(nn, "Port config changed, unregistering. Reboot required before port will be operational again.\n"); nn_warn(nn, "Port config changed, unregistering. Reboot required before port will be operational again.\n");
......
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