All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH net-next 0/8] Expose devlink port attributes
@ 2020-06-02 11:31 Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 1/8] devlink: Move set attribute of devlink_port_attrs to devlink_port Danielle Ratson
                   ` (9 more replies)
  0 siblings, 10 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

Currently, user has no way of knowing if a port can be split and into
how many ports.

Among other things, it is currently impossible to write generic tests
for port split.

In order to be able to expose the information regarding the split
capability to user space, set the required attributes and pass them to
netlink.

Patch 1: Move set attribute from devlink_port_attrs to devlink_port.
Patch 2: Move switch_port attribute from devlink_port_attrs to devlink_port
Patch 3: Replace devlink_port_attrs_set parameters with a struct.
Patch 4: Set and initialize lanes attribute in the driver.
Patch 5: Add lanes attribute to devlink port and pass to netlink.
Patch 6: Set and initialize splittable attribute in the driver.
Patch 7: Add splittable attribute to devlink port and pass them to netlink.
Patch 8: Add a split port test.


Danielle Ratson (8):
  devlink: Move set attribute of devlink_port_attrs to devlink_port
  devlink: Move switch_port attribute of devlink_port_attrs to
    devlink_port
  devlink: Replace devlink_port_attrs_set parameters with a struct
  mlxsw: Set number of port lanes attribute in driver
  devlink: Add a new devlink port lanes attribute and pass to netlink
  mlxsw: Set port split ability attribute in driver
  devlink: Add a new devlink port split ability attribute and pass to
    netlink
  selftests: net: Add port split test

 .../net/ethernet/broadcom/bnxt/bnxt_devlink.c |  13 +-
 drivers/net/ethernet/intel/ice/ice_devlink.c  |   6 +-
 .../ethernet/mellanox/mlx5/core/en/devlink.c  |  19 +-
 .../net/ethernet/mellanox/mlx5/core/en_rep.c  |  20 +-
 drivers/net/ethernet/mellanox/mlxsw/core.c    |  18 +-
 drivers/net/ethernet/mellanox/mlxsw/core.h    |   4 +-
 drivers/net/ethernet/mellanox/mlxsw/minimal.c |   4 +-
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |   6 +-
 .../net/ethernet/mellanox/mlxsw/switchib.c    |   2 +-
 .../net/ethernet/mellanox/mlxsw/switchx2.c    |   2 +-
 .../net/ethernet/netronome/nfp/nfp_devlink.c  |  12 +-
 .../ethernet/pensando/ionic/ionic_devlink.c   |   5 +-
 drivers/net/netdevsim/dev.c                   |  14 +-
 include/net/devlink.h                         |  20 +-
 include/uapi/linux/devlink.h                  |   3 +
 net/core/devlink.c                            |  86 +++---
 net/dsa/dsa2.c                                |  17 +-
 tools/testing/selftests/net/Makefile          |   1 +
 .../selftests/net/devlink_port_split.py       | 259 ++++++++++++++++++
 19 files changed, 399 insertions(+), 112 deletions(-)
 create mode 100755 tools/testing/selftests/net/devlink_port_split.py

-- 
2.20.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 1/8] devlink: Move set attribute of devlink_port_attrs to devlink_port
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 2/8] devlink: Move switch_port " Danielle Ratson
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

The struct devlink_port_attrs holds the attributes of devlink_port.

The 'set' field is not devlink_port's attribute as opposed to most of the
others.

Move 'set' to be devlink_port's field called 'attrs_set'.

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/devlink.h | 4 ++--
 net/core/devlink.c    | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/net/devlink.h b/include/net/devlink.h
index 1df6dfec26c2..3e4efd51d5c5 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -65,8 +65,7 @@ struct devlink_port_pci_vf_attrs {
 };
 
 struct devlink_port_attrs {
-	u8 set:1,
-	   split:1,
+	u8 split:1,
 	   switch_port:1;
 	enum devlink_port_flavour flavour;
 	struct netdev_phys_item_id switch_id;
@@ -90,6 +89,7 @@ struct devlink_port {
 	enum devlink_port_type desired_type;
 	void *type_dev;
 	struct devlink_port_attrs attrs;
+	u8 attrs_set:1;
 	struct delayed_work type_warn_dw;
 };
 
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 2cafbc808b09..e5e594d15d3e 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -524,7 +524,7 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 {
 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 
-	if (!attrs->set)
+	if (!devlink_port->attrs_set)
 		return 0;
 	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
 		return -EMSGSIZE;
@@ -7385,7 +7385,7 @@ static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
 
 	if (WARN_ON(devlink_port->registered))
 		return -EEXIST;
-	attrs->set = true;
+	devlink_port->attrs_set = true;
 	attrs->flavour = flavour;
 	if (switch_id) {
 		attrs->switch_port = true;
@@ -7493,7 +7493,7 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 	int n = 0;
 
-	if (!attrs->set)
+	if (!devlink_port->attrs_set)
 		return -EOPNOTSUPP;
 
 	switch (attrs->flavour) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 2/8] devlink: Move switch_port attribute of devlink_port_attrs to devlink_port
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 1/8] devlink: Move set attribute of devlink_port_attrs to devlink_port Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 3/8] devlink: Replace devlink_port_attrs_set parameters with a struct Danielle Ratson
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

The struct devlink_port_attrs holds the attributes of devlink_port.

Similarly to the previous patch, 'switch_port' attribute is another
exception.

Move 'switch_port' to be devlink_port's field.

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/devlink.h | 6 +++---
 net/core/devlink.c    | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/net/devlink.h b/include/net/devlink.h
index 3e4efd51d5c5..4d840997690a 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -65,8 +65,7 @@ struct devlink_port_pci_vf_attrs {
 };
 
 struct devlink_port_attrs {
-	u8 split:1,
-	   switch_port:1;
+	u8 split:1;
 	enum devlink_port_flavour flavour;
 	struct netdev_phys_item_id switch_id;
 	union {
@@ -89,7 +88,8 @@ struct devlink_port {
 	enum devlink_port_type desired_type;
 	void *type_dev;
 	struct devlink_port_attrs attrs;
-	u8 attrs_set:1;
+	u8 attrs_set:1,
+	   switch_port:1;
 	struct delayed_work type_warn_dw;
 };
 
diff --git a/net/core/devlink.c b/net/core/devlink.c
index e5e594d15d3e..c4507fd9fc11 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -7388,13 +7388,13 @@ static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
 	devlink_port->attrs_set = true;
 	attrs->flavour = flavour;
 	if (switch_id) {
-		attrs->switch_port = true;
+		devlink_port->switch_port = true;
 		if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
 			switch_id_len = MAX_PHYS_ITEM_ID_LEN;
 		memcpy(attrs->switch_id.id, switch_id, switch_id_len);
 		attrs->switch_id.id_len = switch_id_len;
 	} else {
-		attrs->switch_port = false;
+		devlink_port->switch_port = false;
 	}
 	return 0;
 }
@@ -9328,7 +9328,7 @@ int devlink_compat_switch_id_get(struct net_device *dev,
 	 * any devlink lock as only permanent values are accessed.
 	 */
 	devlink_port = netdev_to_devlink_port(dev);
-	if (!devlink_port || !devlink_port->attrs.switch_port)
+	if (!devlink_port || !devlink_port->switch_port)
 		return -EOPNOTSUPP;
 
 	memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 3/8] devlink: Replace devlink_port_attrs_set parameters with a struct
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 1/8] devlink: Move set attribute of devlink_port_attrs to devlink_port Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 2/8] devlink: Move switch_port " Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 4/8] mlxsw: Set number of port lanes attribute in driver Danielle Ratson
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

Currently, devlink_port_attrs_set accepts a long list of parameters,
that most of them are devlink port's attributes.

Use the devlink_port_attrs struct to replace the relevant parameters.

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/broadcom/bnxt/bnxt_devlink.c | 13 +++-
 drivers/net/ethernet/intel/ice/ice_devlink.c  |  6 +-
 .../ethernet/mellanox/mlx5/core/en/devlink.c  | 19 +++---
 .../net/ethernet/mellanox/mlx5/core/en_rep.c  | 20 +++---
 drivers/net/ethernet/mellanox/mlxsw/core.c    | 11 +++-
 .../net/ethernet/netronome/nfp/nfp_devlink.c  | 11 +++-
 .../ethernet/pensando/ionic/ionic_devlink.c   |  5 +-
 drivers/net/netdevsim/dev.c                   | 14 ++--
 include/net/devlink.h                         | 12 +---
 net/core/devlink.c                            | 64 ++++++-------------
 net/dsa/dsa2.c                                | 17 +++--
 11 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index a812beb46325..babaccf92b23 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -685,6 +685,9 @@ static void bnxt_dl_params_unregister(struct bnxt *bp)
 
 int bnxt_dl_register(struct bnxt *bp)
 {
+	struct devlink_port_attrs attrs = {};
+	const unsigned char *switch_id;
+	unsigned char switch_id_len;
 	struct devlink *dl;
 	int rc;
 
@@ -713,9 +716,13 @@ 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;
+	switch_id = bp->dsn;
+	switch_id_len = sizeof(bp->dsn);
+	memcpy(attrs.switch_id.id, switch_id, switch_id_len);
+	attrs.switch_id.id_len = switch_id_len;
+	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 a73d06e06b5d..69715a0cbfe8 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 af89a4803c7d..e6f467037c5c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1193,8 +1193,11 @@ 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;
+	const unsigned char *switch_id;
+	unsigned char switch_id_len;
 	u16 pfnum;
 
 	if (!is_devlink_port_supported(dev, rpriv))
@@ -1203,19 +1206,18 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
 	mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
 	dl_port_index = 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;
+	switch_id = &ppid.id[0];
+	switch_id_len = ppid.id_len;
+	memcpy(attrs.switch_id.id, switch_id, switch_id_len);
+	attrs.switch_id.id_len = switch_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..bbe7358d4ea5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -2129,12 +2129,17 @@ 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.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));
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index 07dbf4d72227..71f4e624b3db 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -353,6 +353,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 +366,14 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
 	if (ret)
 		return ret;
 
+	attrs.split = eth_port.is_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 273c889faaad..aa224d0cfa54 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);
@@ -81,8 +82,8 @@ int ionic_devlink_register(struct ionic *ionic)
 	if (ionic->is_mgmt_nic)
 		return 0;
 
-	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..d88316ea8684 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -889,8 +889,11 @@ 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;
+	const unsigned char *switch_id;
+	unsigned char switch_id_len;
 	int err;
 
 	nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
@@ -899,10 +902,13 @@ 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;
+	switch_id = nsim_dev->switch_id.id;
+	switch_id_len = nsim_dev->switch_id.id_len;
+	memcpy(attrs.switch_id.id, switch_id, switch_id_len);
+	attrs.switch_id.id_len = switch_id_len;
+	devlink_port_attrs_set(devlink_port, &attrs);
 	err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
 				    port_index);
 	if (err)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 4d840997690a..96fe5c05f62f 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1158,17 +1158,9 @@ void devlink_port_type_ib_set(struct devlink_port *devlink_port,
 			      struct ib_device *ibdev);
 void devlink_port_type_clear(struct devlink_port *devlink_port);
 void devlink_port_attrs_set(struct devlink_port *devlink_port,
-			    enum devlink_port_flavour flavour,
-			    u32 port_number, bool split,
-			    u32 split_subport_number,
-			    const unsigned char *switch_id,
-			    unsigned char switch_id_len);
-void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
-				   const unsigned char *switch_id,
-				   unsigned char switch_id_len, u16 pf);
+			    struct devlink_port_attrs *devlink_port_attrs);
+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf);
 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
-				   const unsigned char *switch_id,
-				   unsigned char switch_id_len,
 				   u16 pf, u16 vf);
 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
 			u32 size, u16 ingress_pools_count,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index c4507fd9fc11..6a783e712794 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -7377,9 +7377,7 @@ void devlink_port_type_clear(struct devlink_port *devlink_port)
 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
 
 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
-				    enum devlink_port_flavour flavour,
-				    const unsigned char *switch_id,
-				    unsigned char switch_id_len)
+				    enum devlink_port_flavour flavour)
 {
 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 
@@ -7387,12 +7385,10 @@ static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
 		return -EEXIST;
 	devlink_port->attrs_set = true;
 	attrs->flavour = flavour;
-	if (switch_id) {
+	if (attrs->switch_id.id) {
 		devlink_port->switch_port = true;
-		if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
-			switch_id_len = MAX_PHYS_ITEM_ID_LEN;
-		memcpy(attrs->switch_id.id, switch_id, switch_id_len);
-		attrs->switch_id.id_len = switch_id_len;
+		if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
+			attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
 	} else {
 		devlink_port->switch_port = false;
 	}
@@ -7403,33 +7399,27 @@ static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
  *	devlink_port_attrs_set - Set port attributes
  *
  *	@devlink_port: devlink port
- *	@flavour: flavour of the port
- *	@port_number: number of the port that is facing user, for example
- *	              the front panel port number
- *	@split: indicates if this is split port
- *	@split_subport_number: if the port is split, this is the number
- *	                       of subport.
- *	@switch_id: if the port is part of switch, this is buffer with ID,
- *	            otwerwise this is NULL
- *	@switch_id_len: length of the switch_id buffer
+ *	@devlink_port_attrs: devlink port attributes, holds:
+ *			     @flavour: flavour of the port
+ *			     @port_number: number of the port that is facing
+ *					   user, for example the front panel
+ *			                   port number
+ *			     @split: indicates if this is split port
+ *			     @split_subport_number: if the port is split, this
+ *			                            is the number of subport.
+ *			     @switch_id: if the port is part of switch, this is
+ *					 buffer with ID, otherwise this is NULL
+ *			     @switch_id_len: length of the switch_id buffer
  */
 void devlink_port_attrs_set(struct devlink_port *devlink_port,
-			    enum devlink_port_flavour flavour,
-			    u32 port_number, bool split,
-			    u32 split_subport_number,
-			    const unsigned char *switch_id,
-			    unsigned char switch_id_len)
+			    struct devlink_port_attrs *attrs)
 {
-	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 	int ret;
 
-	ret = __devlink_port_attrs_set(devlink_port, flavour,
-				       switch_id, switch_id_len);
+	ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
 	if (ret)
 		return;
-	attrs->split = split;
-	attrs->phys.port_number = port_number;
-	attrs->phys.split_subport_number = split_subport_number;
+	devlink_port->attrs = *attrs;
 }
 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
 
@@ -7438,20 +7428,14 @@ EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
  *
  *	@devlink_port: devlink port
  *	@pf: associated PF for the devlink port instance
- *	@switch_id: if the port is part of switch, this is buffer with ID,
- *	            otherwise this is NULL
- *	@switch_id_len: length of the switch_id buffer
  */
-void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
-				   const unsigned char *switch_id,
-				   unsigned char switch_id_len, u16 pf)
+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf)
 {
 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 	int ret;
 
 	ret = __devlink_port_attrs_set(devlink_port,
-				       DEVLINK_PORT_FLAVOUR_PCI_PF,
-				       switch_id, switch_id_len);
+				       DEVLINK_PORT_FLAVOUR_PCI_PF);
 	if (ret)
 		return;
 
@@ -7465,21 +7449,15 @@ EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
  *	@devlink_port: devlink port
  *	@pf: associated PF for the devlink port instance
  *	@vf: associated VF of a PF for the devlink port instance
- *	@switch_id: if the port is part of switch, this is buffer with ID,
- *	            otherwise this is NULL
- *	@switch_id_len: length of the switch_id buffer
  */
 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
-				   const unsigned char *switch_id,
-				   unsigned char switch_id_len,
 				   u16 pf, u16 vf)
 {
 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
 	int ret;
 
 	ret = __devlink_port_attrs_set(devlink_port,
-				       DEVLINK_PORT_FLAVOUR_PCI_VF,
-				       switch_id, switch_id_len);
+				       DEVLINK_PORT_FLAVOUR_PCI_VF);
 	if (ret)
 		return;
 	attrs->pci_vf.pf = pf;
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 076908fdd29b..e055efff390b 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -261,10 +261,15 @@ static int dsa_port_setup(struct dsa_port *dp)
 	struct devlink_port *dlp = &dp->devlink_port;
 	bool dsa_port_link_registered = false;
 	bool devlink_port_registered = false;
+	struct devlink_port_attrs attrs = {};
 	struct devlink *dl = ds->devlink;
 	bool dsa_port_enabled = false;
 	int err = 0;
 
+	attrs.phys.port_number = dp->index;
+	memcpy(attrs.switch_id.id, id, len);
+	attrs.switch_id.id_len = len;
+
 	if (dp->setup)
 		return 0;
 
@@ -274,8 +279,8 @@ static int dsa_port_setup(struct dsa_port *dp)
 		break;
 	case DSA_PORT_TYPE_CPU:
 		memset(dlp, 0, sizeof(*dlp));
-		devlink_port_attrs_set(dlp, DEVLINK_PORT_FLAVOUR_CPU,
-				       dp->index, false, 0, id, len);
+		attrs.flavour = DEVLINK_PORT_FLAVOUR_CPU;
+		devlink_port_attrs_set(dlp, &attrs);
 		err = devlink_port_register(dl, dlp, dp->index);
 		if (err)
 			break;
@@ -294,8 +299,8 @@ static int dsa_port_setup(struct dsa_port *dp)
 		break;
 	case DSA_PORT_TYPE_DSA:
 		memset(dlp, 0, sizeof(*dlp));
-		devlink_port_attrs_set(dlp, DEVLINK_PORT_FLAVOUR_DSA,
-				       dp->index, false, 0, id, len);
+		attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA;
+		devlink_port_attrs_set(dlp, &attrs);
 		err = devlink_port_register(dl, dlp, dp->index);
 		if (err)
 			break;
@@ -314,8 +319,8 @@ static int dsa_port_setup(struct dsa_port *dp)
 		break;
 	case DSA_PORT_TYPE_USER:
 		memset(dlp, 0, sizeof(*dlp));
-		devlink_port_attrs_set(dlp, DEVLINK_PORT_FLAVOUR_PHYSICAL,
-				       dp->index, false, 0, id, len);
+		attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+		devlink_port_attrs_set(dlp, &attrs);
 		err = devlink_port_register(dl, dlp, dp->index);
 		if (err)
 			break;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 4/8] mlxsw: Set number of port lanes attribute in driver
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (2 preceding siblings ...)
  2020-06-02 11:31 ` [RFC PATCH net-next 3/8] devlink: Replace devlink_port_attrs_set parameters with a struct Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 5/8] devlink: Add a new devlink port lanes attribute and pass to netlink Danielle Ratson
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

Currently, port attributes like flavour, port number and whether the
port was split are set when initializing a port.

Set the number of lanes of the port as well so that it could be easily
passed to devlink in the next patch.

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c     | 6 ++++--
 drivers/net/ethernet/mellanox/mlxsw/core.h     | 1 +
 drivers/net/ethernet/mellanox/mlxsw/minimal.c  | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 +++-
 drivers/net/ethernet/mellanox/mlxsw/switchib.c | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 2 +-
 6 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index bbe7358d4ea5..f44cb1a537f3 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,
+				  u32 lanes,
 				  const unsigned char *switch_id,
 				  unsigned char switch_id_len)
 {
@@ -2159,13 +2160,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,
+			 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,
-				      switch_id, switch_id_len);
+				      lanes, switch_id, switch_id_len);
 }
 EXPORT_SYMBOL(mlxsw_core_port_init);
 
@@ -2186,7 +2188,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, 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..b5c02e6e6865 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -193,6 +193,7 @@ 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 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..f9c9d7baf3be 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -164,7 +164,7 @@ 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,
+				   module + 1, false, 0, 0,
 				   mlxsw_m->base_mac,
 				   sizeof(mlxsw_m->base_mac));
 	if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 26e413ad3afb..4b4d639d9ba6 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3244,12 +3244,14 @@ 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;
 	int err;
 
 	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,
+				   lanes,
 				   mlxsw_sp->base_mac,
 				   sizeof(mlxsw_sp->base_mac));
 	if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchib.c b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
index 4ff1e623aa76..1b446e6071b2 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, 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..ac4cd7c23439 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, 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",
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 5/8] devlink: Add a new devlink port lanes attribute and pass to netlink
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (3 preceding siblings ...)
  2020-06-02 11:31 ` [RFC PATCH net-next 4/8] mlxsw: Set number of port lanes attribute in driver Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 6/8] mlxsw: Set port split ability attribute in driver Danielle Ratson
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

Add a new devlink port attribute that indicates the port's number of lanes.

Drivers are expected to set it via devlink_port_attrs_set(), before
registering the port.

The attribute is not passed to user space in case the number of lanes is
invalid (0).

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c | 1 +
 include/net/devlink.h                      | 1 +
 include/uapi/linux/devlink.h               | 2 ++
 net/core/devlink.c                         | 7 +++++++
 4 files changed, 11 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index f44cb1a537f3..6cde196f6b70 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -2134,6 +2134,7 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
 	int err;
 
 	attrs.split = split;
+	attrs.lanes = lanes;
 	attrs.flavour = flavour;
 	attrs.phys.port_number = port_number;
 	attrs.phys.split_subport_number = split_port_subnumber;
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 96fe5c05f62f..ee088cead80a 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -66,6 +66,7 @@ struct devlink_port_pci_vf_attrs {
 
 struct devlink_port_attrs {
 	u8 split:1;
+	u32 lanes;
 	enum devlink_port_flavour flavour;
 	struct netdev_phys_item_id switch_id;
 	union {
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 08563e6a424d..806c6a437fa2 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -451,6 +451,8 @@ enum devlink_attr {
 	DEVLINK_ATTR_TRAP_POLICER_RATE,			/* u64 */
 	DEVLINK_ATTR_TRAP_POLICER_BURST,		/* u64 */
 
+	DEVLINK_ATTR_PORT_LANES,			/* u32 */
+
 	/* add new attributes above here, update the policy in devlink.c */
 
 	__DEVLINK_ATTR_MAX,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 6a783e712794..ce82629b7386 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -526,6 +526,10 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 
 	if (!devlink_port->attrs_set)
 		return 0;
+	if (attrs->lanes) {
+		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
+			return -EMSGSIZE;
+	}
 	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
 		return -EMSGSIZE;
 	switch (devlink_port->attrs.flavour) {
@@ -7405,6 +7409,9 @@ static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
  *					   user, for example the front panel
  *			                   port number
  *			     @split: indicates if this is split port
+ *			     @lanes: maximum number of lanes the port supports.
+ *				     0 value is not passed to netlink and valid
+ *				     number is a power of 2.
  *			     @split_subport_number: if the port is split, this
  *			                            is the number of subport.
  *			     @switch_id: if the port is part of switch, this is
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 6/8] mlxsw: Set port split ability attribute in driver
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (4 preceding siblings ...)
  2020-06-02 11:31 ` [RFC PATCH net-next 5/8] devlink: Add a new devlink port lanes attribute and pass to netlink Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 7/8] devlink: Add a new devlink port split ability attribute and pass to netlink Danielle Ratson
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

Currently, port attributes like flavour, port number and whether the port
was split are set when initializing a port.

Set the split ability of the port as well, based on port_mapping->width
field and split attribute of devlink port in spectrum, so that it could be
easily passed to devlink in the next patch.

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c     | 9 +++++----
 drivers/net/ethernet/mellanox/mlxsw/core.h     | 5 ++---
 drivers/net/ethernet/mellanox/mlxsw/minimal.c  | 4 ++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 +++-
 drivers/net/ethernet/mellanox/mlxsw/switchib.c | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 2 +-
 6 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 6cde196f6b70..f85f5d88d331 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -2122,7 +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,
-				  u32 lanes,
+				  bool splittable, u32 lanes,
 				  const unsigned char *switch_id,
 				  unsigned char switch_id_len)
 {
@@ -2161,14 +2161,15 @@ 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,
-			 u32 lanes,
+			 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,
-				      lanes, switch_id, switch_id_len);
+				      splittable, lanes,
+				      switch_id, switch_id_len);
 }
 EXPORT_SYMBOL(mlxsw_core_port_init);
 
@@ -2189,7 +2190,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,
+				     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 b5c02e6e6865..7d6b0a232789 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -191,9 +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 lanes,
+			 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 f9c9d7baf3be..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, 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 4b4d639d9ba6..f40a499b7e76 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3246,12 +3246,14 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 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 / lanes,
-				   lanes,
+				   splittable, lanes,
 				   mlxsw_sp->base_mac,
 				   sizeof(mlxsw_sp->base_mac));
 	if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchib.c b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
index 1b446e6071b2..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, 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 ac4cd7c23439..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, 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",
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 7/8] devlink: Add a new devlink port split ability attribute and pass to netlink
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (5 preceding siblings ...)
  2020-06-02 11:31 ` [RFC PATCH net-next 6/8] mlxsw: Set port split ability attribute in driver Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-02 11:31 ` [RFC PATCH net-next 8/8] selftests: net: Add port split test Danielle Ratson
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson

Add a new attribute that indicates the split ability to devlink port.

Drivers are expected to set it via devlink_port_attrs_set(), before
registering the port.

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c       | 1 +
 drivers/net/ethernet/netronome/nfp/nfp_devlink.c | 1 +
 include/net/devlink.h                            | 3 ++-
 include/uapi/linux/devlink.h                     | 1 +
 net/core/devlink.c                               | 3 +++
 5 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index f85f5d88d331..8b3791d73c99 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -2135,6 +2135,7 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
 
 	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;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index 71f4e624b3db..b6a10565309a 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -367,6 +367,7 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
 		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;
diff --git a/include/net/devlink.h b/include/net/devlink.h
index ee088cead80a..3eb5fd41731f 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -65,7 +65,8 @@ struct devlink_port_pci_vf_attrs {
 };
 
 struct devlink_port_attrs {
-	u8 split:1;
+	u8 split:1,
+	   splittable:1;
 	u32 lanes;
 	enum devlink_port_flavour flavour;
 	struct netdev_phys_item_id switch_id;
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 806c6a437fa2..22bd17ba8adb 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -452,6 +452,7 @@ enum devlink_attr {
 	DEVLINK_ATTR_TRAP_POLICER_BURST,		/* u64 */
 
 	DEVLINK_ATTR_PORT_LANES,			/* u32 */
+	DEVLINK_ATTR_PORT_SPLITTABLE,			/* u8 */
 
 	/* add new attributes above here, update the policy in devlink.c */
 
diff --git a/net/core/devlink.c b/net/core/devlink.c
index ce82629b7386..a47426941e21 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -530,6 +530,8 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
 			return -EMSGSIZE;
 	}
+	if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
+		return -EMSGSIZE;
 	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
 		return -EMSGSIZE;
 	switch (devlink_port->attrs.flavour) {
@@ -7409,6 +7411,7 @@ static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
  *					   user, for example the front panel
  *			                   port number
  *			     @split: indicates if this is split port
+ *			     @splittable: indicates if the port can be split.
  *			     @lanes: maximum number of lanes the port supports.
  *				     0 value is not passed to netlink and valid
  *				     number is a power of 2.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC PATCH net-next 8/8] selftests: net: Add port split test
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (6 preceding siblings ...)
  2020-06-02 11:31 ` [RFC PATCH net-next 7/8] devlink: Add a new devlink port split ability attribute and pass to netlink Danielle Ratson
@ 2020-06-02 11:31 ` Danielle Ratson
  2020-06-03 18:12   ` Florian Fainelli
  2020-06-02 16:21 ` [RFC PATCH net-next 0/8] Expose devlink port attributes Jakub Kicinski
  2020-06-02 19:33 ` Jakub Kicinski
  9 siblings, 1 reply; 17+ messages in thread
From: Danielle Ratson @ 2020-06-02 11:31 UTC (permalink / raw)
  To: netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, f.fainelli,
	mlxsw, Danielle Ratson, Petr Machata

Test port split configuration using previously added number of port lanes
attribute.

Check that all the splittable ports are successfully split to their maximum
number of lanes and below, and that those which are not splittable fail to
be split.

Test output example:

TEST: swp4 is unsplittable                                         [ OK ]
TEST: split port swp53 into 4                                      [ OK ]
TEST: Unsplit port pci/0000:03:00.0/25                             [ OK ]
TEST: split port swp53 into 2                                      [ OK ]
TEST: Unsplit port pci/0000:03:00.0/25                             [ OK ]

Signed-off-by: Danielle Ratson <danieller@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
---
 tools/testing/selftests/net/Makefile          |   1 +
 .../selftests/net/devlink_port_split.py       | 259 ++++++++++++++++++
 2 files changed, 260 insertions(+)
 create mode 100755 tools/testing/selftests/net/devlink_port_split.py

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 895ec992b2f1..90fcf8ba9ed0 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -17,6 +17,7 @@ TEST_PROGS += route_localnet.sh
 TEST_PROGS += reuseaddr_ports_exhausted.sh
 TEST_PROGS += txtimestamp.sh
 TEST_PROGS += vrf-xfrm-tests.sh
+TEST_PROGS += devlink_port_split.py
 TEST_PROGS_EXTENDED := in_netns.sh
 TEST_GEN_FILES =  socket nettest
 TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
diff --git a/tools/testing/selftests/net/devlink_port_split.py b/tools/testing/selftests/net/devlink_port_split.py
new file mode 100755
index 000000000000..738bee04e1eb
--- /dev/null
+++ b/tools/testing/selftests/net/devlink_port_split.py
@@ -0,0 +1,259 @@
+#!/usr/bin/python3
+# SPDX-License-Identifier: GPL-2.0
+
+from subprocess import PIPE, Popen
+import json
+import time
+import argparse
+import collections
+import sys
+
+#
+# Test port split configuration using devlink-port lanes attribute.
+# The test is skipped in case the attribute is not available.
+#
+# First, check that all the ports with 1 lane fail to split.
+# Second, check that all the ports with more than 1 lane can be split
+# to all valid configurations (e.g., split to 2, split to 4 etc.)
+#
+
+
+Port = collections.namedtuple('Port', 'bus_info name')
+
+
+def run_command(cmd, should_fail=False):
+    """
+    Run a command in subprocess.
+    Return: Tuple of (stdout, stderr).
+    """
+
+    p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
+    stdout, stderr = p.communicate()
+    stdout, stderr = stdout.decode(), stderr.decode()
+
+    if stderr != "" and not should_fail:
+        print("Error sending command: %s" % cmd)
+        print(stdout)
+        print(stderr)
+    return stdout, stderr
+
+
+class devlink_ports(object):
+    """
+    Class that holds information on the devlink ports, required to the tests;
+    if_names: A list of interfaces in the devlink ports.
+    """
+
+    def get_if_names(dev):
+        """
+        Get a list of physical devlink ports.
+        Return: Array of tuples (bus_info/port, if_name).
+        """
+
+        arr = []
+
+        cmd = "devlink -j port show"
+        stdout, stderr = run_command(cmd)
+        assert stderr == ""
+        ports = json.loads(stdout)['port']
+
+        for port in ports:
+            if dev in port:
+                if ports[port]['flavour'] == 'physical':
+                    arr.append(Port(bus_info=port, name=ports[port]['netdev']))
+
+        return arr
+
+    def __init__(self, dev):
+        self.if_names = devlink_ports.get_if_names(dev)
+
+
+def get_max_lanes(port):
+    """
+    Get the $port's maximum number of lanes.
+    Return: number of lanes, e.g. 1, 2, 4 and 8.
+    """
+
+    cmd = "devlink -j port show %s" % port
+    stdout, stderr = run_command(cmd)
+    assert stderr == ""
+    values = list(json.loads(stdout)['port'].values())[0]
+
+    if 'lanes' in values:
+        lanes = values['lanes']
+    else:
+        lanes = 0
+    return lanes
+
+
+def split(k, port, should_fail=False):
+    """
+    Split $port into $k ports.
+    If should_fail == True, the split should fail. Otherwise, should pass.
+    Return: Array of sub ports after splitting.
+            If the $port wasn't split, the array will be empty.
+    """
+
+    cmd = "devlink port split %s count %s" % (port.bus_info, k)
+    stdout, stderr = run_command(cmd, should_fail=should_fail)
+
+    if should_fail:
+        if not test(stderr != "", "%s is unsplittable" % port.name):
+            print("split an unsplittable port %s" % port.name)
+            return create_split_group(port, k)
+    else:
+        if stderr == "":
+            return create_split_group(port, k)
+        print("didn't split a splittable port %s" % port.name)
+
+    return []
+
+
+def unsplit(port):
+    """
+    Unsplit $port.
+    """
+
+    cmd = "devlink port unsplit %s" % port
+    stdout, stderr = run_command(cmd)
+    test(stderr == "", "Unsplit port %s" % port)
+
+
+def exists(port, dev):
+    """
+    Check if $port exists in the devlink ports.
+    Return: True is so, False otherwise.
+    """
+
+    return any(dev_port.name == port
+               for dev_port in devlink_ports.get_if_names(dev))
+
+
+def exists_and_lanes(ports, lanes, dev):
+    """
+    Check if every port in the list $ports exists in the devlink ports and has
+    $lanes number of lanes after splitting.
+    Return: True if both are True, False otherwise.
+    """
+
+    for port in ports:
+        max_lanes = get_max_lanes(port)
+        if not exists(port, dev):
+            print("port %s doesn't exist in devlink ports" % port)
+            return False
+        if max_lanes != lanes:
+            print("port %s has %d lanes, but %s were expected"
+                  % (port, lanes, max_lanes))
+            return False
+    return True
+
+
+def test(cond, msg):
+    """
+    Check $cond and print a message accordingly.
+    Return: True is pass, False otherwise.
+    """
+
+    if cond:
+        print("TEST: %-60s [ OK ]" % msg)
+    else:
+        print("TEST: %-60s [FAIL]" % msg)
+
+    return cond
+
+
+def create_split_group(port, k):
+    """
+    Create the split group for $port.
+    Return: Array with $k elements, which are the split port group.
+    """
+
+    return list(port.name + "s" + str(i) for i in range(k))
+
+
+def split_unsplittable_port(port, k):
+    """
+    Test that splitting of unsplittable port fails.
+    """
+
+    # split to max
+    new_split_group = split(k, port, should_fail=True)
+
+    if new_split_group != []:
+        unsplit(port.bus_info)
+
+
+def split_splittable_port(port, k, lanes, dev):
+    """
+    Test that splitting of splittable port passes correctly.
+    """
+
+    new_split_group = split(k, port)
+
+    # Once the split command ends, it takes some time to the sub ifaces'
+    # to get their names. Use udevadm to continue only when all current udev
+    # events are handled.
+    cmd = "udevadm settle"
+    stdout, stderr = run_command(cmd)
+    assert stderr == ""
+
+    if new_split_group != []:
+        test(exists_and_lanes(new_split_group, lanes/k, dev),
+             "split port %s into %s" % (port.name, k))
+
+    unsplit(port.bus_info)
+
+
+def make_parser():
+    parser = argparse.ArgumentParser(description='A test for port splitting.')
+    parser.add_argument('--dev',
+                        help='The devlink handle of the device under test. ' +
+                             'The default is the first registered devlink ' +
+                             'handle.')
+
+    return parser
+
+
+def main(cmdline=None):
+    parser = make_parser()
+    args = parser.parse_args(cmdline)
+
+    dev = args.dev
+    if not dev:
+        cmd = "devlink -j dev show"
+        stdout, stderr = run_command(cmd)
+        assert stderr == ""
+
+        devs = json.loads(stdout)['dev']
+        dev = list(devs.keys())[0]
+
+    cmd = "devlink dev show %s" % dev
+    stdout, stderr = run_command(cmd)
+    if stderr != "":
+        print("devlink device %s can not be found" % dev)
+        sys.exit(1)
+
+    ports = devlink_ports(dev)
+
+    for port in ports.if_names:
+        max_lanes = get_max_lanes(port.name)
+
+        # If max lanes is 0, do not test port splitting at all
+        if max_lanes == 0:
+            continue
+
+        # If 1 lane, shouldn't be able to split
+        elif max_lanes == 1:
+            split_unsplittable_port(port, max_lanes)
+
+        # Else, splitting should pass and all the split ports should exist.
+        else:
+            lane = max_lanes
+            while lane > 1:
+                split_splittable_port(port, lane, max_lanes, dev)
+
+                lane //= 2
+
+
+if __name__ == "__main__":
+    main()
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 0/8] Expose devlink port attributes
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (7 preceding siblings ...)
  2020-06-02 11:31 ` [RFC PATCH net-next 8/8] selftests: net: Add port split test Danielle Ratson
@ 2020-06-02 16:21 ` Jakub Kicinski
  2020-06-02 19:33 ` Jakub Kicinski
  9 siblings, 0 replies; 17+ messages in thread
From: Jakub Kicinski @ 2020-06-02 16:21 UTC (permalink / raw)
  To: Danielle Ratson
  Cc: netdev, davem, michael.chan, jeffrey.t.kirsher, saeedm, leon,
	jiri, idosch, snelson, drivers, andrew, vivien.didelot,
	f.fainelli, mlxsw

On Tue,  2 Jun 2020 14:31:11 +0300 Danielle Ratson wrote:
> Currently, user has no way of knowing if a port can be split and into
> how many ports.
> 
> Among other things, it is currently impossible to write generic tests
> for port split.
> 
> In order to be able to expose the information regarding the split
> capability to user space, set the required attributes and pass them to
> netlink.

Hi! Looks like patches 3, 5, and 7 add warnings when built with W=1 C=1.
Unfortunately there are 500 existing warnings I can't figure out which
ones are new :(

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 0/8] Expose devlink port attributes
  2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
                   ` (8 preceding siblings ...)
  2020-06-02 16:21 ` [RFC PATCH net-next 0/8] Expose devlink port attributes Jakub Kicinski
@ 2020-06-02 19:33 ` Jakub Kicinski
  2020-06-03 10:45   ` Jiri Pirko
  9 siblings, 1 reply; 17+ messages in thread
From: Jakub Kicinski @ 2020-06-02 19:33 UTC (permalink / raw)
  To: Danielle Ratson
  Cc: netdev, davem, michael.chan, jeffrey.t.kirsher, saeedm, leon,
	jiri, idosch, snelson, drivers, andrew, vivien.didelot,
	f.fainelli, mlxsw

On Tue,  2 Jun 2020 14:31:11 +0300 Danielle Ratson wrote:
> Currently, user has no way of knowing if a port can be split and into
> how many ports.
> 
> Among other things, it is currently impossible to write generic tests
> for port split.
> 
> In order to be able to expose the information regarding the split
> capability to user space, set the required attributes and pass them to
> netlink.
> 
> Patch 1: Move set attribute from devlink_port_attrs to devlink_port.
> Patch 2: Move switch_port attribute from devlink_port_attrs to devlink_port
> Patch 3: Replace devlink_port_attrs_set parameters with a struct.
> Patch 4: Set and initialize lanes attribute in the driver.
> Patch 5: Add lanes attribute to devlink port and pass to netlink.
> Patch 6: Set and initialize splittable attribute in the driver.
> Patch 7: Add splittable attribute to devlink port and pass them to netlink.
> Patch 8: Add a split port test.

Since we have the splitability and number of lanes now understood by
the core - can the code also start doing more input checking?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 0/8] Expose devlink port attributes
  2020-06-02 19:33 ` Jakub Kicinski
@ 2020-06-03 10:45   ` Jiri Pirko
  2020-06-04  2:48     ` Jakub Kicinski
  0 siblings, 1 reply; 17+ messages in thread
From: Jiri Pirko @ 2020-06-03 10:45 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Danielle Ratson, netdev, davem, michael.chan, jeffrey.t.kirsher,
	saeedm, leon, jiri, idosch, snelson, drivers, andrew,
	vivien.didelot, f.fainelli, mlxsw

Tue, Jun 02, 2020 at 09:33:11PM CEST, kuba@kernel.org wrote:
>On Tue,  2 Jun 2020 14:31:11 +0300 Danielle Ratson wrote:
>> Currently, user has no way of knowing if a port can be split and into
>> how many ports.
>> 
>> Among other things, it is currently impossible to write generic tests
>> for port split.
>> 
>> In order to be able to expose the information regarding the split
>> capability to user space, set the required attributes and pass them to
>> netlink.
>> 
>> Patch 1: Move set attribute from devlink_port_attrs to devlink_port.
>> Patch 2: Move switch_port attribute from devlink_port_attrs to devlink_port
>> Patch 3: Replace devlink_port_attrs_set parameters with a struct.
>> Patch 4: Set and initialize lanes attribute in the driver.
>> Patch 5: Add lanes attribute to devlink port and pass to netlink.
>> Patch 6: Set and initialize splittable attribute in the driver.
>> Patch 7: Add splittable attribute to devlink port and pass them to netlink.
>> Patch 8: Add a split port test.
>
>Since we have the splitability and number of lanes now understood by
>the core - can the code also start doing more input checking?

Yep, that should certainly be done so some of the checks can move from
the drivers. Do you want to have this done as a part of this patchset or
a separate one?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 8/8] selftests: net: Add port split test
  2020-06-02 11:31 ` [RFC PATCH net-next 8/8] selftests: net: Add port split test Danielle Ratson
@ 2020-06-03 18:12   ` Florian Fainelli
  2020-06-04  3:16     ` Jakub Kicinski
  0 siblings, 1 reply; 17+ messages in thread
From: Florian Fainelli @ 2020-06-03 18:12 UTC (permalink / raw)
  To: Danielle Ratson, netdev
  Cc: davem, michael.chan, kuba, jeffrey.t.kirsher, saeedm, leon, jiri,
	idosch, snelson, drivers, andrew, vivien.didelot, mlxsw,
	Petr Machata



On 6/2/2020 4:31 AM, Danielle Ratson wrote:
> Test port split configuration using previously added number of port lanes
> attribute.
> 
> Check that all the splittable ports are successfully split to their maximum
> number of lanes and below, and that those which are not splittable fail to
> be split.
> 
> Test output example:
> 
> TEST: swp4 is unsplittable                                         [ OK ]
> TEST: split port swp53 into 4                                      [ OK ]
> TEST: Unsplit port pci/0000:03:00.0/25                             [ OK ]
> TEST: split port swp53 into 2                                      [ OK ]
> TEST: Unsplit port pci/0000:03:00.0/25                             [ OK ]
> 
> Signed-off-by: Danielle Ratson <danieller@mellanox.com>
> Reviewed-by: Petr Machata <petrm@mellanox.com>
> ---
>  tools/testing/selftests/net/Makefile          |   1 +
>  .../selftests/net/devlink_port_split.py       | 259 ++++++++++++++++++

Any reason why this is written in python versus shell?
-- 
Florian

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 0/8] Expose devlink port attributes
  2020-06-03 10:45   ` Jiri Pirko
@ 2020-06-04  2:48     ` Jakub Kicinski
  0 siblings, 0 replies; 17+ messages in thread
From: Jakub Kicinski @ 2020-06-04  2:48 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Danielle Ratson, netdev, davem, michael.chan, jeffrey.t.kirsher,
	saeedm, leon, jiri, idosch, snelson, drivers, andrew,
	vivien.didelot, f.fainelli, mlxsw

On Wed, 3 Jun 2020 12:45:04 +0200 Jiri Pirko wrote:
> Tue, Jun 02, 2020 at 09:33:11PM CEST, kuba@kernel.org wrote:
> >On Tue,  2 Jun 2020 14:31:11 +0300 Danielle Ratson wrote:  
> >> Currently, user has no way of knowing if a port can be split and into
> >> how many ports.
> >> 
> >> Among other things, it is currently impossible to write generic tests
> >> for port split.
> >> 
> >> In order to be able to expose the information regarding the split
> >> capability to user space, set the required attributes and pass them to
> >> netlink.
> >> 
> >> Patch 1: Move set attribute from devlink_port_attrs to devlink_port.
> >> Patch 2: Move switch_port attribute from devlink_port_attrs to devlink_port
> >> Patch 3: Replace devlink_port_attrs_set parameters with a struct.
> >> Patch 4: Set and initialize lanes attribute in the driver.
> >> Patch 5: Add lanes attribute to devlink port and pass to netlink.
> >> Patch 6: Set and initialize splittable attribute in the driver.
> >> Patch 7: Add splittable attribute to devlink port and pass them to netlink.
> >> Patch 8: Add a split port test.  
> >
> >Since we have the splitability and number of lanes now understood by
> >the core - can the code also start doing more input checking?  
> 
> Yep, that should certainly be done so some of the checks can move from
> the drivers. Do you want to have this done as a part of this patchset or
> a separate one?

May be a little quicker to review if everything was done in one series,
but no strong feelings.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 8/8] selftests: net: Add port split test
  2020-06-03 18:12   ` Florian Fainelli
@ 2020-06-04  3:16     ` Jakub Kicinski
  2020-06-04  4:01       ` Florian Fainelli
  0 siblings, 1 reply; 17+ messages in thread
From: Jakub Kicinski @ 2020-06-04  3:16 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Danielle Ratson, netdev, davem, michael.chan, jeffrey.t.kirsher,
	saeedm, leon, jiri, idosch, snelson, drivers, andrew,
	vivien.didelot, mlxsw, Petr Machata

On Wed, 3 Jun 2020 11:12:51 -0700 Florian Fainelli wrote:
> Any reason why this is written in python versus shell?

Perhaps personal preference of the author :) 

I'd be curious to hear the disadvantages, is python too big for
embedded targets?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 8/8] selftests: net: Add port split test
  2020-06-04  3:16     ` Jakub Kicinski
@ 2020-06-04  4:01       ` Florian Fainelli
  2020-06-04  9:44         ` Petr Machata
  0 siblings, 1 reply; 17+ messages in thread
From: Florian Fainelli @ 2020-06-04  4:01 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Danielle Ratson, netdev, davem, michael.chan, jeffrey.t.kirsher,
	saeedm, leon, jiri, idosch, snelson, drivers, andrew,
	vivien.didelot, mlxsw, Petr Machata



On 6/3/2020 8:16 PM, Jakub Kicinski wrote:
> On Wed, 3 Jun 2020 11:12:51 -0700 Florian Fainelli wrote:
>> Any reason why this is written in python versus shell?
> 
> Perhaps personal preference of the author :) 
> 
> I'd be curious to hear the disadvantages, is python too big for
> embedded targets?

The uncompressed root filesystem (buildroot based) we use is 37MB
without it and becomes 55MB with python3. Compressed, we are looking at
a 16MB vs 22MB kernel+initramfs, this is a sizable increase, but still
within reason.

NFS mounting when testing network is not such a great idea unless you
have a dedicated port that you can reserve which you sometimes do not
have, that makes extending your program base a bit harder.

In general there appears to be no direction from kernel maintainers
about what scripting language is acceptable for writing selftests. My
concern over time is that if we all let our preferences pick a scripting
language, we could make it harder for people to actually run these tests
when running non mainstream systems and we could start requiring more
and more interpreters or runtime environments over time.

If there is no strong technical reason for using python, which at first
glance there does not appear to be, could we consider shell?
-- 
Florian

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH net-next 8/8] selftests: net: Add port split test
  2020-06-04  4:01       ` Florian Fainelli
@ 2020-06-04  9:44         ` Petr Machata
  0 siblings, 0 replies; 17+ messages in thread
From: Petr Machata @ 2020-06-04  9:44 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Jakub Kicinski, Danielle Ratson, netdev, davem, michael.chan,
	jeffrey.t.kirsher, saeedm, leon, jiri, idosch, snelson, drivers,
	andrew, vivien.didelot, mlxsw


Florian Fainelli <f.fainelli@gmail.com> writes:

> In general there appears to be no direction from kernel maintainers
> about what scripting language is acceptable for writing selftests. My
> concern over time is that if we all let our preferences pick a scripting
> language, we could make it harder for people to actually run these tests
> when running non mainstream systems and we could start requiring more
> and more interpreters or runtime environments over time.

You make it sound as if we pushed like Ruby or SBCL or S-Lang, or some
craziness like that. Python is a conservative choice in the Linux
kernel. Not as conservative as Bash or C, but still conservative, Python
is used quite a bit, even for selftests (TDC!).

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-06-04  9:44 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-02 11:31 [RFC PATCH net-next 0/8] Expose devlink port attributes Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 1/8] devlink: Move set attribute of devlink_port_attrs to devlink_port Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 2/8] devlink: Move switch_port " Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 3/8] devlink: Replace devlink_port_attrs_set parameters with a struct Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 4/8] mlxsw: Set number of port lanes attribute in driver Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 5/8] devlink: Add a new devlink port lanes attribute and pass to netlink Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 6/8] mlxsw: Set port split ability attribute in driver Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 7/8] devlink: Add a new devlink port split ability attribute and pass to netlink Danielle Ratson
2020-06-02 11:31 ` [RFC PATCH net-next 8/8] selftests: net: Add port split test Danielle Ratson
2020-06-03 18:12   ` Florian Fainelli
2020-06-04  3:16     ` Jakub Kicinski
2020-06-04  4:01       ` Florian Fainelli
2020-06-04  9:44         ` Petr Machata
2020-06-02 16:21 ` [RFC PATCH net-next 0/8] Expose devlink port attributes Jakub Kicinski
2020-06-02 19:33 ` Jakub Kicinski
2020-06-03 10:45   ` Jiri Pirko
2020-06-04  2:48     ` Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.