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@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260612113904.537595-7-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
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 */
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)
{
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);