[PATCH net-next 06/12] net/mlx5: Expose PF number from query_esw_functions

From: Tariq Toukan

Date: Thu May 21 2026 - 07:20:02 EST


From: Moshe Shemesh <moshe@xxxxxxxxxx>

Extract pci_device_function from the query_esw_functions output for both
the host PF and satellite PFs, storing it alongside the existing
host_number field.

Add mlx5_esw_get_hpf_pf_num() helper that returns the host PF's actual
PCI device function when the new query format is supported, falling back
to PCI_FUNC(dev->pdev->devfn) for older firmware. Use it in devlink port
attribute setup so that host PF and VF devlink ports report the correct
PF number rather than the ECPF's own PCI function number.

Signed-off-by: Moshe Shemesh <moshe@xxxxxxxxxx>
Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
---
.../mellanox/mlx5/core/esw/devlink_port.c | 4 ++++
.../net/ethernet/mellanox/mlx5/core/eswitch.c | 22 ++++++++++++++++---
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 4 ++++
3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
index e723f05cd4d3..d5f0101aa966 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
@@ -37,6 +37,8 @@ static void mlx5_esw_offloads_pf_vf_devlink_port_attrs_set(struct mlx5_eswitch *
controller_num = mlx5_esw_get_hpf_host_number(dev) + 1;

if (vport_num == MLX5_VPORT_HOST_PF) {
+ if (external)
+ pfnum = mlx5_esw_get_hpf_pf_num(dev);
memcpy(dl_port->attrs.switch_id.id, ppid.id, ppid.id_len);
dl_port->attrs.switch_id.id_len = ppid.id_len;
devlink_port_attrs_pci_pf_set(dl_port, controller_num, pfnum, external);
@@ -49,6 +51,8 @@ static void mlx5_esw_offloads_pf_vf_devlink_port_attrs_set(struct mlx5_eswitch *
if (vport->adjacent) {
func_id = vport->adj_info.function_id;
pfnum = vport->adj_info.parent_pci_devfn;
+ } else if (external) {
+ pfnum = mlx5_esw_get_hpf_pf_num(dev);
}

devlink_port_attrs_pci_vf_set(dl_port, controller_num, pfnum,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 42cdb4309258..8e2ac759d1f3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1157,6 +1157,8 @@ mlx5_esw_host_pf_from_net_func_params(const u8 *entry, int num_entries)
entry, pci_total_vfs),
.host_number = MLX5_GET(network_function_params,
entry, host_number),
+ .pf_num = MLX5_GET(network_function_params, entry,
+ pci_device_function),
};
}

@@ -2103,7 +2105,6 @@ int mlx5_esw_spf_get_host_number(struct mlx5_core_dev *dev, int spf_idx,
return -EINVAL;

*host_number = esw->esw_funcs.spfs[spf_idx].host_number;
-
return 0;
}

@@ -2117,6 +2118,17 @@ u16 mlx5_esw_get_hpf_host_number(struct mlx5_core_dev *dev)
return esw->esw_funcs.hpf_host_number;
}

+u16 mlx5_esw_get_hpf_pf_num(struct mlx5_core_dev *dev)
+{
+ struct mlx5_eswitch *esw = dev->priv.eswitch;
+
+ if (mlx5_core_is_ecpf_esw_manager(dev) &&
+ MLX5_CAP_GEN(dev, query_host_net_function_v1))
+ return esw->esw_funcs.hpf_pf_num;
+
+ return PCI_FUNC(dev->pdev->devfn);
+}
+
bool mlx5_esw_has_spf_sfs(struct mlx5_core_dev *dev)
{
struct mlx5_eswitch *esw = dev->priv.eswitch;
@@ -2127,7 +2139,7 @@ bool mlx5_esw_has_spf_sfs(struct mlx5_core_dev *dev)
return esw->esw_funcs.has_spf_sfs;
}

-static int mlx5_esw_hpf_host_number_init(struct mlx5_eswitch *esw)
+static int mlx5_esw_hpf_info_init(struct mlx5_eswitch *esw)
{
struct mlx5_esw_pf_info host_pf_info;
const u32 *query_host_out;
@@ -2142,6 +2154,7 @@ static int mlx5_esw_hpf_host_number_init(struct mlx5_eswitch *esw)
/* Mark non local controller with non zero controller number. */
host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, query_host_out);
esw->esw_funcs.hpf_host_number = host_pf_info.host_number;
+ esw->esw_funcs.hpf_pf_num = host_pf_info.pf_num;
kvfree(query_host_out);
return 0;
}
@@ -2255,6 +2268,9 @@ static int mlx5_esw_spfs_init(struct mlx5_eswitch *esw)
esw_funcs->spfs[esw_funcs->num_spfs].vhca_id = vhca_id;
esw_funcs->spfs[esw_funcs->num_spfs].host_number =
MLX5_GET(network_function_params, entry, host_number);
+ esw_funcs->spfs[esw_funcs->num_spfs].pf_num =
+ MLX5_GET(network_function_params, entry,
+ pci_device_function);
esw_funcs->num_spfs++;

entry += MLX5_UN_SZ_BYTES(net_function_params);
@@ -2297,7 +2313,7 @@ static int mlx5_esw_vports_init(struct mlx5_eswitch *esw)

xa_init(&esw->vports);

- err = mlx5_esw_hpf_host_number_init(esw);
+ err = mlx5_esw_hpf_info_init(esw);
if (err)
goto err;

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 88041dd8a39d..03c7582d7b95 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -77,6 +77,7 @@ struct mlx5_esw_pf_info {
u16 num_of_vfs;
u16 total_vfs;
u16 host_number;
+ u16 pf_num;
};

#ifdef CONFIG_MLX5_ESWITCH
@@ -352,6 +353,7 @@ struct mlx5_esw_spf {
u16 vport_num;
u16 vhca_id;
u16 host_number;
+ u16 pf_num;
};

struct mlx5_esw_functions {
@@ -360,6 +362,7 @@ struct mlx5_esw_functions {
u16 num_vfs;
u16 num_ec_vfs;
u16 hpf_host_number;
+ u16 hpf_pf_num;
bool has_spf_sfs;
struct mlx5_esw_spf *spfs;
int num_spfs;
@@ -887,6 +890,7 @@ int mlx5_esw_get_num_spfs(struct mlx5_core_dev *dev);
int mlx5_esw_spf_get_host_number(struct mlx5_core_dev *dev, int spf_idx,
u16 *host_number);
u16 mlx5_esw_get_hpf_host_number(struct mlx5_core_dev *dev);
+u16 mlx5_esw_get_hpf_pf_num(struct mlx5_core_dev *dev);
bool mlx5_esw_has_spf_sfs(struct mlx5_core_dev *dev);

int mlx5_esw_vport_vhca_id_map(struct mlx5_eswitch *esw,
--
2.44.0