@@ -308,22 +308,68 @@ static int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev,
308
308
return mlx5_cmd_exec (dev , in , sizeof (in ), out , sizeof (out ));
309
309
}
310
310
311
+ static int mlx5_set_extended_dest (struct mlx5_core_dev * dev ,
312
+ struct fs_fte * fte , bool * extended_dest )
313
+ {
314
+ int fw_log_max_fdb_encap_uplink =
315
+ MLX5_CAP_ESW (dev , log_max_fdb_encap_uplink );
316
+ int num_fwd_destinations = 0 ;
317
+ struct mlx5_flow_rule * dst ;
318
+ int num_encap = 0 ;
319
+
320
+ * extended_dest = false;
321
+ if (!(fte -> action .action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ))
322
+ return 0 ;
323
+
324
+ list_for_each_entry (dst , & fte -> node .children , node .list ) {
325
+ if (dst -> dest_attr .type == MLX5_FLOW_DESTINATION_TYPE_COUNTER )
326
+ continue ;
327
+ if (dst -> dest_attr .type == MLX5_FLOW_DESTINATION_TYPE_VPORT &&
328
+ dst -> dest_attr .vport .flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID )
329
+ num_encap ++ ;
330
+ num_fwd_destinations ++ ;
331
+ }
332
+ if (num_fwd_destinations > 1 && num_encap > 0 )
333
+ * extended_dest = true;
334
+
335
+ if (* extended_dest && !fw_log_max_fdb_encap_uplink ) {
336
+ mlx5_core_warn (dev , "FW does not support extended destination" );
337
+ return - EOPNOTSUPP ;
338
+ }
339
+ if (num_encap > (1 << fw_log_max_fdb_encap_uplink )) {
340
+ mlx5_core_warn (dev , "FW does not support more than %d encaps" ,
341
+ 1 << fw_log_max_fdb_encap_uplink );
342
+ return - EOPNOTSUPP ;
343
+ }
344
+
345
+ return 0 ;
346
+ }
311
347
static int mlx5_cmd_set_fte (struct mlx5_core_dev * dev ,
312
348
int opmod , int modify_mask ,
313
349
struct mlx5_flow_table * ft ,
314
350
unsigned group_id ,
315
351
struct fs_fte * fte )
316
352
{
317
- unsigned int inlen = MLX5_ST_SZ_BYTES (set_fte_in ) +
318
- fte -> dests_size * MLX5_ST_SZ_BYTES (dest_format_struct );
319
353
u32 out [MLX5_ST_SZ_DW (set_fte_out )] = {0 };
354
+ bool extended_dest = false;
320
355
struct mlx5_flow_rule * dst ;
321
356
void * in_flow_context , * vlan ;
322
357
void * in_match_value ;
358
+ unsigned int inlen ;
359
+ int dst_cnt_size ;
323
360
void * in_dests ;
324
361
u32 * in ;
325
362
int err ;
326
363
364
+ if (mlx5_set_extended_dest (dev , fte , & extended_dest ))
365
+ return - EOPNOTSUPP ;
366
+
367
+ if (!extended_dest )
368
+ dst_cnt_size = MLX5_ST_SZ_BYTES (dest_format_struct );
369
+ else
370
+ dst_cnt_size = MLX5_ST_SZ_BYTES (extended_dest_format );
371
+
372
+ inlen = MLX5_ST_SZ_BYTES (set_fte_in ) + fte -> dests_size * dst_cnt_size ;
327
373
in = kvzalloc (inlen , GFP_KERNEL );
328
374
if (!in )
329
375
return - ENOMEM ;
@@ -343,9 +389,20 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
343
389
MLX5_SET (flow_context , in_flow_context , group_id , group_id );
344
390
345
391
MLX5_SET (flow_context , in_flow_context , flow_tag , fte -> action .flow_tag );
346
- MLX5_SET (flow_context , in_flow_context , action , fte -> action .action );
347
- MLX5_SET (flow_context , in_flow_context , packet_reformat_id ,
348
- fte -> action .reformat_id );
392
+ MLX5_SET (flow_context , in_flow_context , extended_destination ,
393
+ extended_dest );
394
+ if (extended_dest ) {
395
+ u32 action ;
396
+
397
+ action = fte -> action .action &
398
+ ~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT ;
399
+ MLX5_SET (flow_context , in_flow_context , action , action );
400
+ } else {
401
+ MLX5_SET (flow_context , in_flow_context , action ,
402
+ fte -> action .action );
403
+ MLX5_SET (flow_context , in_flow_context , packet_reformat_id ,
404
+ fte -> action .reformat_id );
405
+ }
349
406
MLX5_SET (flow_context , in_flow_context , modify_header_id ,
350
407
fte -> action .modify_id );
351
408
@@ -392,6 +449,15 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
392
449
MLX5_SET (dest_format_struct , in_dests ,
393
450
destination_eswitch_owner_vhca_id ,
394
451
dst -> dest_attr .vport .vhca_id );
452
+ if (extended_dest ) {
453
+ MLX5_SET (dest_format_struct , in_dests ,
454
+ packet_reformat ,
455
+ !!(dst -> dest_attr .vport .flags &
456
+ MLX5_FLOW_DEST_VPORT_REFORMAT_ID ));
457
+ MLX5_SET (extended_dest_format , in_dests ,
458
+ packet_reformat_id ,
459
+ dst -> dest_attr .vport .reformat_id );
460
+ }
395
461
break ;
396
462
default :
397
463
id = dst -> dest_attr .tir_num ;
@@ -400,7 +466,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
400
466
MLX5_SET (dest_format_struct , in_dests , destination_type ,
401
467
type );
402
468
MLX5_SET (dest_format_struct , in_dests , destination_id , id );
403
- in_dests += MLX5_ST_SZ_BYTES ( dest_format_struct ) ;
469
+ in_dests += dst_cnt_size ;
404
470
list_size ++ ;
405
471
}
406
472
@@ -421,7 +487,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
421
487
422
488
MLX5_SET (flow_counter_list , in_dests , flow_counter_id ,
423
489
dst -> dest_attr .counter_id );
424
- in_dests += MLX5_ST_SZ_BYTES ( dest_format_struct ) ;
490
+ in_dests += dst_cnt_size ;
425
491
list_size ++ ;
426
492
}
427
493
if (list_size > max_list_size ) {
0 commit comments