[PATCH net-next 06/15] net/mlx5: SD, expend vport metadata for SD secondary devices

From: Tariq Toukan

Date: Thu Jun 04 2026 - 07:55:03 EST


From: Shay Drory <shayd@xxxxxxxxxx>

In Socket Direct configurations the primary and secondary PFs share the
same native_port_num. The eswitch vport metadata encodes pf_num in its
upper bits to distinguish vports across PFs. Without SD-awareness, both
PFs generate identical metadata, causing FDB rules to steer traffic to
the wrong representor.

Add mlx5_sd_pf_num_get() which remaps the pf_num for SD devices.
Use it so each PF in an SD group produces unique vport metadata.

Signed-off-by: Shay Drory <shayd@xxxxxxxxxx>
Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
---
.../mellanox/mlx5/core/eswitch_offloads.c | 6 +++---
.../net/ethernet/mellanox/mlx5/core/lib/sd.c | 21 +++++++++++++++++++
.../net/ethernet/mellanox/mlx5/core/lib/sd.h | 1 +
3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 12805e80ce57..366531d8ef02 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -3472,12 +3472,12 @@ u32 mlx5_esw_match_metadata_alloc(struct mlx5_eswitch *esw)
u32 vport_end_ida = (1 << ESW_VPORT_BITS) - 1;
/* Reserve 0xf for internal port offload */
u32 max_pf_num = (1 << ESW_PFNUM_BITS) - 2;
- u32 pf_num;
+ int pf_num;
int id;

/* Only 4 bits of pf_num */
- pf_num = mlx5_get_dev_index(esw->dev);
- if (pf_num > max_pf_num)
+ pf_num = mlx5_sd_pf_num_get(esw->dev);
+ if (pf_num < 0 || pf_num > max_pf_num)
return 0;

/* Metadata is 4 bits of PFNUM and 12 bits of unique id */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index afad05a1e3fe..8b1f3a25d80d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -85,6 +85,27 @@ bool mlx5_sd_is_primary(struct mlx5_core_dev *dev)
return sd->primary;
}

+int mlx5_sd_pf_num_get(struct mlx5_core_dev *dev)
+{
+ struct mlx5_sd *sd = mlx5_get_sd(dev);
+ int pf_num = mlx5_get_dev_index(dev);
+ struct mlx5_core_dev *pos;
+ int i;
+
+ if (!sd)
+ return pf_num;
+
+ mlx5_devcom_comp_assert_locked(sd->devcom);
+ if (!mlx5_devcom_comp_is_ready(sd->devcom))
+ return -ENODEV;
+
+ mlx5_sd_for_each_dev(i, mlx5_sd_get_primary(dev), pos)
+ if (pos == dev)
+ break;
+
+ return pf_num * sd->host_buses + i;
+}
+
struct mlx5_core_dev *
mlx5_sd_primary_get_peer(struct mlx5_core_dev *primary, int idx)
{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
index 011702ff6f02..7a41adbcee71 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
@@ -12,6 +12,7 @@ struct mlx5_sd;

struct mlx5_core_dev *mlx5_sd_get_primary(struct mlx5_core_dev *dev);
bool mlx5_sd_is_primary(struct mlx5_core_dev *dev);
+int mlx5_sd_pf_num_get(struct mlx5_core_dev *dev);
struct mlx5_core_dev *mlx5_sd_primary_get_peer(struct mlx5_core_dev *primary, int idx);
int mlx5_sd_ch_ix_get_dev_ix(struct mlx5_core_dev *dev, int ch_ix);
int mlx5_sd_ch_ix_get_vec_ix(struct mlx5_core_dev *dev, int ch_ix);
--
2.44.0