[PATCH net-next 11/12] net/mlx5: Add FDB peer miss rules for satellite PFs

From: Tariq Toukan

Date: Thu May 21 2026 - 07:22:05 EST


From: Moshe Shemesh <moshe@xxxxxxxxxx>

Add satellite PF (SPF) vports to the FDB peer miss rules flow.
Introduce mlx5_esw_for_each_spf_vport() macro to iterate SPF vports.

Signed-off-by: Moshe Shemesh <moshe@xxxxxxxxxx>
Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
---
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 10 +++++++++
.../mellanox/mlx5/core/eswitch_offloads.c | 22 ++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 1d8e2486d518..c8d6c94a4475 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -790,6 +790,16 @@ void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw);
MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base) +\
(last) - 1)

+/* SPF vport numbers are not contiguous, iterate via the spfs array
+ * and look up each vport in the xarray.
+ */
+#define mlx5_esw_for_each_spf_vport(esw, index, vport) \
+ for ((index) = 0; \
+ (index) < (esw)->esw_funcs.num_spfs && \
+ ((vport) = xa_load(&(esw)->vports, \
+ (esw)->esw_funcs.spfs[(index)].vport_num)); \
+ (index)++)
+
#define mlx5_esw_for_each_rep(esw, i, rep) \
xa_for_each(&((esw)->offloads.vport_reps), i, rep)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 59446c444570..355d27934fb4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -1231,6 +1231,19 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw,
flows[peer_vport->index] = flow;
}

+ mlx5_esw_for_each_spf_vport(peer_esw, i, peer_vport) {
+ esw_set_peer_miss_rule_source_port(esw, peer_esw, spec,
+ peer_vport->vport);
+
+ flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
+ spec, &flow_act, &dest, 1);
+ if (IS_ERR(flow)) {
+ err = PTR_ERR(flow);
+ goto add_ecpf_flow_err;
+ }
+ flows[peer_vport->index] = flow;
+ }
+
if (mlx5_ecpf_vport_exists(peer_dev)) {
peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF);
MLX5_SET(fte_match_set_misc, misc, source_port, MLX5_VPORT_ECPF);
@@ -1299,7 +1312,11 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw,
mlx5_del_flow_rules(flows[peer_vport->index]);
}
add_ecpf_flow_err:
-
+ mlx5_esw_for_each_spf_vport(peer_esw, i, peer_vport) {
+ if (!flows[peer_vport->index])
+ continue;
+ mlx5_del_flow_rules(flows[peer_vport->index]);
+ }
if (mlx5_core_is_ecpf_esw_manager(peer_dev) &&
mlx5_esw_host_functions_enabled(peer_dev)) {
peer_vport = mlx5_eswitch_get_vport(peer_esw,
@@ -1343,6 +1360,9 @@ static void esw_del_fdb_peer_miss_rules(struct mlx5_eswitch *esw,
mlx5_del_flow_rules(flows[peer_vport->index]);
}

+ mlx5_esw_for_each_spf_vport(peer_esw, i, peer_vport)
+ mlx5_del_flow_rules(flows[peer_vport->index]);
+
if (mlx5_core_is_ecpf_esw_manager(peer_dev) &&
mlx5_esw_host_functions_enabled(peer_dev)) {
peer_vport = mlx5_eswitch_get_vport(peer_esw,
--
2.44.0