aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2020-07-09 13:15:30 -0700
committerDavid S. Miller <davem@davemloft.net>2020-07-09 13:15:30 -0700
commit8fb49c0109f47e4a25e8ba36abd8381afbfa7a08 (patch)
tree2b29fc5bcaa3787987243f649c682c642839bdaf /drivers
parentnet: phy: mscc: fix ptr_ret.cocci warnings (diff)
parentselftests: net: Add port split test (diff)
downloadlinux-dev-8fb49c0109f47e4a25e8ba36abd8381afbfa7a08.tar.xz
linux-dev-8fb49c0109f47e4a25e8ba36abd8381afbfa7a08.zip
Merge branch 'Expose-port-split-attributes'
Ido Schimmel says: ==================== Expose port split attributes Danielle says: Currently, user space has no way of knowing if a port can be split and into how many ports. Among other things, this makes it impossible to write generic tests for port split functionality. Therefore, this set exposes two new devlink port attributes to user space: Number of lanes and whether the port can be split or not. Patch set overview: Patches #1-#4 cleanup 'struct devlink_port_attrs' and reduce the number of parameters passed between drivers and devlink via devlink_port_attrs_set() Patch #5 adds devlink port lanes attributes Patches #6-#7 add devlink port splittable attribute Patch #8 exploits the fact that devlink is now aware of port's number of lanes and whether the port can be split or not and moves some checks from drivers to devlink Patch #9 adds a port split test Changes since v2: * Remove some local variables from patch #3 * Reword function description in patch #5 * Fix a bug in patch #8 * Add a test for the splittable attribute in patch #9 Changes since v1: * Rename 'width' attribute to 'lanes' * Add 'splittable' attribute * Move checks from drivers to devlink ==================== Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c9
-rw-r--r--drivers/net/ethernet/intel/ice/ice_devlink.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/minimal.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c23
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/switchib.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/switchx2.c2
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_devlink.c17
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_devlink.c5
-rw-r--r--drivers/net/netdevsim/dev.c10
13 files changed, 72 insertions, 63 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index 2bd610fafc58..3a854195d5b0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -691,6 +691,7 @@ static void bnxt_dl_params_unregister(struct bnxt *bp)
int bnxt_dl_register(struct bnxt *bp)
{
+ struct devlink_port_attrs attrs = {};
struct devlink *dl;
int rc;
@@ -719,9 +720,11 @@ int bnxt_dl_register(struct bnxt *bp)
if (!BNXT_PF(bp))
return 0;
- devlink_port_attrs_set(&bp->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- bp->pf.port_id, false, 0, bp->dsn,
- sizeof(bp->dsn));
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = bp->pf.port_id;
+ memcpy(attrs.switch_id.id, bp->dsn, sizeof(bp->dsn));
+ attrs.switch_id.id_len = sizeof(bp->dsn);
+ devlink_port_attrs_set(&bp->dl_port, &attrs);
rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
if (rc) {
netdev_err(bp->dev, "devlink_port_register failed\n");
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
index 3ea470e8cfa2..43da2dcb0cbc 100644
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
@@ -312,6 +312,7 @@ int ice_devlink_create_port(struct ice_pf *pf)
struct devlink *devlink = priv_to_devlink(pf);
struct ice_vsi *vsi = ice_get_main_vsi(pf);
struct device *dev = ice_pf_to_dev(pf);
+ struct devlink_port_attrs attrs = {};
int err;
if (!vsi) {
@@ -319,8 +320,9 @@ int ice_devlink_create_port(struct ice_pf *pf)
return -EIO;
}
- devlink_port_attrs_set(&pf->devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- pf->hw.pf_id, false, 0, NULL, 0);
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = pf->hw.pf_id;
+ devlink_port_attrs_set(&pf->devlink_port, &attrs);
err = devlink_port_register(devlink, &pf->devlink_port, pf->hw.pf_id);
if (err) {
dev_err(dev, "devlink_port_register failed: %d\n", err);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
index f8b2de4b04be..a69c62d72d16 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
@@ -6,17 +6,16 @@
int mlx5e_devlink_port_register(struct mlx5e_priv *priv)
{
struct devlink *devlink = priv_to_devlink(priv->mdev);
+ struct devlink_port_attrs attrs = {};
- if (mlx5_core_is_pf(priv->mdev))
- devlink_port_attrs_set(&priv->dl_port,
- DEVLINK_PORT_FLAVOUR_PHYSICAL,
- PCI_FUNC(priv->mdev->pdev->devfn),
- false, 0,
- NULL, 0);
- else
- devlink_port_attrs_set(&priv->dl_port,
- DEVLINK_PORT_FLAVOUR_VIRTUAL,
- 0, false, 0, NULL, 0);
+ if (mlx5_core_is_pf(priv->mdev)) {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = PCI_FUNC(priv->mdev->pdev->devfn);
+ } else {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_VIRTUAL;
+ }
+
+ devlink_port_attrs_set(&priv->dl_port, &attrs);
return devlink_port_register(devlink, &priv->dl_port, 1);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index ed2430677b12..0a69f10ac30c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1185,6 +1185,7 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
{
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_eswitch_rep *rep = rpriv->rep;
+ struct devlink_port_attrs attrs = {};
struct netdev_phys_item_id ppid = {};
unsigned int dl_port_index = 0;
u16 pfnum;
@@ -1195,19 +1196,16 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, rep->vport);
pfnum = PCI_FUNC(dev->pdev->devfn);
-
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = pfnum;
+ memcpy(attrs.switch_id.id, &ppid.id[0], ppid.id_len);
+ attrs.switch_id.id_len = ppid.id_len;
if (rep->vport == MLX5_VPORT_UPLINK)
- devlink_port_attrs_set(&rpriv->dl_port,
- DEVLINK_PORT_FLAVOUR_PHYSICAL,
- pfnum, false, 0,
- &ppid.id[0], ppid.id_len);
+ devlink_port_attrs_set(&rpriv->dl_port, &attrs);
else if (rep->vport == MLX5_VPORT_PF)
- devlink_port_attrs_pci_pf_set(&rpriv->dl_port,
- &ppid.id[0], ppid.id_len,
- pfnum);
+ devlink_port_attrs_pci_pf_set(&rpriv->dl_port, pfnum);
else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport))
devlink_port_attrs_pci_vf_set(&rpriv->dl_port,
- &ppid.id[0], ppid.id_len,
pfnum, rep->vport - 1);
return devlink_port_register(devlink, &rpriv->dl_port, dl_port_index);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index e9ccd333f61d..8b3791d73c99 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -2122,6 +2122,7 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
enum devlink_port_flavour flavour,
u32 port_number, bool split,
u32 split_port_subnumber,
+ bool splittable, u32 lanes,
const unsigned char *switch_id,
unsigned char switch_id_len)
{
@@ -2129,12 +2130,19 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
struct mlxsw_core_port *mlxsw_core_port =
&mlxsw_core->ports[local_port];
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
+ struct devlink_port_attrs attrs = {};
int err;
+ attrs.split = split;
+ attrs.lanes = lanes;
+ attrs.splittable = splittable;
+ attrs.flavour = flavour;
+ attrs.phys.port_number = port_number;
+ attrs.phys.split_subport_number = split_port_subnumber;
+ memcpy(attrs.switch_id.id, switch_id, switch_id_len);
+ attrs.switch_id.id_len = switch_id_len;
mlxsw_core_port->local_port = local_port;
- devlink_port_attrs_set(devlink_port, flavour, port_number,
- split, split_port_subnumber,
- switch_id, switch_id_len);
+ devlink_port_attrs_set(devlink_port, &attrs);
err = devlink_port_register(devlink, devlink_port, local_port);
if (err)
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
@@ -2154,12 +2162,14 @@ static void __mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
u32 port_number, bool split,
u32 split_port_subnumber,
+ bool splittable, u32 lanes,
const unsigned char *switch_id,
unsigned char switch_id_len)
{
return __mlxsw_core_port_init(mlxsw_core, local_port,
DEVLINK_PORT_FLAVOUR_PHYSICAL,
port_number, split, split_port_subnumber,
+ splittable, lanes,
switch_id, switch_id_len);
}
EXPORT_SYMBOL(mlxsw_core_port_init);
@@ -2181,7 +2191,7 @@ int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
err = __mlxsw_core_port_init(mlxsw_core, MLXSW_PORT_CPU_PORT,
DEVLINK_PORT_FLAVOUR_CPU,
- 0, false, 0,
+ 0, false, 0, false, 0,
switch_id, switch_id_len);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 22b0dfa7cfae..7d6b0a232789 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -191,8 +191,8 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
- u32 port_number, bool split,
- u32 split_port_subnumber,
+ u32 port_number, bool split, u32 split_port_subnumber,
+ bool splittable, u32 lanes,
const unsigned char *switch_id,
unsigned char switch_id_len);
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
index c4caeeadcba9..c010db2c9dba 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -164,8 +164,8 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
int err;
err = mlxsw_core_port_init(mlxsw_m->core, local_port,
- module + 1, false, 0,
- mlxsw_m->base_mac,
+ module + 1, false, 0, false,
+ 0, mlxsw_m->base_mac,
sizeof(mlxsw_m->base_mac));
if (err) {
dev_err(mlxsw_m->bus_info->dev, "Port %d: Failed to init core port\n",
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 81bb9ea1479b..eeeafd1d82ce 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1733,12 +1733,16 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
bool split = !!split_base_local_port;
struct mlxsw_sp_port *mlxsw_sp_port;
+ u32 lanes = port_mapping->width;
struct net_device *dev;
+ bool splittable;
int err;
+ splittable = lanes > 1 && !split;
err = mlxsw_core_port_init(mlxsw_sp->core, local_port,
port_mapping->module + 1, split,
- port_mapping->lane / port_mapping->width,
+ port_mapping->lane / lanes,
+ splittable, lanes,
mlxsw_sp->base_mac,
sizeof(mlxsw_sp->base_mac));
if (err) {
@@ -2232,13 +2236,6 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
return -EINVAL;
}
- /* Split ports cannot be split. */
- if (mlxsw_sp_port->split) {
- netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
- NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further");
- return -EINVAL;
- }
-
max_width = mlxsw_core_module_max_width(mlxsw_core,
mlxsw_sp_port->mapping.module);
if (max_width < 0) {
@@ -2247,19 +2244,13 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
return max_width;
}
- /* Split port with non-max and 1 module width cannot be split. */
- if (mlxsw_sp_port->mapping.width != max_width || max_width == 1) {
+ /* Split port with non-max cannot be split. */
+ if (mlxsw_sp_port->mapping.width != max_width) {
netdev_err(mlxsw_sp_port->dev, "Port cannot be split\n");
NL_SET_ERR_MSG_MOD(extack, "Port cannot be split");
return -EINVAL;
}
- if (count == 1 || !is_power_of_2(count) || count > max_width) {
- netdev_err(mlxsw_sp_port->dev, "Invalid split count\n");
- NL_SET_ERR_MSG_MOD(extack, "Invalid split count");
- return -EINVAL;
- }
-
offset = mlxsw_sp_local_ports_offset(mlxsw_core, count, max_width);
if (offset < 0) {
netdev_err(mlxsw_sp_port->dev, "Cannot obtain local port offset\n");
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchib.c b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
index 4ff1e623aa76..1e561132eb1e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchib.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
@@ -281,7 +281,7 @@ static int mlxsw_sib_port_create(struct mlxsw_sib *mlxsw_sib, u8 local_port,
int err;
err = mlxsw_core_port_init(mlxsw_sib->core, local_port,
- module + 1, false, 0,
+ module + 1, false, 0, false, 0,
mlxsw_sib->hw_id, sizeof(mlxsw_sib->hw_id));
if (err) {
dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to init core port\n",
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index b438f5576e18..6f9a725662fb 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -1107,7 +1107,7 @@ static int mlxsw_sx_port_eth_create(struct mlxsw_sx *mlxsw_sx, u8 local_port,
int err;
err = mlxsw_core_port_init(mlxsw_sx->core, local_port,
- module + 1, false, 0,
+ module + 1, false, 0, false, 0,
mlxsw_sx->hw_id, sizeof(mlxsw_sx->hw_id));
if (err) {
dev_err(mlxsw_sx->bus_info->dev, "Port %d: Failed to init core port\n",
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index 07dbf4d72227..be52510d446b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -70,9 +70,6 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
unsigned int lanes;
int ret;
- if (count < 2)
- return -EINVAL;
-
mutex_lock(&pf->lock);
rtnl_lock();
@@ -81,7 +78,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
if (ret)
goto out;
- if (eth_port.is_split || eth_port.port_lanes % count) {
+ if (eth_port.port_lanes % count) {
ret = -EINVAL;
goto out;
}
@@ -353,6 +350,7 @@ const struct devlink_ops nfp_devlink_ops = {
int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
{
+ struct devlink_port_attrs attrs = {};
struct nfp_eth_table_port eth_port;
struct devlink *devlink;
const u8 *serial;
@@ -365,10 +363,15 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
if (ret)
return ret;
+ attrs.split = eth_port.is_split;
+ attrs.splittable = !attrs.split;
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = eth_port.label_port;
+ attrs.phys.split_subport_number = eth_port.label_subport;
serial_len = nfp_cpp_serial(port->app->cpp, &serial);
- devlink_port_attrs_set(&port->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- eth_port.label_port, eth_port.is_split,
- eth_port.label_subport, serial, serial_len);
+ memcpy(attrs.switch_id.id, serial, serial_len);
+ attrs.switch_id.id_len = serial_len;
+ devlink_port_attrs_set(&port->dl_port, &attrs);
devlink = priv_to_devlink(app->pf);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
index 2d590e571133..c4f4fd469fe3 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
@@ -69,6 +69,7 @@ void ionic_devlink_free(struct ionic *ionic)
int ionic_devlink_register(struct ionic *ionic)
{
struct devlink *dl = priv_to_devlink(ionic);
+ struct devlink_port_attrs attrs = {};
int err;
err = devlink_register(dl, ionic->dev);
@@ -77,8 +78,8 @@ int ionic_devlink_register(struct ionic *ionic)
return err;
}
- devlink_port_attrs_set(&ionic->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- 0, false, 0, NULL, 0);
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ devlink_port_attrs_set(&ionic->dl_port, &attrs);
err = devlink_port_register(dl, &ionic->dl_port, 0);
if (err)
dev_err(ionic->dev, "devlink_port_register failed: %d\n", err);
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index ec6b6f7818ac..0dc2c66a5d56 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -889,6 +889,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
unsigned int port_index)
{
+ struct devlink_port_attrs attrs = {};
struct nsim_dev_port *nsim_dev_port;
struct devlink_port *devlink_port;
int err;
@@ -899,10 +900,11 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
nsim_dev_port->port_index = port_index;
devlink_port = &nsim_dev_port->devlink_port;
- devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- port_index + 1, 0, 0,
- nsim_dev->switch_id.id,
- nsim_dev->switch_id.id_len);
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = port_index + 1;
+ memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
+ attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
+ devlink_port_attrs_set(devlink_port, &attrs);
err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
port_index);
if (err)