@@ -17,6 +17,12 @@ struct mlx5e_fs_udp {
17
17
int ref_cnt ;
18
18
};
19
19
20
+ struct mlx5e_fs_any {
21
+ struct mlx5e_flow_table table ;
22
+ struct mlx5_flow_handle * default_rule ;
23
+ int ref_cnt ;
24
+ };
25
+
20
26
static char * fs_udp_type2str (enum fs_udp_type i )
21
27
{
22
28
switch (i ) {
@@ -341,3 +347,259 @@ int mlx5e_fs_tt_redirect_udp_create(struct mlx5e_priv *priv)
341
347
priv -> fs .udp = NULL ;
342
348
return err ;
343
349
}
350
+
351
+ static void fs_any_set_ethertype_flow (struct mlx5_flow_spec * spec , u16 ether_type )
352
+ {
353
+ spec -> match_criteria_enable = MLX5_MATCH_OUTER_HEADERS ;
354
+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , outer_headers .ethertype );
355
+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .ethertype , ether_type );
356
+ }
357
+
358
+ struct mlx5_flow_handle *
359
+ mlx5e_fs_tt_redirect_any_add_rule (struct mlx5e_priv * priv ,
360
+ u32 tir_num , u16 ether_type )
361
+ {
362
+ struct mlx5_flow_destination dest = {};
363
+ struct mlx5_flow_table * ft = NULL ;
364
+ MLX5_DECLARE_FLOW_ACT (flow_act );
365
+ struct mlx5_flow_handle * rule ;
366
+ struct mlx5_flow_spec * spec ;
367
+ struct mlx5e_fs_any * fs_any ;
368
+ int err ;
369
+
370
+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
371
+ if (!spec )
372
+ return ERR_PTR (- ENOMEM );
373
+
374
+ fs_any = priv -> fs .any ;
375
+ ft = fs_any -> table .t ;
376
+
377
+ fs_any_set_ethertype_flow (spec , ether_type );
378
+ dest .type = MLX5_FLOW_DESTINATION_TYPE_TIR ;
379
+ dest .tir_num = tir_num ;
380
+
381
+ rule = mlx5_add_flow_rules (ft , spec , & flow_act , & dest , 1 );
382
+ kvfree (spec );
383
+
384
+ if (IS_ERR (rule )) {
385
+ err = PTR_ERR (rule );
386
+ netdev_err (priv -> netdev , "%s: add ANY rule failed, err %d\n" ,
387
+ __func__ , err );
388
+ }
389
+ return rule ;
390
+ }
391
+
392
+ static int fs_any_add_default_rule (struct mlx5e_priv * priv )
393
+ {
394
+ struct mlx5e_flow_table * fs_any_t ;
395
+ struct mlx5_flow_destination dest ;
396
+ MLX5_DECLARE_FLOW_ACT (flow_act );
397
+ struct mlx5_flow_handle * rule ;
398
+ struct mlx5e_fs_any * fs_any ;
399
+ int err ;
400
+
401
+ fs_any = priv -> fs .any ;
402
+ fs_any_t = & fs_any -> table ;
403
+
404
+ dest = mlx5e_ttc_get_default_dest (priv , MLX5E_TT_ANY );
405
+ rule = mlx5_add_flow_rules (fs_any_t -> t , NULL , & flow_act , & dest , 1 );
406
+ if (IS_ERR (rule )) {
407
+ err = PTR_ERR (rule );
408
+ netdev_err (priv -> netdev ,
409
+ "%s: add default rule failed, fs type=ANY, err %d\n" ,
410
+ __func__ , err );
411
+ return err ;
412
+ }
413
+
414
+ fs_any -> default_rule = rule ;
415
+ return 0 ;
416
+ }
417
+
418
+ #define MLX5E_FS_ANY_NUM_GROUPS (2)
419
+ #define MLX5E_FS_ANY_GROUP1_SIZE (BIT(16))
420
+ #define MLX5E_FS_ANY_GROUP2_SIZE (BIT(0))
421
+ #define MLX5E_FS_ANY_TABLE_SIZE (MLX5E_FS_ANY_GROUP1_SIZE +\
422
+ MLX5E_FS_ANY_GROUP2_SIZE)
423
+
424
+ static int fs_any_create_groups (struct mlx5e_flow_table * ft )
425
+ {
426
+ int inlen = MLX5_ST_SZ_BYTES (create_flow_group_in );
427
+ void * outer_headers_c ;
428
+ int ix = 0 ;
429
+ u32 * in ;
430
+ int err ;
431
+ u8 * mc ;
432
+
433
+ ft -> g = kcalloc (MLX5E_FS_UDP_NUM_GROUPS , sizeof (* ft -> g ), GFP_KERNEL );
434
+ in = kvzalloc (inlen , GFP_KERNEL );
435
+ if (!in || !ft -> g ) {
436
+ kfree (ft -> g );
437
+ kvfree (in );
438
+ return - ENOMEM ;
439
+ }
440
+
441
+ /* Match on ethertype */
442
+ mc = MLX5_ADDR_OF (create_flow_group_in , in , match_criteria );
443
+ outer_headers_c = MLX5_ADDR_OF (fte_match_param , mc , outer_headers );
444
+ MLX5_SET_TO_ONES (fte_match_set_lyr_2_4 , outer_headers_c , ethertype );
445
+ MLX5_SET_CFG (in , match_criteria_enable , MLX5_MATCH_OUTER_HEADERS );
446
+ MLX5_SET_CFG (in , start_flow_index , ix );
447
+ ix += MLX5E_FS_ANY_GROUP1_SIZE ;
448
+ MLX5_SET_CFG (in , end_flow_index , ix - 1 );
449
+ ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
450
+ if (IS_ERR (ft -> g [ft -> num_groups ]))
451
+ goto err ;
452
+ ft -> num_groups ++ ;
453
+
454
+ /* Default Flow Group */
455
+ memset (in , 0 , inlen );
456
+ MLX5_SET_CFG (in , start_flow_index , ix );
457
+ ix += MLX5E_FS_ANY_GROUP2_SIZE ;
458
+ MLX5_SET_CFG (in , end_flow_index , ix - 1 );
459
+ ft -> g [ft -> num_groups ] = mlx5_create_flow_group (ft -> t , in );
460
+ if (IS_ERR (ft -> g [ft -> num_groups ]))
461
+ goto err ;
462
+ ft -> num_groups ++ ;
463
+
464
+ kvfree (in );
465
+ return 0 ;
466
+
467
+ err :
468
+ err = PTR_ERR (ft -> g [ft -> num_groups ]);
469
+ ft -> g [ft -> num_groups ] = NULL ;
470
+ kvfree (in );
471
+
472
+ return err ;
473
+ }
474
+
475
+ static int fs_any_create_table (struct mlx5e_priv * priv )
476
+ {
477
+ struct mlx5e_flow_table * ft = & priv -> fs .any -> table ;
478
+ struct mlx5_flow_table_attr ft_attr = {};
479
+ int err ;
480
+
481
+ ft -> num_groups = 0 ;
482
+
483
+ ft_attr .max_fte = MLX5E_FS_UDP_TABLE_SIZE ;
484
+ ft_attr .level = MLX5E_FS_TT_ANY_FT_LEVEL ;
485
+ ft_attr .prio = MLX5E_NIC_PRIO ;
486
+
487
+ ft -> t = mlx5_create_flow_table (priv -> fs .ns , & ft_attr );
488
+ if (IS_ERR (ft -> t )) {
489
+ err = PTR_ERR (ft -> t );
490
+ ft -> t = NULL ;
491
+ return err ;
492
+ }
493
+
494
+ netdev_dbg (priv -> netdev , "Created fs ANY table id %u level %u\n" ,
495
+ ft -> t -> id , ft -> t -> level );
496
+
497
+ err = fs_any_create_groups (ft );
498
+ if (err )
499
+ goto err ;
500
+
501
+ err = fs_any_add_default_rule (priv );
502
+ if (err )
503
+ goto err ;
504
+
505
+ return 0 ;
506
+
507
+ err :
508
+ mlx5e_destroy_flow_table (ft );
509
+ return err ;
510
+ }
511
+
512
+ static int fs_any_disable (struct mlx5e_priv * priv )
513
+ {
514
+ int err ;
515
+
516
+ /* Modify ttc rules destination to point back to the indir TIRs */
517
+ err = mlx5e_ttc_fwd_default_dest (priv , MLX5E_TT_ANY );
518
+ if (err ) {
519
+ netdev_err (priv -> netdev ,
520
+ "%s: modify ttc[%d] default destination failed, err(%d)\n" ,
521
+ __func__ , MLX5E_TT_ANY , err );
522
+ return err ;
523
+ }
524
+ return 0 ;
525
+ }
526
+
527
+ static int fs_any_enable (struct mlx5e_priv * priv )
528
+ {
529
+ struct mlx5_flow_destination dest = {};
530
+ int err ;
531
+
532
+ dest .type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ;
533
+ dest .ft = priv -> fs .any -> table .t ;
534
+
535
+ /* Modify ttc rules destination to point on the accel_fs FTs */
536
+ err = mlx5e_ttc_fwd_dest (priv , MLX5E_TT_ANY , & dest );
537
+ if (err ) {
538
+ netdev_err (priv -> netdev ,
539
+ "%s: modify ttc[%d] destination to accel failed, err(%d)\n" ,
540
+ __func__ , MLX5E_TT_ANY , err );
541
+ return err ;
542
+ }
543
+ return 0 ;
544
+ }
545
+
546
+ static void fs_any_destroy_table (struct mlx5e_fs_any * fs_any )
547
+ {
548
+ if (IS_ERR_OR_NULL (fs_any -> table .t ))
549
+ return ;
550
+
551
+ mlx5_del_flow_rules (fs_any -> default_rule );
552
+ mlx5e_destroy_flow_table (& fs_any -> table );
553
+ fs_any -> table .t = NULL ;
554
+ }
555
+
556
+ void mlx5e_fs_tt_redirect_any_destroy (struct mlx5e_priv * priv )
557
+ {
558
+ struct mlx5e_fs_any * fs_any = priv -> fs .any ;
559
+
560
+ if (!fs_any )
561
+ return ;
562
+
563
+ if (-- fs_any -> ref_cnt )
564
+ return ;
565
+
566
+ fs_any_disable (priv );
567
+
568
+ fs_any_destroy_table (fs_any );
569
+
570
+ kfree (fs_any );
571
+ priv -> fs .any = NULL ;
572
+ }
573
+
574
+ int mlx5e_fs_tt_redirect_any_create (struct mlx5e_priv * priv )
575
+ {
576
+ int err ;
577
+
578
+ if (priv -> fs .any ) {
579
+ priv -> fs .any -> ref_cnt ++ ;
580
+ return 0 ;
581
+ }
582
+
583
+ priv -> fs .any = kzalloc (sizeof (* priv -> fs .any ), GFP_KERNEL );
584
+ if (!priv -> fs .any )
585
+ return - ENOMEM ;
586
+
587
+ err = fs_any_create_table (priv );
588
+ if (err )
589
+ return err ;
590
+
591
+ err = fs_any_enable (priv );
592
+ if (err )
593
+ goto err_destroy_table ;
594
+
595
+ priv -> fs .any -> ref_cnt = 1 ;
596
+
597
+ return 0 ;
598
+
599
+ err_destroy_table :
600
+ fs_any_destroy_table (priv -> fs .any );
601
+
602
+ kfree (priv -> fs .any );
603
+ priv -> fs .any = NULL ;
604
+ return err ;
605
+ }
0 commit comments