summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
diff options
context:
space:
mode:
authorJakub Kicinski2017-05-22 19:59:28 +0200
committerDavid S. Miller2017-05-22 20:59:04 +0200
commiteb488c26d713b2a9ebba6c12bbefd04e01197693 (patch)
treebc4562458f046d11a1ea2e2b49de574c259c359b /drivers/net/ethernet/netronome/nfp/nfp_net_main.c
parentnfp: disallow mixing vNICs with and without NSP port entry (diff)
downloadkernel-qcow2-linux-eb488c26d713b2a9ebba6c12bbefd04e01197693.tar.gz
kernel-qcow2-linux-eb488c26d713b2a9ebba6c12bbefd04e01197693.tar.xz
kernel-qcow2-linux-eb488c26d713b2a9ebba6c12bbefd04e01197693.zip
nfp: introduce nfp_port
Encapsulate port information into struct nfp_port. nfp_port will soon be extended to contain devlink_port information. It also makes it easier to reuse port-related code between vNICs and representors. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfp_net_main.c')
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_main.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 8f267b1534e2..8e1e55187262 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -58,6 +58,7 @@
#include "nfp_net_ctrl.h"
#include "nfp_net.h"
#include "nfp_main.h"
+#include "nfp_port.h"
#define NFP_PF_CSR_SLICE_SIZE (32 * 1024)
@@ -142,14 +143,16 @@ err_area:
static void
nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id)
{
+ struct nfp_eth_table_port *eth_port;
struct nfp_net_dp *dp = &nn->dp;
u8 mac_addr[ETH_ALEN];
const char *mac_str;
char name[32];
- if (nn->eth_port) {
- ether_addr_copy(dp->netdev->dev_addr, nn->eth_port->mac_addr);
- ether_addr_copy(dp->netdev->perm_addr, nn->eth_port->mac_addr);
+ eth_port = __nfp_port_get_eth_port(nn->port);
+ if (eth_port) {
+ ether_addr_copy(dp->netdev->dev_addr, eth_port->mac_addr);
+ ether_addr_copy(dp->netdev->perm_addr, eth_port->mac_addr);
return;
}
@@ -270,6 +273,7 @@ static u8 __iomem *nfp_net_pf_map_ctrl_bar(struct nfp_pf *pf)
static void nfp_net_pf_free_vnic(struct nfp_pf *pf, struct nfp_net *nn)
{
+ nfp_port_free(nn->port);
list_del(&nn->vnic_list);
pf->num_vnics--;
nfp_net_free(nn);
@@ -291,6 +295,7 @@ nfp_net_pf_alloc_vnic(struct nfp_pf *pf, void __iomem *ctrl_bar,
int stride, struct nfp_net_fw_version *fw_ver,
unsigned int eth_id)
{
+ struct nfp_eth_table_port *eth_port;
u32 n_tx_rings, n_rx_rings;
struct nfp_net *nn;
@@ -310,7 +315,18 @@ nfp_net_pf_alloc_vnic(struct nfp_pf *pf, void __iomem *ctrl_bar,
nn->dp.is_vf = 0;
nn->stride_rx = stride;
nn->stride_tx = stride;
- nn->eth_port = nfp_net_find_port(pf->eth_tbl, eth_id);
+
+ eth_port = nfp_net_find_port(pf->eth_tbl, eth_id);
+ if (eth_port) {
+ nn->port = nfp_port_alloc(pf->app, NFP_PORT_PHYS_PORT,
+ nn->dp.netdev);
+ if (IS_ERR(nn->port)) {
+ nfp_net_free(nn);
+ return ERR_CAST(nn->port);
+ }
+ nn->port->eth_id = eth_id;
+ nn->port->eth_port = eth_port;
+ }
pf->num_vnics++;
list_add_tail(&nn->vnic_list, &pf->vnics);
@@ -380,12 +396,12 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
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) {
+ if (pf->eth_tbl && !nn->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) {
+ if (nn->port && nn->port->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;
@@ -526,13 +542,20 @@ static void nfp_net_refresh_vnics(struct work_struct *work)
rtnl_lock();
list_for_each_entry(nn, &pf->vnics, vnic_list) {
- if (!nn->eth_port)
+ if (!__nfp_port_get_eth_port(nn->port))
continue;
- nn->eth_port = nfp_net_find_port(eth_table,
- nn->eth_port->eth_index);
- if (!nn->eth_port)
- nfp_err(pf->cpp,
- "Warning: port disappeared after reconfig\n");
+ nn->port->eth_port = nfp_net_find_port(eth_table,
+ nn->port->eth_id);
+ if (!nn->port->eth_port) {
+ nfp_warn(pf->cpp, "Warning: port #%d not present after reconfig\n",
+ nn->port->eth_id);
+ continue;
+ }
+ if (nn->port->eth_port->override_changed) {
+ nfp_warn(pf->cpp, "Port config changed, unregistering. Reboot required before port will be operational again.\n");
+ nn->port->type = NFP_PORT_INVALID;
+ continue;
+ }
}
rtnl_unlock();
@@ -540,11 +563,9 @@ static void nfp_net_refresh_vnics(struct work_struct *work)
pf->eth_tbl = eth_table;
list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
- if (nn->eth_port && !nn->eth_port->override_changed)
+ if (!nn->port || nn->port->type != NFP_PORT_INVALID)
continue;
- nn_warn(nn, "Port config changed, unregistering. Reboot required before port will be operational again.\n");
-
nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
nfp_net_clean(nn);
@@ -557,32 +578,33 @@ out:
mutex_unlock(&pf->lock);
}
-void nfp_net_refresh_port_table(struct nfp_net *nn)
+void nfp_net_refresh_port_table(struct nfp_port *port)
{
- struct nfp_pf *pf = pci_get_drvdata(nn->pdev);
+ struct nfp_pf *pf = port->app->pf;
schedule_work(&pf->port_refresh_work);
}
-int nfp_net_refresh_eth_port(struct nfp_net *nn)
+int nfp_net_refresh_eth_port(struct nfp_port *port)
{
+ struct nfp_cpp *cpp = port->app->cpp;
struct nfp_eth_table_port *eth_port;
struct nfp_eth_table *eth_table;
- eth_table = nfp_eth_read_ports(nn->app->cpp);
+ eth_table = nfp_eth_read_ports(cpp);
if (!eth_table) {
- nn_err(nn, "Error refreshing port state table!\n");
+ nfp_err(cpp, "Error refreshing port state table!\n");
return -EIO;
}
- eth_port = nfp_net_find_port(eth_table, nn->eth_port->eth_index);
+ eth_port = nfp_net_find_port(eth_table, port->eth_id);
if (!eth_port) {
- nn_err(nn, "Error finding state of the port!\n");
+ nfp_err(cpp, "Error finding state of the port!\n");
kfree(eth_table);
return -EIO;
}
- memcpy(nn->eth_port, eth_port, sizeof(*eth_port));
+ memcpy(port->eth_port, eth_port, sizeof(*eth_port));
kfree(eth_table);