Commit 8fb49c01 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents faea30ed f3348a82
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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");
+4 −2
Original line number Diff line number Diff line
@@ -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);
+9 −10
Original line number Diff line number Diff line
@@ -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);
}
+7 −9
Original line number Diff line number Diff line
@@ -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);
+14 −4
Original line number Diff line number Diff line
@@ -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;
Loading