@@ -310,17 +310,41 @@ struct mlxsw_afa_block {
310
310
struct mlxsw_afa_set * first_set ;
311
311
struct mlxsw_afa_set * cur_set ;
312
312
unsigned int cur_act_index ; /* In current set. */
313
- struct list_head fwd_entry_ref_list ;
313
+ struct list_head resource_list ; /* List of resources held by actions
314
+ * in this block.
315
+ */
314
316
};
315
317
318
+ struct mlxsw_afa_resource {
319
+ struct list_head list ;
320
+ void (* destructor )(struct mlxsw_afa_block * block ,
321
+ struct mlxsw_afa_resource * resource );
322
+ };
323
+
324
+ static void mlxsw_afa_resource_add (struct mlxsw_afa_block * block ,
325
+ struct mlxsw_afa_resource * resource )
326
+ {
327
+ list_add (& resource -> list , & block -> resource_list );
328
+ }
329
+
330
+ static void mlxsw_afa_resources_destroy (struct mlxsw_afa_block * block )
331
+ {
332
+ struct mlxsw_afa_resource * resource , * tmp ;
333
+
334
+ list_for_each_entry_safe (resource , tmp , & block -> resource_list , list ) {
335
+ list_del (& resource -> list );
336
+ resource -> destructor (block , resource );
337
+ }
338
+ }
339
+
316
340
struct mlxsw_afa_block * mlxsw_afa_block_create (struct mlxsw_afa * mlxsw_afa )
317
341
{
318
342
struct mlxsw_afa_block * block ;
319
343
320
344
block = kzalloc (sizeof (* block ), GFP_KERNEL );
321
345
if (!block )
322
346
return NULL ;
323
- INIT_LIST_HEAD (& block -> fwd_entry_ref_list );
347
+ INIT_LIST_HEAD (& block -> resource_list );
324
348
block -> afa = mlxsw_afa ;
325
349
326
350
/* At least one action set is always present, so just create it here */
@@ -336,8 +360,6 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa)
336
360
}
337
361
EXPORT_SYMBOL (mlxsw_afa_block_create );
338
362
339
- static void mlxsw_afa_fwd_entry_refs_destroy (struct mlxsw_afa_block * block );
340
-
341
363
void mlxsw_afa_block_destroy (struct mlxsw_afa_block * block )
342
364
{
343
365
struct mlxsw_afa_set * set = block -> first_set ;
@@ -348,7 +370,7 @@ void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block)
348
370
mlxsw_afa_set_put (block -> afa , set );
349
371
set = next_set ;
350
372
} while (set );
351
- mlxsw_afa_fwd_entry_refs_destroy (block );
373
+ mlxsw_afa_resources_destroy (block );
352
374
kfree (block );
353
375
}
354
376
EXPORT_SYMBOL (mlxsw_afa_block_destroy );
@@ -489,10 +511,29 @@ static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa,
489
511
}
490
512
491
513
struct mlxsw_afa_fwd_entry_ref {
492
- struct list_head list ;
514
+ struct mlxsw_afa_resource resource ;
493
515
struct mlxsw_afa_fwd_entry * fwd_entry ;
494
516
};
495
517
518
+ static void
519
+ mlxsw_afa_fwd_entry_ref_destroy (struct mlxsw_afa_block * block ,
520
+ struct mlxsw_afa_fwd_entry_ref * fwd_entry_ref )
521
+ {
522
+ mlxsw_afa_fwd_entry_put (block -> afa , fwd_entry_ref -> fwd_entry );
523
+ kfree (fwd_entry_ref );
524
+ }
525
+
526
+ static void
527
+ mlxsw_afa_fwd_entry_ref_destructor (struct mlxsw_afa_block * block ,
528
+ struct mlxsw_afa_resource * resource )
529
+ {
530
+ struct mlxsw_afa_fwd_entry_ref * fwd_entry_ref ;
531
+
532
+ fwd_entry_ref = container_of (resource , struct mlxsw_afa_fwd_entry_ref ,
533
+ resource );
534
+ mlxsw_afa_fwd_entry_ref_destroy (block , fwd_entry_ref );
535
+ }
536
+
496
537
static struct mlxsw_afa_fwd_entry_ref *
497
538
mlxsw_afa_fwd_entry_ref_create (struct mlxsw_afa_block * block , u8 local_port )
498
539
{
@@ -509,31 +550,60 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)
509
550
goto err_fwd_entry_get ;
510
551
}
511
552
fwd_entry_ref -> fwd_entry = fwd_entry ;
512
- list_add (& fwd_entry_ref -> list , & block -> fwd_entry_ref_list );
553
+ fwd_entry_ref -> resource .destructor = mlxsw_afa_fwd_entry_ref_destructor ;
554
+ mlxsw_afa_resource_add (block , & fwd_entry_ref -> resource );
513
555
return fwd_entry_ref ;
514
556
515
557
err_fwd_entry_get :
516
558
kfree (fwd_entry_ref );
517
559
return ERR_PTR (err );
518
560
}
519
561
562
+ struct mlxsw_afa_counter {
563
+ struct mlxsw_afa_resource resource ;
564
+ u32 counter_index ;
565
+ };
566
+
520
567
static void
521
- mlxsw_afa_fwd_entry_ref_destroy (struct mlxsw_afa_block * block ,
522
- struct mlxsw_afa_fwd_entry_ref * fwd_entry_ref )
568
+ mlxsw_afa_counter_destroy (struct mlxsw_afa_block * block ,
569
+ struct mlxsw_afa_counter * counter )
523
570
{
524
- list_del (& fwd_entry_ref -> list );
525
- mlxsw_afa_fwd_entry_put (block -> afa , fwd_entry_ref -> fwd_entry );
526
- kfree (fwd_entry_ref );
571
+ block -> afa -> ops -> counter_index_put (block -> afa -> ops_priv ,
572
+ counter -> counter_index );
573
+ kfree (counter );
574
+ }
575
+
576
+ static void
577
+ mlxsw_afa_counter_destructor (struct mlxsw_afa_block * block ,
578
+ struct mlxsw_afa_resource * resource )
579
+ {
580
+ struct mlxsw_afa_counter * counter ;
581
+
582
+ counter = container_of (resource , struct mlxsw_afa_counter , resource );
583
+ mlxsw_afa_counter_destroy (block , counter );
527
584
}
528
585
529
- static void mlxsw_afa_fwd_entry_refs_destroy (struct mlxsw_afa_block * block )
586
+ static struct mlxsw_afa_counter *
587
+ mlxsw_afa_counter_create (struct mlxsw_afa_block * block )
530
588
{
531
- struct mlxsw_afa_fwd_entry_ref * fwd_entry_ref ;
532
- struct mlxsw_afa_fwd_entry_ref * tmp ;
589
+ struct mlxsw_afa_counter * counter ;
590
+ int err ;
591
+
592
+ counter = kzalloc (sizeof (* counter ), GFP_KERNEL );
593
+ if (!counter )
594
+ return ERR_PTR (- ENOMEM );
595
+
596
+ err = block -> afa -> ops -> counter_index_get (block -> afa -> ops_priv ,
597
+ & counter -> counter_index );
598
+ if (err )
599
+ goto err_counter_index_get ;
600
+ counter -> resource .destructor = mlxsw_afa_counter_destructor ;
601
+ mlxsw_afa_resource_add (block , & counter -> resource );
602
+ return counter ;
533
603
534
- list_for_each_entry_safe ( fwd_entry_ref , tmp ,
535
- & block -> fwd_entry_ref_list , list )
536
- mlxsw_afa_fwd_entry_ref_destroy ( block , fwd_entry_ref );
604
+ err_counter_index_get :
605
+ kfree ( counter );
606
+ return ERR_PTR ( err );
537
607
}
538
608
539
609
#define MLXSW_AFA_ONE_ACTION_LEN 32
@@ -690,6 +760,16 @@ MLXSW_ITEM32(afa, trapdisc, forward_action, 0x00, 0, 4);
690
760
*/
691
761
MLXSW_ITEM32 (afa , trapdisc , trap_id , 0x04 , 0 , 9 );
692
762
763
+ /* afa_trapdisc_mirror_agent
764
+ * Mirror agent.
765
+ */
766
+ MLXSW_ITEM32 (afa , trapdisc , mirror_agent , 0x08 , 29 , 3 );
767
+
768
+ /* afa_trapdisc_mirror_enable
769
+ * Mirror enable.
770
+ */
771
+ MLXSW_ITEM32 (afa , trapdisc , mirror_enable , 0x08 , 24 , 1 );
772
+
693
773
static inline void
694
774
mlxsw_afa_trapdisc_pack (char * payload ,
695
775
enum mlxsw_afa_trapdisc_trap_action trap_action ,
@@ -701,6 +781,14 @@ mlxsw_afa_trapdisc_pack(char *payload,
701
781
mlxsw_afa_trapdisc_trap_id_set (payload , trap_id );
702
782
}
703
783
784
+ static inline void
785
+ mlxsw_afa_trapdisc_mirror_pack (char * payload , bool mirror_enable ,
786
+ u8 mirror_agent )
787
+ {
788
+ mlxsw_afa_trapdisc_mirror_enable_set (payload , mirror_enable );
789
+ mlxsw_afa_trapdisc_mirror_agent_set (payload , mirror_agent );
790
+ }
791
+
704
792
int mlxsw_afa_block_append_drop (struct mlxsw_afa_block * block )
705
793
{
706
794
char * act = mlxsw_afa_block_append_action (block ,
@@ -746,6 +834,104 @@ int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
746
834
}
747
835
EXPORT_SYMBOL (mlxsw_afa_block_append_trap_and_forward );
748
836
837
+ struct mlxsw_afa_mirror {
838
+ struct mlxsw_afa_resource resource ;
839
+ int span_id ;
840
+ u8 local_in_port ;
841
+ u8 local_out_port ;
842
+ bool ingress ;
843
+ };
844
+
845
+ static void
846
+ mlxsw_afa_mirror_destroy (struct mlxsw_afa_block * block ,
847
+ struct mlxsw_afa_mirror * mirror )
848
+ {
849
+ block -> afa -> ops -> mirror_del (block -> afa -> ops_priv ,
850
+ mirror -> local_in_port ,
851
+ mirror -> local_out_port ,
852
+ mirror -> ingress );
853
+ kfree (mirror );
854
+ }
855
+
856
+ static void
857
+ mlxsw_afa_mirror_destructor (struct mlxsw_afa_block * block ,
858
+ struct mlxsw_afa_resource * resource )
859
+ {
860
+ struct mlxsw_afa_mirror * mirror ;
861
+
862
+ mirror = container_of (resource , struct mlxsw_afa_mirror , resource );
863
+ mlxsw_afa_mirror_destroy (block , mirror );
864
+ }
865
+
866
+ static struct mlxsw_afa_mirror *
867
+ mlxsw_afa_mirror_create (struct mlxsw_afa_block * block ,
868
+ u8 local_in_port , u8 local_out_port ,
869
+ bool ingress )
870
+ {
871
+ struct mlxsw_afa_mirror * mirror ;
872
+ int err ;
873
+
874
+ mirror = kzalloc (sizeof (* mirror ), GFP_KERNEL );
875
+ if (!mirror )
876
+ return ERR_PTR (- ENOMEM );
877
+
878
+ err = block -> afa -> ops -> mirror_add (block -> afa -> ops_priv ,
879
+ local_in_port , local_out_port ,
880
+ ingress , & mirror -> span_id );
881
+ if (err )
882
+ goto err_mirror_add ;
883
+
884
+ mirror -> ingress = ingress ;
885
+ mirror -> local_out_port = local_out_port ;
886
+ mirror -> local_in_port = local_in_port ;
887
+ mirror -> resource .destructor = mlxsw_afa_mirror_destructor ;
888
+ mlxsw_afa_resource_add (block , & mirror -> resource );
889
+ return mirror ;
890
+
891
+ err_mirror_add :
892
+ kfree (mirror );
893
+ return ERR_PTR (err );
894
+ }
895
+
896
+ static int
897
+ mlxsw_afa_block_append_allocated_mirror (struct mlxsw_afa_block * block ,
898
+ u8 mirror_agent )
899
+ {
900
+ char * act = mlxsw_afa_block_append_action (block ,
901
+ MLXSW_AFA_TRAPDISC_CODE ,
902
+ MLXSW_AFA_TRAPDISC_SIZE );
903
+ if (!act )
904
+ return - ENOBUFS ;
905
+ mlxsw_afa_trapdisc_pack (act , MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP ,
906
+ MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD , 0 );
907
+ mlxsw_afa_trapdisc_mirror_pack (act , true, mirror_agent );
908
+ return 0 ;
909
+ }
910
+
911
+ int
912
+ mlxsw_afa_block_append_mirror (struct mlxsw_afa_block * block ,
913
+ u8 local_in_port , u8 local_out_port , bool ingress )
914
+ {
915
+ struct mlxsw_afa_mirror * mirror ;
916
+ int err ;
917
+
918
+ mirror = mlxsw_afa_mirror_create (block , local_in_port , local_out_port ,
919
+ ingress );
920
+ if (IS_ERR (mirror ))
921
+ return PTR_ERR (mirror );
922
+
923
+ err = mlxsw_afa_block_append_allocated_mirror (block , mirror -> span_id );
924
+ if (err )
925
+ goto err_append_allocated_mirror ;
926
+
927
+ return 0 ;
928
+
929
+ err_append_allocated_mirror :
930
+ mlxsw_afa_mirror_destroy (block , mirror );
931
+ return err ;
932
+ }
933
+ EXPORT_SYMBOL (mlxsw_afa_block_append_mirror );
934
+
749
935
/* Forwarding Action
750
936
* -----------------
751
937
* Forwarding Action can be used to implement Policy Based Switching (PBS)
@@ -853,18 +1039,43 @@ mlxsw_afa_polcnt_pack(char *payload,
853
1039
mlxsw_afa_polcnt_counter_index_set (payload , counter_index );
854
1040
}
855
1041
856
- int mlxsw_afa_block_append_counter (struct mlxsw_afa_block * block ,
857
- u32 counter_index )
1042
+ int mlxsw_afa_block_append_allocated_counter (struct mlxsw_afa_block * block ,
1043
+ u32 counter_index )
858
1044
{
859
- char * act = mlxsw_afa_block_append_action (block ,
860
- MLXSW_AFA_POLCNT_CODE ,
1045
+ char * act = mlxsw_afa_block_append_action (block , MLXSW_AFA_POLCNT_CODE ,
861
1046
MLXSW_AFA_POLCNT_SIZE );
862
1047
if (!act )
863
1048
return - ENOBUFS ;
864
1049
mlxsw_afa_polcnt_pack (act , MLXSW_AFA_POLCNT_COUNTER_SET_TYPE_PACKETS_BYTES ,
865
1050
counter_index );
866
1051
return 0 ;
867
1052
}
1053
+ EXPORT_SYMBOL (mlxsw_afa_block_append_allocated_counter );
1054
+
1055
+ int mlxsw_afa_block_append_counter (struct mlxsw_afa_block * block ,
1056
+ u32 * p_counter_index )
1057
+ {
1058
+ struct mlxsw_afa_counter * counter ;
1059
+ u32 counter_index ;
1060
+ int err ;
1061
+
1062
+ counter = mlxsw_afa_counter_create (block );
1063
+ if (IS_ERR (counter ))
1064
+ return PTR_ERR (counter );
1065
+ counter_index = counter -> counter_index ;
1066
+
1067
+ err = mlxsw_afa_block_append_allocated_counter (block , counter_index );
1068
+ if (err )
1069
+ goto err_append_allocated_counter ;
1070
+
1071
+ if (p_counter_index )
1072
+ * p_counter_index = counter_index ;
1073
+ return 0 ;
1074
+
1075
+ err_append_allocated_counter :
1076
+ mlxsw_afa_counter_destroy (block , counter );
1077
+ return err ;
1078
+ }
868
1079
EXPORT_SYMBOL (mlxsw_afa_block_append_counter );
869
1080
870
1081
/* Virtual Router and Forwarding Domain Action
0 commit comments