All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tariq Toukan <tariqt@nvidia.com>
To: Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>
Cc: Saeed Mahameed <saeedm@nvidia.com>,
	Leon Romanovsky <leon@kernel.org>,
	Tariq Toukan <tariqt@nvidia.com>, Mark Bloch <mbloch@nvidia.com>,
	"Moshe Shemesh" <moshe@nvidia.com>,
	Akiva Goldberger <agoldberger@nvidia.com>,
	<netdev@vger.kernel.org>, <linux-rdma@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, Gal Pressman <gal@nvidia.com>,
	Dragos Tatulea <dtatulea@nvidia.com>
Subject: [PATCH net-next 2/8] net/mlx5: Use v1 response layout for query_esw_functions
Date: Sun, 10 May 2026 08:34:42 +0300	[thread overview]
Message-ID: <20260510053448.326823-3-tariqt@nvidia.com> (raw)
In-Reply-To: <20260510053448.326823-1-tariqt@nvidia.com>

From: Moshe Shemesh <moshe@nvidia.com>

Use the v1 response layout for the query_esw_functions command when
supported by the device. When query_host_net_function_v1 capability is
set, use MLX5_QUERY_ESW_FUNC_OP_MOD_LAYOUT_V1 to retrieve parameters
for multiple network functions, allocating the output buffer according
to query_host_net_function_num_max. Validate that firmware does not
return more entries than the allocated buffer.

This change does not introduce new functionality, but enables the
existing mlx5_esw_query_functions() callers to retrieve host PF
information with the new layout as well. The mlx5_esw_get_host_pf_info()
helper abstracts parsing the command output in both legacy and new
formats, so callers do not need to handle the different layouts.

Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../net/ethernet/mellanox/mlx5/core/eswitch.c | 88 +++++++++++++++++--
 .../net/ethernet/mellanox/mlx5/core/eswitch.h |  5 +-
 .../mellanox/mlx5/core/eswitch_offloads.c     |  6 +-
 .../net/ethernet/mellanox/mlx5/core/sriov.c   |  2 +-
 4 files changed, 89 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 861e79ddb489..8b62dde7eb70 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1063,11 +1063,28 @@ static int eswitch_vport_event(struct notifier_block *nb,
  */
 const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
 {
-	int outlen = MLX5_ST_SZ_BYTES(query_esw_functions_out);
+	bool net_func_v1 = MLX5_CAP_GEN(dev, query_host_net_function_v1);
 	u32 in[MLX5_ST_SZ_DW(query_esw_functions_in)] = {};
+	int alloc_entries;
+	int outlen;
 	u32 *out;
 	int err;
 
+	if (net_func_v1) {
+		alloc_entries = MLX5_CAP_GEN(dev,
+					     query_host_net_function_num_max);
+		alloc_entries = max(alloc_entries, 1);
+		MLX5_SET(query_esw_functions_in, in, op_mod,
+			 MLX5_QUERY_ESW_FUNC_OP_MOD_LAYOUT_V1);
+		outlen = MLX5_BYTE_OFF(query_esw_functions_out,
+				       net_function_params) +
+			 alloc_entries * MLX5_UN_SZ_BYTES(net_function_params);
+		outlen = max_t(int, outlen,
+			       MLX5_ST_SZ_BYTES(query_esw_functions_out));
+	} else {
+		outlen = MLX5_ST_SZ_BYTES(query_esw_functions_out);
+	}
+
 	out = kvzalloc(outlen, GFP_KERNEL);
 	if (!out)
 		return ERR_PTR(-ENOMEM);
@@ -1076,9 +1093,25 @@ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
 		 MLX5_CMD_OP_QUERY_ESW_FUNCTIONS);
 
 	err = mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
-	if (!err)
-		return out;
+	if (err)
+		goto free;
+
+	if (net_func_v1) {
+		int num_entries;
+
+		num_entries = MLX5_GET(query_esw_functions_out, out,
+				       net_function_num);
+		if (num_entries > alloc_entries) {
+			mlx5_core_warn(dev, "Got %d entries, max expected %d\n",
+				       num_entries, alloc_entries);
+			err = -EINVAL;
+			goto free;
+		}
+	}
+
+	return out;
 
+free:
 	kvfree(out);
 	return ERR_PTR(err);
 }
@@ -1100,12 +1133,55 @@ mlx5_esw_host_pf_from_host_params(const void *entry)
 	};
 }
 
-struct mlx5_esw_pf_info mlx5_esw_get_host_pf_info(const u32 *out)
+static struct mlx5_esw_pf_info
+mlx5_esw_host_pf_from_net_func_params(const u8 *entry, int num_entries)
+{
+	int i;
+
+	for (i = 0; i < num_entries; i++) {
+		int pf_type, state;
+
+		pf_type = MLX5_GET(network_function_params, entry, pci_pf_type);
+		if (pf_type != MLX5_PCI_PF_TYPE_EXTERNAL_HOST_PF) {
+			entry += MLX5_UN_SZ_BYTES(net_function_params);
+			continue;
+		}
+
+		state = MLX5_GET(network_function_params, entry, vhca_state);
+
+		return (struct mlx5_esw_pf_info) {
+			.pf_disabled = state != MLX5_VHCA_STATE_IN_USE,
+			.num_of_vfs = MLX5_GET(network_function_params,
+					       entry, pci_num_vfs),
+			.total_vfs = MLX5_GET(network_function_params,
+					      entry, pci_total_vfs),
+			.host_number = MLX5_GET(network_function_params,
+						entry, host_number),
+		};
+	}
+
+	/* No external host PF entry found */
+	return (struct mlx5_esw_pf_info) {
+		.pf_not_exist = true,
+		.pf_disabled = true,
+	};
+}
+
+struct mlx5_esw_pf_info
+mlx5_esw_get_host_pf_info(struct mlx5_core_dev *dev, const u32 *out)
 {
 	const void *entry;
 
 	entry = MLX5_ADDR_OF(query_esw_functions_out, out, net_function_params);
 
+	if (MLX5_CAP_GEN(dev, query_host_net_function_v1)) {
+		int num_entries = MLX5_GET(query_esw_functions_out, out,
+					   net_function_num);
+
+		return mlx5_esw_host_pf_from_net_func_params(entry,
+							     num_entries);
+	}
+
 	return mlx5_esw_host_pf_from_host_params(entry);
 }
 
@@ -1121,7 +1197,7 @@ static int mlx5_esw_host_functions_enabled_query(struct mlx5_eswitch *esw)
 	if (IS_ERR(query_host_out))
 		return PTR_ERR(query_host_out);
 
-	host_pf_info = mlx5_esw_get_host_pf_info(query_host_out);
+	host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, query_host_out);
 	esw->esw_funcs.host_funcs_disabled = host_pf_info.pf_not_exist;
 
 	kvfree(query_host_out);
@@ -1561,7 +1637,7 @@ mlx5_eswitch_update_num_of_vfs(struct mlx5_eswitch *esw, int num_vfs)
 	if (IS_ERR(out))
 		return;
 
-	host_pf_info = mlx5_esw_get_host_pf_info(out);
+	host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, out);
 	esw->esw_funcs.num_vfs = host_pf_info.num_of_vfs;
 	if (mlx5_core_ec_sriov_enabled(esw->dev))
 		esw->esw_funcs.num_ec_vfs = num_vfs;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index cfaae59a6e7c..a5f832ed2251 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -657,7 +657,8 @@ bool mlx5_esw_multipath_prereq(struct mlx5_core_dev *dev0,
 			       struct mlx5_core_dev *dev1);
 
 const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev);
-struct mlx5_esw_pf_info mlx5_esw_get_host_pf_info(const u32 *out);
+struct mlx5_esw_pf_info mlx5_esw_get_host_pf_info(struct mlx5_core_dev *dev,
+						  const u32 *out);
 int mlx5_esw_host_pf_enable_hca(struct mlx5_core_dev *dev);
 int mlx5_esw_host_pf_disable_hca(struct mlx5_core_dev *dev);
 
@@ -986,7 +987,7 @@ static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
 }
 
 static inline struct mlx5_esw_pf_info
-mlx5_esw_get_host_pf_info(const u32 *out)
+mlx5_esw_get_host_pf_info(struct mlx5_core_dev *dev, const u32 *out)
 {
 	return (struct mlx5_esw_pf_info) {};
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 217c2fe6b690..acbc37b05308 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -3716,7 +3716,7 @@ static void esw_vfs_changed_event_handler(struct mlx5_eswitch *esw)
 	if (IS_ERR(out))
 		return;
 
-	host_pf_info = mlx5_esw_get_host_pf_info(out);
+	host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, out);
 	new_num_vfs = host_pf_info.num_of_vfs;
 
 	if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_info.pf_disabled)
@@ -3832,7 +3832,7 @@ static int mlx5_esw_host_number_init(struct mlx5_eswitch *esw)
 		return PTR_ERR(query_host_out);
 
 	/* Mark non local controller with non zero controller number. */
-	host_pf_info = mlx5_esw_get_host_pf_info(query_host_out);
+	host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, query_host_out);
 	esw->offloads.host_number = host_pf_info.host_number;
 	kvfree(query_host_out);
 	return 0;
@@ -4988,7 +4988,7 @@ int mlx5_devlink_pf_port_fn_state_get(struct devlink_port *port,
 	if (IS_ERR(query_out))
 		return PTR_ERR(query_out);
 
-	host_pf_info = mlx5_esw_get_host_pf_info(query_out);
+	host_pf_info = mlx5_esw_get_host_pf_info(vport->dev, query_out);
 
 	*opstate = host_pf_info.pf_disabled ?
 			DEVLINK_PORT_FN_OPSTATE_DETACHED :
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
index 79f76c456d72..0770b5d99c5d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
@@ -285,7 +285,7 @@ static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev)
 		 */
 		if (IS_ERR(out))
 			goto done;
-		host_pf_info = mlx5_esw_get_host_pf_info(out);
+		host_pf_info = mlx5_esw_get_host_pf_info(dev, out);
 		host_total_vfs = host_pf_info.total_vfs;
 		kvfree(out);
 		return host_total_vfs;
-- 
2.44.0


  parent reply	other threads:[~2026-05-10  5:35 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-10  5:34 [PATCH net-next 0/8] net/mlx5: Prepare eswitch infrastructure for satellite PF support Tariq Toukan
2026-05-10  5:34 ` [PATCH net-next 1/8] net/mlx5: Use helper to parse host PF info Tariq Toukan
2026-05-14 19:19   ` Simon Horman
2026-05-10  5:34 ` Tariq Toukan [this message]
2026-05-14 19:18   ` [PATCH net-next 2/8] net/mlx5: Use v1 response layout for query_esw_functions Simon Horman
2026-05-10  5:34 ` [PATCH net-next 3/8] net/mlx5: Use mlx5_eswitch_is_vf_vport() for IPsec VF checks Tariq Toukan
2026-05-10  5:34 ` [PATCH net-next 4/8] net/mlx5: Switch vport HCA cap helpers to kvzalloc Tariq Toukan
2026-05-10  5:34 ` [PATCH net-next 5/8] net/mlx5: Add mlx5_vport_set_other_func_general_cap macro Tariq Toukan
2026-05-10  5:34 ` [PATCH net-next 6/8] net/mlx5: Refactor mlx5_set_msix_vec_count() SET_HCA_CAP Tariq Toukan
2026-05-10  5:34 ` [PATCH net-next 7/8] net/mlx5: Use vport helper for IPsec eswitch set caps Tariq Toukan
2026-05-10  5:34 ` [PATCH net-next 8/8] net/mlx5: Generalize enable/disable HCA for any PF vport Tariq Toukan
2026-05-14  2:25 ` [PATCH net-next 0/8] net/mlx5: Prepare eswitch infrastructure for satellite PF support Jakub Kicinski
2026-05-14  7:56   ` Moshe Shemesh
2026-05-14  9:53     ` Paolo Abeni
2026-05-14  9:59       ` Paolo Abeni
2026-05-14 23:16     ` Jakub Kicinski

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=20260510053448.326823-3-tariqt@nvidia.com \
    --to=tariqt@nvidia.com \
    --cc=agoldberger@nvidia.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=dtatulea@nvidia.com \
    --cc=edumazet@google.com \
    --cc=gal@nvidia.com \
    --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 \
    /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.