All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tariq Toukan <tariqt@nvidia.com>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, <netdev@vger.kernel.org>,
	Paolo Abeni <pabeni@redhat.com>
Cc: Gal Pressman <gal@nvidia.com>, Leon Romanovsky <leon@kernel.org>,
	<linux-kernel@vger.kernel.org>, <linux-rdma@vger.kernel.org>,
	Mark Bloch <mbloch@nvidia.com>, Moshe Shemesh <moshe@nvidia.com>,
	Saeed Mahameed <saeedm@nvidia.com>, Shay Drory <shayd@nvidia.com>,
	Simon Horman <horms@kernel.org>, Tariq Toukan <tariqt@nvidia.com>
Subject: [PATCH net-next] net/mlx5: SD, prefer sd_group_size from vport context
Date: Mon, 10 Aug 2026 12:30:37 +0300	[thread overview]
Message-ID: <20260810093037.3138197-1-tariqt@nvidia.com> (raw)

From: Shay Drory <shayd@nvidia.com>

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 <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../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


             reply	other threads:[~2026-08-10  9:31 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10  9:30 Tariq Toukan [this message]
2026-08-11 12:44 ` [PATCH net-next] net/mlx5: SD, prefer sd_group_size from vport context Simon Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260810093037.3138197-1-tariqt@nvidia.com \
    --to=tariqt@nvidia.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gal@nvidia.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=mbloch@nvidia.com \
    --cc=moshe@nvidia.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=saeedm@nvidia.com \
    --cc=shayd@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.