mirror of https://lore.kernel.org/lkml/
 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: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10  9:30 Tariq Toukan [this message]
2026-08-11 12:44 ` Simon Horman
2026-08-12  6:03   ` Shay Drori
2026-08-14 19:27 ` Jakub Kicinski
2026-08-14 19:51 ` patchwork-bot+netdevbpf

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®