4949#include "en/devlink.h"
5050#include "fs_core.h"
5151#include "lib/mlx5.h"
52+ #include "lib/devcom.h"
5253#define CREATE_TRACE_POINTS
5354#include "diag/en_rep_tracepoint.h"
5455#include "en_accel/ipsec.h"
@@ -310,6 +311,8 @@ static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
310311 rpriv = mlx5e_rep_to_rep_priv (rep );
311312 list_for_each_entry_safe (rep_sq , tmp , & rpriv -> vport_sqs_list , list ) {
312313 mlx5_eswitch_del_send_to_vport_rule (rep_sq -> send_to_vport_rule );
314+ if (rep_sq -> send_to_vport_rule_peer )
315+ mlx5_eswitch_del_send_to_vport_rule (rep_sq -> send_to_vport_rule_peer );
313316 list_del (& rep_sq -> list );
314317 kfree (rep_sq );
315318 }
@@ -319,6 +322,7 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
319322 struct mlx5_eswitch_rep * rep ,
320323 u32 * sqns_array , int sqns_num )
321324{
325+ struct mlx5_eswitch * peer_esw = NULL ;
322326 struct mlx5_flow_handle * flow_rule ;
323327 struct mlx5e_rep_priv * rpriv ;
324328 struct mlx5e_rep_sq * rep_sq ;
@@ -329,6 +333,10 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
329333 return 0 ;
330334
331335 rpriv = mlx5e_rep_to_rep_priv (rep );
336+ if (mlx5_devcom_is_paired (esw -> dev -> priv .devcom , MLX5_DEVCOM_ESW_OFFLOADS ))
337+ peer_esw = mlx5_devcom_get_peer_data (esw -> dev -> priv .devcom ,
338+ MLX5_DEVCOM_ESW_OFFLOADS );
339+
332340 for (i = 0 ; i < sqns_num ; i ++ ) {
333341 rep_sq = kzalloc (sizeof (* rep_sq ), GFP_KERNEL );
334342 if (!rep_sq ) {
@@ -345,12 +353,34 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
345353 goto out_err ;
346354 }
347355 rep_sq -> send_to_vport_rule = flow_rule ;
356+ rep_sq -> sqn = sqns_array [i ];
357+
358+ if (peer_esw ) {
359+ flow_rule = mlx5_eswitch_add_send_to_vport_rule (peer_esw , esw ,
360+ rep , sqns_array [i ]);
361+ if (IS_ERR (flow_rule )) {
362+ err = PTR_ERR (flow_rule );
363+ mlx5_eswitch_del_send_to_vport_rule (rep_sq -> send_to_vport_rule );
364+ kfree (rep_sq );
365+ goto out_err ;
366+ }
367+ rep_sq -> send_to_vport_rule_peer = flow_rule ;
368+ }
369+
348370 list_add (& rep_sq -> list , & rpriv -> vport_sqs_list );
349371 }
372+
373+ if (peer_esw )
374+ mlx5_devcom_release_peer_data (esw -> dev -> priv .devcom , MLX5_DEVCOM_ESW_OFFLOADS );
375+
350376 return 0 ;
351377
352378out_err :
353379 mlx5e_sqs2vport_stop (esw , rep );
380+
381+ if (peer_esw )
382+ mlx5_devcom_release_peer_data (esw -> dev -> priv .devcom , MLX5_DEVCOM_ESW_OFFLOADS );
383+
354384 return err ;
355385}
356386
@@ -1264,10 +1294,64 @@ static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
12641294 return rpriv -> netdev ;
12651295}
12661296
1297+ static void mlx5e_vport_rep_event_unpair (struct mlx5_eswitch_rep * rep )
1298+ {
1299+ struct mlx5e_rep_priv * rpriv ;
1300+ struct mlx5e_rep_sq * rep_sq ;
1301+
1302+ rpriv = mlx5e_rep_to_rep_priv (rep );
1303+ list_for_each_entry (rep_sq , & rpriv -> vport_sqs_list , list ) {
1304+ if (!rep_sq -> send_to_vport_rule_peer )
1305+ continue ;
1306+ mlx5_eswitch_del_send_to_vport_rule (rep_sq -> send_to_vport_rule_peer );
1307+ rep_sq -> send_to_vport_rule_peer = NULL ;
1308+ }
1309+ }
1310+
1311+ static int mlx5e_vport_rep_event_pair (struct mlx5_eswitch * esw ,
1312+ struct mlx5_eswitch_rep * rep ,
1313+ struct mlx5_eswitch * peer_esw )
1314+ {
1315+ struct mlx5_flow_handle * flow_rule ;
1316+ struct mlx5e_rep_priv * rpriv ;
1317+ struct mlx5e_rep_sq * rep_sq ;
1318+
1319+ rpriv = mlx5e_rep_to_rep_priv (rep );
1320+ list_for_each_entry (rep_sq , & rpriv -> vport_sqs_list , list ) {
1321+ if (rep_sq -> send_to_vport_rule_peer )
1322+ continue ;
1323+ flow_rule = mlx5_eswitch_add_send_to_vport_rule (peer_esw , esw , rep , rep_sq -> sqn );
1324+ if (IS_ERR (flow_rule ))
1325+ goto err_out ;
1326+ rep_sq -> send_to_vport_rule_peer = flow_rule ;
1327+ }
1328+
1329+ return 0 ;
1330+ err_out :
1331+ mlx5e_vport_rep_event_unpair (rep );
1332+ return PTR_ERR (flow_rule );
1333+ }
1334+
1335+ static int mlx5e_vport_rep_event (struct mlx5_eswitch * esw ,
1336+ struct mlx5_eswitch_rep * rep ,
1337+ enum mlx5_switchdev_event event ,
1338+ void * data )
1339+ {
1340+ int err = 0 ;
1341+
1342+ if (event == MLX5_SWITCHDEV_EVENT_PAIR )
1343+ err = mlx5e_vport_rep_event_pair (esw , rep , data );
1344+ else if (event == MLX5_SWITCHDEV_EVENT_UNPAIR )
1345+ mlx5e_vport_rep_event_unpair (rep );
1346+
1347+ return err ;
1348+ }
1349+
12671350static const struct mlx5_eswitch_rep_ops rep_ops = {
12681351 .load = mlx5e_vport_rep_load ,
12691352 .unload = mlx5e_vport_rep_unload ,
1270- .get_proto_dev = mlx5e_vport_rep_get_proto_dev
1353+ .get_proto_dev = mlx5e_vport_rep_get_proto_dev ,
1354+ .event = mlx5e_vport_rep_event ,
12711355};
12721356
12731357static int mlx5e_rep_probe (struct auxiliary_device * adev ,
0 commit comments