|
38 | 38 | #include "lib/devcom.h" |
39 | 39 | #include "mlx5_core.h" |
40 | 40 | #include "eswitch.h" |
| 41 | +#include "esw/acl/ofld.h" |
41 | 42 | #include "lag.h" |
42 | 43 | #include "mp.h" |
43 | 44 |
|
@@ -210,6 +211,62 @@ static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker, |
210 | 211 | *port1 = MLX5_LAG_EGRESS_PORT_2; |
211 | 212 | } |
212 | 213 |
|
| 214 | +static bool mlx5_lag_has_drop_rule(struct mlx5_lag *ldev) |
| 215 | +{ |
| 216 | + return ldev->pf[MLX5_LAG_P1].has_drop || ldev->pf[MLX5_LAG_P2].has_drop; |
| 217 | +} |
| 218 | + |
| 219 | +static void mlx5_lag_drop_rule_cleanup(struct mlx5_lag *ldev) |
| 220 | +{ |
| 221 | + int i; |
| 222 | + |
| 223 | + for (i = 0; i < MLX5_MAX_PORTS; i++) { |
| 224 | + if (!ldev->pf[i].has_drop) |
| 225 | + continue; |
| 226 | + |
| 227 | + mlx5_esw_acl_ingress_vport_drop_rule_destroy(ldev->pf[i].dev->priv.eswitch, |
| 228 | + MLX5_VPORT_UPLINK); |
| 229 | + ldev->pf[i].has_drop = false; |
| 230 | + } |
| 231 | +} |
| 232 | + |
| 233 | +static void mlx5_lag_drop_rule_setup(struct mlx5_lag *ldev, |
| 234 | + struct lag_tracker *tracker) |
| 235 | +{ |
| 236 | + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; |
| 237 | + struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev; |
| 238 | + struct mlx5_core_dev *inactive; |
| 239 | + u8 v2p_port1, v2p_port2; |
| 240 | + int inactive_idx; |
| 241 | + int err; |
| 242 | + |
| 243 | + /* First delete the current drop rule so there won't be any dropped |
| 244 | + * packets |
| 245 | + */ |
| 246 | + mlx5_lag_drop_rule_cleanup(ldev); |
| 247 | + |
| 248 | + if (!ldev->tracker.has_inactive) |
| 249 | + return; |
| 250 | + |
| 251 | + mlx5_infer_tx_affinity_mapping(tracker, &v2p_port1, &v2p_port2); |
| 252 | + |
| 253 | + if (v2p_port1 == MLX5_LAG_EGRESS_PORT_1) { |
| 254 | + inactive = dev1; |
| 255 | + inactive_idx = MLX5_LAG_P2; |
| 256 | + } else { |
| 257 | + inactive = dev0; |
| 258 | + inactive_idx = MLX5_LAG_P1; |
| 259 | + } |
| 260 | + |
| 261 | + err = mlx5_esw_acl_ingress_vport_drop_rule_create(inactive->priv.eswitch, |
| 262 | + MLX5_VPORT_UPLINK); |
| 263 | + if (!err) |
| 264 | + ldev->pf[inactive_idx].has_drop = true; |
| 265 | + else |
| 266 | + mlx5_core_err(inactive, |
| 267 | + "Failed to create lag drop rule, error: %d", err); |
| 268 | +} |
| 269 | + |
213 | 270 | static int _mlx5_modify_lag(struct mlx5_lag *ldev, u8 v2p_port1, u8 v2p_port2) |
214 | 271 | { |
215 | 272 | struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; |
@@ -244,6 +301,10 @@ void mlx5_modify_lag(struct mlx5_lag *ldev, |
244 | 301 | ldev->v2p_map[MLX5_LAG_P1], |
245 | 302 | ldev->v2p_map[MLX5_LAG_P2]); |
246 | 303 | } |
| 304 | + |
| 305 | + if (tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP && |
| 306 | + !(ldev->flags & MLX5_LAG_FLAG_ROCE)) |
| 307 | + mlx5_lag_drop_rule_setup(ldev, tracker); |
247 | 308 | } |
248 | 309 |
|
249 | 310 | static void mlx5_lag_set_port_sel_mode(struct mlx5_lag *ldev, |
@@ -345,6 +406,10 @@ int mlx5_activate_lag(struct mlx5_lag *ldev, |
345 | 406 | return err; |
346 | 407 | } |
347 | 408 |
|
| 409 | + if (tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP && |
| 410 | + !roce_lag) |
| 411 | + mlx5_lag_drop_rule_setup(ldev, tracker); |
| 412 | + |
348 | 413 | ldev->flags |= flags; |
349 | 414 | ldev->shared_fdb = shared_fdb; |
350 | 415 | return 0; |
@@ -379,11 +444,15 @@ static int mlx5_deactivate_lag(struct mlx5_lag *ldev) |
379 | 444 | "Failed to deactivate VF LAG; driver restart required\n" |
380 | 445 | "Make sure all VFs are unbound prior to VF LAG activation or deactivation\n"); |
381 | 446 | } |
382 | | - } else if (flags & MLX5_LAG_FLAG_HASH_BASED) { |
383 | | - mlx5_lag_port_sel_destroy(ldev); |
| 447 | + return err; |
384 | 448 | } |
385 | 449 |
|
386 | | - return err; |
| 450 | + if (flags & MLX5_LAG_FLAG_HASH_BASED) |
| 451 | + mlx5_lag_port_sel_destroy(ldev); |
| 452 | + if (mlx5_lag_has_drop_rule(ldev)) |
| 453 | + mlx5_lag_drop_rule_cleanup(ldev); |
| 454 | + |
| 455 | + return 0; |
387 | 456 | } |
388 | 457 |
|
389 | 458 | static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev) |
|
0 commit comments