@@ -848,6 +848,15 @@ struct mlxsw_sp_acl_tcam_flower_rule {
848848 struct mlxsw_sp_acl_tcam_entry entry ;
849849};
850850
851+ struct mlxsw_sp_acl_tcam_mr_ruleset {
852+ struct mlxsw_sp_acl_tcam_chunk * chunk ;
853+ struct mlxsw_sp_acl_tcam_group group ;
854+ };
855+
856+ struct mlxsw_sp_acl_tcam_mr_rule {
857+ struct mlxsw_sp_acl_tcam_entry entry ;
858+ };
859+
851860static int
852861mlxsw_sp_acl_tcam_flower_ruleset_add (struct mlxsw_sp * mlxsw_sp ,
853862 struct mlxsw_sp_acl_tcam * tcam ,
@@ -952,9 +961,129 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
952961 .rule_activity_get = mlxsw_sp_acl_tcam_flower_rule_activity_get ,
953962};
954963
964+ static int
965+ mlxsw_sp_acl_tcam_mr_ruleset_add (struct mlxsw_sp * mlxsw_sp ,
966+ struct mlxsw_sp_acl_tcam * tcam ,
967+ void * ruleset_priv ,
968+ struct mlxsw_afk_element_usage * tmplt_elusage )
969+ {
970+ struct mlxsw_sp_acl_tcam_mr_ruleset * ruleset = ruleset_priv ;
971+ int err ;
972+
973+ err = mlxsw_sp_acl_tcam_group_add (mlxsw_sp , tcam , & ruleset -> group ,
974+ mlxsw_sp_acl_tcam_patterns ,
975+ MLXSW_SP_ACL_TCAM_PATTERNS_COUNT ,
976+ tmplt_elusage );
977+ if (err )
978+ return err ;
979+
980+ /* For most of the TCAM clients it would make sense to take a tcam chunk
981+ * only when the first rule is written. This is not the case for
982+ * multicast router as it is required to bind the multicast router to a
983+ * specific ACL Group ID which must exist in HW before multicast router
984+ * is initialized.
985+ */
986+ ruleset -> chunk = mlxsw_sp_acl_tcam_chunk_get (mlxsw_sp , & ruleset -> group ,
987+ 1 , tmplt_elusage );
988+ if (IS_ERR (ruleset -> chunk )) {
989+ err = PTR_ERR (ruleset -> chunk );
990+ goto err_chunk_get ;
991+ }
992+
993+ return 0 ;
994+
995+ err_chunk_get :
996+ mlxsw_sp_acl_tcam_group_del (mlxsw_sp , & ruleset -> group );
997+ return err ;
998+ }
999+
1000+ static void
1001+ mlxsw_sp_acl_tcam_mr_ruleset_del (struct mlxsw_sp * mlxsw_sp , void * ruleset_priv )
1002+ {
1003+ struct mlxsw_sp_acl_tcam_mr_ruleset * ruleset = ruleset_priv ;
1004+
1005+ mlxsw_sp_acl_tcam_chunk_put (mlxsw_sp , ruleset -> chunk );
1006+ mlxsw_sp_acl_tcam_group_del (mlxsw_sp , & ruleset -> group );
1007+ }
1008+
1009+ static int
1010+ mlxsw_sp_acl_tcam_mr_ruleset_bind (struct mlxsw_sp * mlxsw_sp , void * ruleset_priv ,
1011+ struct mlxsw_sp_port * mlxsw_sp_port ,
1012+ bool ingress )
1013+ {
1014+ /* Binding is done when initializing multicast router */
1015+ return 0 ;
1016+ }
1017+
1018+ static void
1019+ mlxsw_sp_acl_tcam_mr_ruleset_unbind (struct mlxsw_sp * mlxsw_sp ,
1020+ void * ruleset_priv ,
1021+ struct mlxsw_sp_port * mlxsw_sp_port ,
1022+ bool ingress )
1023+ {
1024+ }
1025+
1026+ static u16
1027+ mlxsw_sp_acl_tcam_mr_ruleset_group_id (void * ruleset_priv )
1028+ {
1029+ struct mlxsw_sp_acl_tcam_mr_ruleset * ruleset = ruleset_priv ;
1030+
1031+ return mlxsw_sp_acl_tcam_group_id (& ruleset -> group );
1032+ }
1033+
1034+ static size_t mlxsw_sp_acl_tcam_mr_rule_priv_size (struct mlxsw_sp * mlxsw_sp )
1035+ {
1036+ return sizeof (struct mlxsw_sp_acl_tcam_mr_rule ) +
1037+ mlxsw_sp_acl_tcam_entry_priv_size (mlxsw_sp );
1038+ }
1039+
1040+ static int
1041+ mlxsw_sp_acl_tcam_mr_rule_add (struct mlxsw_sp * mlxsw_sp , void * ruleset_priv ,
1042+ void * rule_priv ,
1043+ struct mlxsw_sp_acl_rule_info * rulei )
1044+ {
1045+ struct mlxsw_sp_acl_tcam_mr_ruleset * ruleset = ruleset_priv ;
1046+ struct mlxsw_sp_acl_tcam_mr_rule * rule = rule_priv ;
1047+
1048+ return mlxsw_sp_acl_tcam_entry_add (mlxsw_sp , & ruleset -> group ,
1049+ & rule -> entry , rulei );
1050+ }
1051+
1052+ static void
1053+ mlxsw_sp_acl_tcam_mr_rule_del (struct mlxsw_sp * mlxsw_sp , void * rule_priv )
1054+ {
1055+ struct mlxsw_sp_acl_tcam_mr_rule * rule = rule_priv ;
1056+
1057+ mlxsw_sp_acl_tcam_entry_del (mlxsw_sp , & rule -> entry );
1058+ }
1059+
1060+ static int
1061+ mlxsw_sp_acl_tcam_mr_rule_activity_get (struct mlxsw_sp * mlxsw_sp ,
1062+ void * rule_priv , bool * activity )
1063+ {
1064+ struct mlxsw_sp_acl_tcam_mr_rule * rule = rule_priv ;
1065+
1066+ return mlxsw_sp_acl_tcam_entry_activity_get (mlxsw_sp , & rule -> entry ,
1067+ activity );
1068+ }
1069+
1070+ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
1071+ .ruleset_priv_size = sizeof (struct mlxsw_sp_acl_tcam_mr_ruleset ),
1072+ .ruleset_add = mlxsw_sp_acl_tcam_mr_ruleset_add ,
1073+ .ruleset_del = mlxsw_sp_acl_tcam_mr_ruleset_del ,
1074+ .ruleset_bind = mlxsw_sp_acl_tcam_mr_ruleset_bind ,
1075+ .ruleset_unbind = mlxsw_sp_acl_tcam_mr_ruleset_unbind ,
1076+ .ruleset_group_id = mlxsw_sp_acl_tcam_mr_ruleset_group_id ,
1077+ .rule_priv_size = mlxsw_sp_acl_tcam_mr_rule_priv_size ,
1078+ .rule_add = mlxsw_sp_acl_tcam_mr_rule_add ,
1079+ .rule_del = mlxsw_sp_acl_tcam_mr_rule_del ,
1080+ .rule_activity_get = mlxsw_sp_acl_tcam_mr_rule_activity_get ,
1081+ };
1082+
9551083static const struct mlxsw_sp_acl_profile_ops *
9561084mlxsw_sp_acl_tcam_profile_ops_arr [] = {
9571085 [MLXSW_SP_ACL_PROFILE_FLOWER ] = & mlxsw_sp_acl_tcam_flower_ops ,
1086+ [MLXSW_SP_ACL_PROFILE_MR ] = & mlxsw_sp_acl_tcam_mr_ops ,
9581087};
9591088
9601089const struct mlxsw_sp_acl_profile_ops *
0 commit comments