[PATCH net-next] net/mlx5: SD, prefer sd_group_size from vport context

Tariq Toukan <[email protected]>
Newsgroups org.kernel.vger.linux-rdma,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
From: Shay Drory <[email protected]>

Newer FW reports the SD group size directly in the NIC vport context
via the sd_group_size field, gated by the sd_group_size capability.
Switch sd_init() to source the group size from there and fall back to
the MPIR-based host_buses query only when the cap is absent.
sd_group_size might return 1 in some FW configuration. Add explicit
check to disable SD creation in this case.

While here, rename host_buses to group_size throughout sd.c to follow
the new name on capable FW.

issue: 4680618
Signed-off-by: Shay Drory <[email protected]>
Reviewed-by: Moshe Shemesh <[email protected]>
Signed-off-by: Tariq Toukan <[email protected]>
---
 .../net/ethernet/mellanox/mlx5/core/lib/sd.c  | 75 ++++++++++---------
 .../net/ethernet/mellanox/mlx5/core/lib/sd.h  |  1 +
 .../net/ethernet/mellanox/mlx5/core/vport.c   |  6 +-
 include/linux/mlx5/vport.h                    |  3 +-
 4 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index ee2fdefa1945..4cdc50cd6f03 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -19,7 +19,7 @@
 
 struct mlx5_sd {
 	u32 group_id;
-	u8 host_buses;
+	u8 group_size;
 	struct mlx5_devcom_comp_dev *devcom;
 	struct dentry *dfs;
 	u8 state;
@@ -46,14 +46,14 @@ enum mlx5_sd_state {
 	MLX5_SD_STATE_UP,
 };
 
-static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
+static int mlx5_sd_get_group_size(struct mlx5_core_dev *dev)
 {
 	struct mlx5_sd *sd = mlx5_get_sd(dev);
 
 	if (!sd)
 		return 1;
 
-	return sd->host_buses;
+	return sd->group_size;
 }
 
 struct mlx5_core_dev *mlx5_sd_get_primary(struct mlx5_core_dev *dev)
@@ -107,7 +107,7 @@ int mlx5_sd_pf_num_get(struct mlx5_core_dev *dev)
 		if (pos == dev)
 			break;
 
-	return pf_num * sd->host_buses + i;
+	return pf_num * sd->group_size + i;
 }
 
 struct mlx5_core_dev *
@@ -118,7 +118,7 @@ mlx5_sd_primary_get_peer(struct mlx5_core_dev *primary, int idx)
 	if (idx == 0)
 		return primary;
 
-	if (idx >= mlx5_sd_get_host_buses(primary))
+	if (idx >= mlx5_sd_get_group_size(primary))
 		return NULL;
 
 	sd = mlx5_get_sd(primary);
@@ -130,7 +130,7 @@ int mlx5_sd_ch_ix_get_dev_ix(struct mlx5_core_dev *dev, int ch_ix)
 	if (is_mdev_switchdev_mode(dev))
 		return 0;
 
-	return ch_ix % mlx5_sd_get_host_buses(dev);
+	return ch_ix % mlx5_sd_get_group_size(dev);
 }
 
 int mlx5_sd_ch_ix_get_vec_ix(struct mlx5_core_dev *dev, int ch_ix)
@@ -138,7 +138,7 @@ int mlx5_sd_ch_ix_get_vec_ix(struct mlx5_core_dev *dev, int ch_ix)
 	if (is_mdev_switchdev_mode(dev))
 		return ch_ix;
 
-	return ch_ix / mlx5_sd_get_host_buses(dev);
+	return ch_ix / mlx5_sd_get_group_size(dev);
 }
 
 struct mlx5_core_dev *mlx5_sd_ch_ix_get_dev(struct mlx5_core_dev *primary, int ch_ix)
@@ -164,7 +164,7 @@ static bool ft_create_alias_supported(struct mlx5_core_dev *dev)
 }
 
 static int mlx5_query_sd(struct mlx5_core_dev *dev, bool *sdm,
-			 u8 *host_buses)
+			 u8 *group_size)
 {
 	u32 out[MLX5_ST_SZ_DW(mpir_reg)];
 	int err;
@@ -174,7 +174,7 @@ static int mlx5_query_sd(struct mlx5_core_dev *dev, bool *sdm,
 		return err;
 
 	*sdm = MLX5_GET(mpir_reg, out, sdm);
-	*host_buses = MLX5_GET(mpir_reg, out, host_buses);
+	*group_size = MLX5_GET(mpir_reg, out, host_buses);
 
 	return 0;
 }
@@ -184,10 +184,10 @@ static u32 mlx5_sd_group_id(struct mlx5_core_dev *dev, u8 sd_group)
 	return (u32)((MLX5_CAP_GEN(dev, native_port_num) << 8) | sd_group);
 }
 
-static bool mlx5_sd_caps_supported(struct mlx5_core_dev *dev, u8 host_buses)
+static bool mlx5_sd_caps_supported(struct mlx5_core_dev *dev, u8 group_size)
 {
 	/* Honor the SW implementation limit */
-	if (host_buses > MLX5_SD_MAX_GROUP_SZ)
+	if (group_size > MLX5_SD_MAX_GROUP_SZ)
 		return false;
 
 	/* Disconnect secondaries from the network */
@@ -200,7 +200,7 @@ static bool mlx5_sd_caps_supported(struct mlx5_core_dev *dev, u8 host_buses)
 	/* RX steering from primary to secondaries */
 	if (!MLX5_CAP_GEN(dev, cross_vhca_rqt))
 		return false;
-	if (host_buses > MLX5_CAP_GEN_2(dev, max_rqt_vhca_id))
+	if (group_size > MLX5_CAP_GEN_2(dev, max_rqt_vhca_id))
 		return false;
 
 	/* TX steering from secondaries to primary */
@@ -214,7 +214,7 @@ static bool mlx5_sd_caps_supported(struct mlx5_core_dev *dev, u8 host_buses)
 
 bool mlx5_sd_is_supported(struct mlx5_core_dev *dev)
 {
-	u8 host_buses, sd_group;
+	u8 group_size = U8_MAX, sd_group;
 	bool sdm;
 	int err;
 
@@ -222,23 +222,25 @@ bool mlx5_sd_is_supported(struct mlx5_core_dev *dev)
 	if (!mlx5_core_is_pf(dev))
 		return false;
 
-	err = mlx5_query_nic_vport_sd_group(dev, &sd_group);
-	if (err || !sd_group)
+	err = mlx5_query_nic_vport_sd_group(dev, &sd_group, &group_size);
+	if (err || !sd_group || group_size < MLX5_SD_MIN_GROUP_SZ)
 		return false;
 
-	if (!MLX5_CAP_MCAM_REG(dev, mpir))
-		return false;
+	if (group_size == U8_MAX) {
+		if (!MLX5_CAP_MCAM_REG(dev, mpir))
+			return false;
 
-	err = mlx5_query_sd(dev, &sdm, &host_buses);
-	if (err || !sdm)
-		return false;
+		err = mlx5_query_sd(dev, &sdm, &group_size);
+		if (err || !sdm)
+			return false;
+	}
 
-	return mlx5_sd_caps_supported(dev, host_buses);
+	return mlx5_sd_caps_supported(dev, group_size);
 }
 
 static int sd_init(struct mlx5_core_dev *dev)
 {
-	u8 host_buses, sd_group;
+	u8 group_size = U8_MAX, sd_group;
 	struct mlx5_sd *sd;
 	u32 group_id;
 	bool sdm;
@@ -248,26 +250,27 @@ static int sd_init(struct mlx5_core_dev *dev)
 	if (!mlx5_core_is_pf(dev))
 		return 0;
 
-	err = mlx5_query_nic_vport_sd_group(dev, &sd_group);
+	err = mlx5_query_nic_vport_sd_group(dev, &sd_group, &group_size);
 	if (err)
 		return err;
 
-	if (!sd_group)
+	if (!sd_group || group_size < MLX5_SD_MIN_GROUP_SZ)
 		return 0;
 
-	if (!MLX5_CAP_MCAM_REG(dev, mpir))
-		return 0;
+	if (group_size == U8_MAX) {
+		if (!MLX5_CAP_MCAM_REG(dev, mpir))
+			return 0;
 
-	err = mlx5_query_sd(dev, &sdm, &host_buses);
-	if (err)
-		return err;
-
-	if (!sdm)
-		return 0;
+		err = mlx5_query_sd(dev, &sdm, &group_size);
+		if (err)
+			return err;
 
+		if (!sdm)
+			return 0;
+	}
 	group_id = mlx5_sd_group_id(dev, sd_group);
 
-	if (!mlx5_sd_caps_supported(dev, host_buses)) {
+	if (!mlx5_sd_caps_supported(dev, group_size)) {
 		sd_warn(dev, "can't support requested netdev combining for group id 0x%x, skipping\n",
 			group_id);
 		return 0;
@@ -277,7 +280,7 @@ static int sd_init(struct mlx5_core_dev *dev)
 	if (!sd)
 		return -ENOMEM;
 
-	sd->host_buses = host_buses;
+	sd->group_size = group_size;
 	sd->group_id = group_id;
 
 	mlx5_set_sd(dev, sd);
@@ -540,7 +543,7 @@ static int sd_register(struct mlx5_core_dev *dev)
 	sd->devcom = devcom;
 
 	mlx5_devcom_comp_lock(devcom);
-	if (mlx5_devcom_comp_get_size(devcom) != sd->host_buses ||
+	if (mlx5_devcom_comp_get_size(devcom) != sd->group_size ||
 	    mlx5_devcom_comp_is_ready(devcom))
 		goto out;
 
@@ -576,7 +579,7 @@ static int sd_register(struct mlx5_core_dev *dev)
 				      DEVCOM_CANT_FAIL, primary);
 
 	primary_sd = mlx5_get_sd(primary);
-	if (primary_sd->next_secondary_idx + 1 == sd->host_buses)
+	if (primary_sd->next_secondary_idx + 1 == sd->group_size)
 		mlx5_devcom_comp_set_ready(devcom, true);
 out:
 	mlx5_devcom_comp_unlock(devcom);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
index cb88bf34079a..bc8dbc299070 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
@@ -6,6 +6,7 @@
 
 #include <linux/types.h>
 
+#define MLX5_SD_MIN_GROUP_SZ 2
 #define MLX5_SD_MAX_GROUP_SZ 2
 
 struct mlx5_sd;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
index 3676e26ac6b0..3d86510af615 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -550,7 +550,8 @@ int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
 }
 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid);
 
-int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group)
+int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group,
+				  u8 *sd_group_size)
 {
 	int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 	u32 *out;
@@ -566,6 +567,9 @@ int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group)
 
 	*sd_group = MLX5_GET(query_nic_vport_context_out, out,
 			     nic_vport_context.sd_group);
+	if (MLX5_CAP_GEN(mdev, sd_group_size))
+		*sd_group_size = MLX5_GET(query_nic_vport_context_out, out,
+					  nic_vport_context.sd_group_size);
 out:
 	kvfree(out);
 	return err;
diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h
index ee34d3ed335f..577168a4ca0c 100644
--- a/include/linux/mlx5/vport.h
+++ b/include/linux/mlx5/vport.h
@@ -78,7 +78,8 @@ int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu);
 int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu);
 int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
 					   u64 *system_image_guid);
-int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group);
+int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group,
+				  u8 *sd_group_size);
 int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev,
 				   u16 vport, bool other_vport, u64 *node_guid);
 int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev,

base-commit: 001b5d347d8ba39b2dccaefcc57967b18caec8fe
-- 
2.44.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.