1852f660bSAlex Vesker // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2852f660bSAlex Vesker /* Copyright (c) 2019 Mellanox Technologies. */
3852f660bSAlex Vesker 
4852f660bSAlex Vesker #include "dr_types.h"
5852f660bSAlex Vesker 
dr_mask_is_smac_set(struct mlx5dr_match_spec * spec)6852f660bSAlex Vesker static bool dr_mask_is_smac_set(struct mlx5dr_match_spec *spec)
7852f660bSAlex Vesker {
8852f660bSAlex Vesker 	return (spec->smac_47_16 || spec->smac_15_0);
9852f660bSAlex Vesker }
10852f660bSAlex Vesker 
dr_mask_is_dmac_set(struct mlx5dr_match_spec * spec)11852f660bSAlex Vesker static bool dr_mask_is_dmac_set(struct mlx5dr_match_spec *spec)
12852f660bSAlex Vesker {
13852f660bSAlex Vesker 	return (spec->dmac_47_16 || spec->dmac_15_0);
14852f660bSAlex Vesker }
15852f660bSAlex Vesker 
dr_mask_is_l3_base_set(struct mlx5dr_match_spec * spec)16852f660bSAlex Vesker static bool dr_mask_is_l3_base_set(struct mlx5dr_match_spec *spec)
17852f660bSAlex Vesker {
18852f660bSAlex Vesker 	return (spec->ip_protocol || spec->frag || spec->tcp_flags ||
19852f660bSAlex Vesker 		spec->ip_ecn || spec->ip_dscp);
20852f660bSAlex Vesker }
21852f660bSAlex Vesker 
dr_mask_is_tcp_udp_base_set(struct mlx5dr_match_spec * spec)22852f660bSAlex Vesker static bool dr_mask_is_tcp_udp_base_set(struct mlx5dr_match_spec *spec)
23852f660bSAlex Vesker {
24852f660bSAlex Vesker 	return (spec->tcp_sport || spec->tcp_dport ||
25852f660bSAlex Vesker 		spec->udp_sport || spec->udp_dport);
26852f660bSAlex Vesker }
27852f660bSAlex Vesker 
dr_mask_is_ipv4_set(struct mlx5dr_match_spec * spec)28852f660bSAlex Vesker static bool dr_mask_is_ipv4_set(struct mlx5dr_match_spec *spec)
29852f660bSAlex Vesker {
30852f660bSAlex Vesker 	return (spec->dst_ip_31_0 || spec->src_ip_31_0);
31852f660bSAlex Vesker }
32852f660bSAlex Vesker 
dr_mask_is_ipv4_5_tuple_set(struct mlx5dr_match_spec * spec)33852f660bSAlex Vesker static bool dr_mask_is_ipv4_5_tuple_set(struct mlx5dr_match_spec *spec)
34852f660bSAlex Vesker {
35852f660bSAlex Vesker 	return (dr_mask_is_l3_base_set(spec) ||
36852f660bSAlex Vesker 		dr_mask_is_tcp_udp_base_set(spec) ||
37852f660bSAlex Vesker 		dr_mask_is_ipv4_set(spec));
38852f660bSAlex Vesker }
39852f660bSAlex Vesker 
dr_mask_is_eth_l2_tnl_set(struct mlx5dr_match_misc * misc)40852f660bSAlex Vesker static bool dr_mask_is_eth_l2_tnl_set(struct mlx5dr_match_misc *misc)
41852f660bSAlex Vesker {
42852f660bSAlex Vesker 	return misc->vxlan_vni;
43852f660bSAlex Vesker }
44852f660bSAlex Vesker 
dr_mask_is_ttl_set(struct mlx5dr_match_spec * spec)45852f660bSAlex Vesker static bool dr_mask_is_ttl_set(struct mlx5dr_match_spec *spec)
46852f660bSAlex Vesker {
47852f660bSAlex Vesker 	return spec->ttl_hoplimit;
48852f660bSAlex Vesker }
49852f660bSAlex Vesker 
dr_mask_is_ipv4_ihl_set(struct mlx5dr_match_spec * spec)505c422bfaSYevgeny Kliteynik static bool dr_mask_is_ipv4_ihl_set(struct mlx5dr_match_spec *spec)
515c422bfaSYevgeny Kliteynik {
525c422bfaSYevgeny Kliteynik 	return spec->ipv4_ihl;
535c422bfaSYevgeny Kliteynik }
545c422bfaSYevgeny Kliteynik 
55852f660bSAlex Vesker #define DR_MASK_IS_L2_DST(_spec, _misc, _inner_outer) (_spec.first_vid || \
56852f660bSAlex Vesker 	(_spec).first_cfi || (_spec).first_prio || (_spec).cvlan_tag || \
57852f660bSAlex Vesker 	(_spec).svlan_tag || (_spec).dmac_47_16 || (_spec).dmac_15_0 || \
58852f660bSAlex Vesker 	(_spec).ethertype || (_spec).ip_version || \
59852f660bSAlex Vesker 	(_misc)._inner_outer##_second_vid || \
60852f660bSAlex Vesker 	(_misc)._inner_outer##_second_cfi || \
61852f660bSAlex Vesker 	(_misc)._inner_outer##_second_prio || \
62852f660bSAlex Vesker 	(_misc)._inner_outer##_second_cvlan_tag || \
63852f660bSAlex Vesker 	(_misc)._inner_outer##_second_svlan_tag)
64852f660bSAlex Vesker 
65852f660bSAlex Vesker #define DR_MASK_IS_ETH_L4_SET(_spec, _misc, _inner_outer) ( \
66852f660bSAlex Vesker 	dr_mask_is_l3_base_set(&(_spec)) || \
67852f660bSAlex Vesker 	dr_mask_is_tcp_udp_base_set(&(_spec)) || \
68852f660bSAlex Vesker 	dr_mask_is_ttl_set(&(_spec)) || \
69852f660bSAlex Vesker 	(_misc)._inner_outer##_ipv6_flow_label)
70852f660bSAlex Vesker 
71852f660bSAlex Vesker #define DR_MASK_IS_ETH_L4_MISC_SET(_misc3, _inner_outer) ( \
72852f660bSAlex Vesker 	(_misc3)._inner_outer##_tcp_seq_num || \
73852f660bSAlex Vesker 	(_misc3)._inner_outer##_tcp_ack_num)
74852f660bSAlex Vesker 
75852f660bSAlex Vesker #define DR_MASK_IS_FIRST_MPLS_SET(_misc2, _inner_outer) ( \
76852f660bSAlex Vesker 	(_misc2)._inner_outer##_first_mpls_label || \
77852f660bSAlex Vesker 	(_misc2)._inner_outer##_first_mpls_exp || \
78852f660bSAlex Vesker 	(_misc2)._inner_outer##_first_mpls_s_bos || \
79852f660bSAlex Vesker 	(_misc2)._inner_outer##_first_mpls_ttl)
80852f660bSAlex Vesker 
dr_mask_is_tnl_gre_set(struct mlx5dr_match_misc * misc)81de1facafSYevgeny Kliteynik static bool dr_mask_is_tnl_gre_set(struct mlx5dr_match_misc *misc)
82852f660bSAlex Vesker {
83852f660bSAlex Vesker 	return (misc->gre_key_h || misc->gre_key_l ||
84852f660bSAlex Vesker 		misc->gre_protocol || misc->gre_c_present ||
85852f660bSAlex Vesker 		misc->gre_k_present || misc->gre_s_present);
86852f660bSAlex Vesker }
87852f660bSAlex Vesker 
8835ba005dSYevgeny Kliteynik #define DR_MASK_IS_OUTER_MPLS_OVER_GRE_SET(_misc) (\
8935ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_gre_label || \
9035ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_gre_exp || \
9135ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_gre_s_bos || \
9235ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_gre_ttl)
93852f660bSAlex Vesker 
9435ba005dSYevgeny Kliteynik #define DR_MASK_IS_OUTER_MPLS_OVER_UDP_SET(_misc) (\
9535ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_udp_label || \
9635ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_udp_exp || \
9735ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_udp_s_bos || \
9835ba005dSYevgeny Kliteynik 	(_misc)->outer_first_mpls_over_udp_ttl)
99852f660bSAlex Vesker 
1006e9e286eSYevgeny Kliteynik static bool
dr_mask_is_vxlan_gpe_set(struct mlx5dr_match_misc3 * misc3)1018a8a1023SYevgeny Kliteynik dr_mask_is_vxlan_gpe_set(struct mlx5dr_match_misc3 *misc3)
102852f660bSAlex Vesker {
103852f660bSAlex Vesker 	return (misc3->outer_vxlan_gpe_vni ||
104852f660bSAlex Vesker 		misc3->outer_vxlan_gpe_next_protocol ||
105852f660bSAlex Vesker 		misc3->outer_vxlan_gpe_flags);
106852f660bSAlex Vesker }
107852f660bSAlex Vesker 
1086e9e286eSYevgeny Kliteynik static bool
dr_matcher_supp_vxlan_gpe(struct mlx5dr_cmd_caps * caps)1098a8a1023SYevgeny Kliteynik dr_matcher_supp_vxlan_gpe(struct mlx5dr_cmd_caps *caps)
1106e9e286eSYevgeny Kliteynik {
1116862c787SYevgeny Kliteynik 	return (caps->sw_format_ver >= MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
1129f125cedSYevgeny Kliteynik 	       (caps->flex_protocols & MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED);
1136e9e286eSYevgeny Kliteynik }
1146e9e286eSYevgeny Kliteynik 
1156e9e286eSYevgeny Kliteynik static bool
dr_mask_is_tnl_vxlan_gpe(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)1168a8a1023SYevgeny Kliteynik dr_mask_is_tnl_vxlan_gpe(struct mlx5dr_match_param *mask,
1176e9e286eSYevgeny Kliteynik 			 struct mlx5dr_domain *dmn)
1186e9e286eSYevgeny Kliteynik {
1198a8a1023SYevgeny Kliteynik 	return dr_mask_is_vxlan_gpe_set(&mask->misc3) &&
1208a8a1023SYevgeny Kliteynik 	       dr_matcher_supp_vxlan_gpe(&dmn->info.caps);
1216e9e286eSYevgeny Kliteynik }
1226e9e286eSYevgeny Kliteynik 
dr_mask_is_tnl_geneve_set(struct mlx5dr_match_misc * misc)1238a8a1023SYevgeny Kliteynik static bool dr_mask_is_tnl_geneve_set(struct mlx5dr_match_misc *misc)
124b6d12238SYevgeny Kliteynik {
125b6d12238SYevgeny Kliteynik 	return misc->geneve_vni ||
126b6d12238SYevgeny Kliteynik 	       misc->geneve_oam ||
127b6d12238SYevgeny Kliteynik 	       misc->geneve_protocol_type ||
128b6d12238SYevgeny Kliteynik 	       misc->geneve_opt_len;
129b6d12238SYevgeny Kliteynik }
130b6d12238SYevgeny Kliteynik 
dr_mask_is_tnl_geneve_tlv_opt(struct mlx5dr_match_misc3 * misc3)1313442e033SYevgeny Kliteynik static bool dr_mask_is_tnl_geneve_tlv_opt(struct mlx5dr_match_misc3 *misc3)
1323442e033SYevgeny Kliteynik {
1333442e033SYevgeny Kliteynik 	return misc3->geneve_tlv_option_0_data;
1343442e033SYevgeny Kliteynik }
1353442e033SYevgeny Kliteynik 
136b6d12238SYevgeny Kliteynik static bool
dr_matcher_supp_flex_parser_ok(struct mlx5dr_cmd_caps * caps)137f59464e2SYevgeny Kliteynik dr_matcher_supp_flex_parser_ok(struct mlx5dr_cmd_caps *caps)
138f59464e2SYevgeny Kliteynik {
139f59464e2SYevgeny Kliteynik 	return caps->flex_parser_ok_bits_supp;
140f59464e2SYevgeny Kliteynik }
141f59464e2SYevgeny Kliteynik 
dr_mask_is_tnl_geneve_tlv_opt_exist_set(struct mlx5dr_match_misc * misc,struct mlx5dr_domain * dmn)142f59464e2SYevgeny Kliteynik static bool dr_mask_is_tnl_geneve_tlv_opt_exist_set(struct mlx5dr_match_misc *misc,
143f59464e2SYevgeny Kliteynik 						    struct mlx5dr_domain *dmn)
144f59464e2SYevgeny Kliteynik {
145f59464e2SYevgeny Kliteynik 	return dr_matcher_supp_flex_parser_ok(&dmn->info.caps) &&
146f59464e2SYevgeny Kliteynik 	       misc->geneve_tlv_option_0_exist;
147f59464e2SYevgeny Kliteynik }
148f59464e2SYevgeny Kliteynik 
149f59464e2SYevgeny Kliteynik static bool
dr_matcher_supp_tnl_geneve(struct mlx5dr_cmd_caps * caps)1508a8a1023SYevgeny Kliteynik dr_matcher_supp_tnl_geneve(struct mlx5dr_cmd_caps *caps)
151b6d12238SYevgeny Kliteynik {
1526862c787SYevgeny Kliteynik 	return (caps->sw_format_ver >= MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
1539f125cedSYevgeny Kliteynik 	       (caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_ENABLED);
154b6d12238SYevgeny Kliteynik }
155b6d12238SYevgeny Kliteynik 
156b6d12238SYevgeny Kliteynik static bool
dr_mask_is_tnl_geneve(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)1578a8a1023SYevgeny Kliteynik dr_mask_is_tnl_geneve(struct mlx5dr_match_param *mask,
158b6d12238SYevgeny Kliteynik 		      struct mlx5dr_domain *dmn)
159b6d12238SYevgeny Kliteynik {
1608a8a1023SYevgeny Kliteynik 	return dr_mask_is_tnl_geneve_set(&mask->misc) &&
1618a8a1023SYevgeny Kliteynik 	       dr_matcher_supp_tnl_geneve(&dmn->info.caps);
1628a8a1023SYevgeny Kliteynik }
1638a8a1023SYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_set(struct mlx5dr_match_misc3 * misc3)164df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_set(struct mlx5dr_match_misc3 *misc3)
165df9dd15aSYevgeny Kliteynik {
166df9dd15aSYevgeny Kliteynik 	return misc3->gtpu_msg_flags || misc3->gtpu_msg_type || misc3->gtpu_teid;
167df9dd15aSYevgeny Kliteynik }
168df9dd15aSYevgeny Kliteynik 
dr_matcher_supp_tnl_gtpu(struct mlx5dr_cmd_caps * caps)169df9dd15aSYevgeny Kliteynik static bool dr_matcher_supp_tnl_gtpu(struct mlx5dr_cmd_caps *caps)
170df9dd15aSYevgeny Kliteynik {
171df9dd15aSYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_ENABLED;
172df9dd15aSYevgeny Kliteynik }
173df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)174df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu(struct mlx5dr_match_param *mask,
175df9dd15aSYevgeny Kliteynik 				struct mlx5dr_domain *dmn)
176df9dd15aSYevgeny Kliteynik {
177df9dd15aSYevgeny Kliteynik 	return dr_mask_is_tnl_gtpu_set(&mask->misc3) &&
178df9dd15aSYevgeny Kliteynik 	       dr_matcher_supp_tnl_gtpu(&dmn->info.caps);
179df9dd15aSYevgeny Kliteynik }
180df9dd15aSYevgeny Kliteynik 
dr_matcher_supp_tnl_gtpu_dw_0(struct mlx5dr_cmd_caps * caps)181df9dd15aSYevgeny Kliteynik static int dr_matcher_supp_tnl_gtpu_dw_0(struct mlx5dr_cmd_caps *caps)
182df9dd15aSYevgeny Kliteynik {
183df9dd15aSYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_0_ENABLED;
184df9dd15aSYevgeny Kliteynik }
185df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_dw_0(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)186df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_dw_0(struct mlx5dr_match_param *mask,
187df9dd15aSYevgeny Kliteynik 				     struct mlx5dr_domain *dmn)
188df9dd15aSYevgeny Kliteynik {
189df9dd15aSYevgeny Kliteynik 	return mask->misc3.gtpu_dw_0 &&
190df9dd15aSYevgeny Kliteynik 	       dr_matcher_supp_tnl_gtpu_dw_0(&dmn->info.caps);
191df9dd15aSYevgeny Kliteynik }
192df9dd15aSYevgeny Kliteynik 
dr_matcher_supp_tnl_gtpu_teid(struct mlx5dr_cmd_caps * caps)193df9dd15aSYevgeny Kliteynik static int dr_matcher_supp_tnl_gtpu_teid(struct mlx5dr_cmd_caps *caps)
194df9dd15aSYevgeny Kliteynik {
195df9dd15aSYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_TEID_ENABLED;
196df9dd15aSYevgeny Kliteynik }
197df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_teid(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)198df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_teid(struct mlx5dr_match_param *mask,
199df9dd15aSYevgeny Kliteynik 				     struct mlx5dr_domain *dmn)
200df9dd15aSYevgeny Kliteynik {
201df9dd15aSYevgeny Kliteynik 	return mask->misc3.gtpu_teid &&
202df9dd15aSYevgeny Kliteynik 	       dr_matcher_supp_tnl_gtpu_teid(&dmn->info.caps);
203df9dd15aSYevgeny Kliteynik }
204df9dd15aSYevgeny Kliteynik 
dr_matcher_supp_tnl_gtpu_dw_2(struct mlx5dr_cmd_caps * caps)205df9dd15aSYevgeny Kliteynik static int dr_matcher_supp_tnl_gtpu_dw_2(struct mlx5dr_cmd_caps *caps)
206df9dd15aSYevgeny Kliteynik {
207df9dd15aSYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_2_ENABLED;
208df9dd15aSYevgeny Kliteynik }
209df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_dw_2(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)210df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_dw_2(struct mlx5dr_match_param *mask,
211df9dd15aSYevgeny Kliteynik 				     struct mlx5dr_domain *dmn)
212df9dd15aSYevgeny Kliteynik {
213df9dd15aSYevgeny Kliteynik 	return mask->misc3.gtpu_dw_2 &&
214df9dd15aSYevgeny Kliteynik 	       dr_matcher_supp_tnl_gtpu_dw_2(&dmn->info.caps);
215df9dd15aSYevgeny Kliteynik }
216df9dd15aSYevgeny Kliteynik 
dr_matcher_supp_tnl_gtpu_first_ext(struct mlx5dr_cmd_caps * caps)217df9dd15aSYevgeny Kliteynik static int dr_matcher_supp_tnl_gtpu_first_ext(struct mlx5dr_cmd_caps *caps)
218df9dd15aSYevgeny Kliteynik {
219df9dd15aSYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_FIRST_EXT_DW_0_ENABLED;
220df9dd15aSYevgeny Kliteynik }
221df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_first_ext(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)222df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_first_ext(struct mlx5dr_match_param *mask,
223df9dd15aSYevgeny Kliteynik 					  struct mlx5dr_domain *dmn)
224df9dd15aSYevgeny Kliteynik {
225df9dd15aSYevgeny Kliteynik 	return mask->misc3.gtpu_first_ext_dw_0 &&
226df9dd15aSYevgeny Kliteynik 	       dr_matcher_supp_tnl_gtpu_first_ext(&dmn->info.caps);
227df9dd15aSYevgeny Kliteynik }
228df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_flex_parser_0(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)229df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_flex_parser_0(struct mlx5dr_match_param *mask,
230df9dd15aSYevgeny Kliteynik 					      struct mlx5dr_domain *dmn)
231df9dd15aSYevgeny Kliteynik {
232df9dd15aSYevgeny Kliteynik 	struct mlx5dr_cmd_caps *caps = &dmn->info.caps;
233df9dd15aSYevgeny Kliteynik 
234df9dd15aSYevgeny Kliteynik 	return (dr_is_flex_parser_0_id(caps->flex_parser_id_gtpu_dw_0) &&
235df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_dw_0(mask, dmn)) ||
236df9dd15aSYevgeny Kliteynik 	       (dr_is_flex_parser_0_id(caps->flex_parser_id_gtpu_teid) &&
237df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_teid(mask, dmn)) ||
238df9dd15aSYevgeny Kliteynik 	       (dr_is_flex_parser_0_id(caps->flex_parser_id_gtpu_dw_2) &&
239df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_dw_2(mask, dmn)) ||
240df9dd15aSYevgeny Kliteynik 	       (dr_is_flex_parser_0_id(caps->flex_parser_id_gtpu_first_ext_dw_0) &&
241df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_first_ext(mask, dmn));
242df9dd15aSYevgeny Kliteynik }
243df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_flex_parser_1(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)244df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_flex_parser_1(struct mlx5dr_match_param *mask,
245df9dd15aSYevgeny Kliteynik 					      struct mlx5dr_domain *dmn)
246df9dd15aSYevgeny Kliteynik {
247df9dd15aSYevgeny Kliteynik 	struct mlx5dr_cmd_caps *caps = &dmn->info.caps;
248df9dd15aSYevgeny Kliteynik 
249df9dd15aSYevgeny Kliteynik 	return (dr_is_flex_parser_1_id(caps->flex_parser_id_gtpu_dw_0) &&
250df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_dw_0(mask, dmn)) ||
251df9dd15aSYevgeny Kliteynik 	       (dr_is_flex_parser_1_id(caps->flex_parser_id_gtpu_teid) &&
252df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_teid(mask, dmn)) ||
253df9dd15aSYevgeny Kliteynik 	       (dr_is_flex_parser_1_id(caps->flex_parser_id_gtpu_dw_2) &&
254df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_dw_2(mask, dmn)) ||
255df9dd15aSYevgeny Kliteynik 	       (dr_is_flex_parser_1_id(caps->flex_parser_id_gtpu_first_ext_dw_0) &&
256df9dd15aSYevgeny Kliteynik 		dr_mask_is_tnl_gtpu_first_ext(mask, dmn));
257df9dd15aSYevgeny Kliteynik }
258df9dd15aSYevgeny Kliteynik 
dr_mask_is_tnl_gtpu_any(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)259df9dd15aSYevgeny Kliteynik static bool dr_mask_is_tnl_gtpu_any(struct mlx5dr_match_param *mask,
260df9dd15aSYevgeny Kliteynik 				    struct mlx5dr_domain *dmn)
261df9dd15aSYevgeny Kliteynik {
262df9dd15aSYevgeny Kliteynik 	return dr_mask_is_tnl_gtpu_flex_parser_0(mask, dmn) ||
263df9dd15aSYevgeny Kliteynik 	       dr_mask_is_tnl_gtpu_flex_parser_1(mask, dmn) ||
264df9dd15aSYevgeny Kliteynik 	       dr_mask_is_tnl_gtpu(mask, dmn);
265df9dd15aSYevgeny Kliteynik }
266df9dd15aSYevgeny Kliteynik 
dr_matcher_supp_icmp_v4(struct mlx5dr_cmd_caps * caps)2678a8a1023SYevgeny Kliteynik static int dr_matcher_supp_icmp_v4(struct mlx5dr_cmd_caps *caps)
2688a8a1023SYevgeny Kliteynik {
2696862c787SYevgeny Kliteynik 	return (caps->sw_format_ver >= MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
2709f125cedSYevgeny Kliteynik 	       (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED);
2718a8a1023SYevgeny Kliteynik }
2728a8a1023SYevgeny Kliteynik 
dr_matcher_supp_icmp_v6(struct mlx5dr_cmd_caps * caps)2738a8a1023SYevgeny Kliteynik static int dr_matcher_supp_icmp_v6(struct mlx5dr_cmd_caps *caps)
2748a8a1023SYevgeny Kliteynik {
2756862c787SYevgeny Kliteynik 	return (caps->sw_format_ver >= MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
2769f125cedSYevgeny Kliteynik 	       (caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED);
277b6d12238SYevgeny Kliteynik }
278b6d12238SYevgeny Kliteynik 
dr_mask_is_icmpv6_set(struct mlx5dr_match_misc3 * misc3)279de1facafSYevgeny Kliteynik static bool dr_mask_is_icmpv6_set(struct mlx5dr_match_misc3 *misc3)
280852f660bSAlex Vesker {
281852f660bSAlex Vesker 	return (misc3->icmpv6_type || misc3->icmpv6_code ||
282852f660bSAlex Vesker 		misc3->icmpv6_header_data);
283852f660bSAlex Vesker }
284852f660bSAlex Vesker 
dr_mask_is_icmp(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)2858a8a1023SYevgeny Kliteynik static bool dr_mask_is_icmp(struct mlx5dr_match_param *mask,
286de1facafSYevgeny Kliteynik 			    struct mlx5dr_domain *dmn)
287de1facafSYevgeny Kliteynik {
288de1facafSYevgeny Kliteynik 	if (DR_MASK_IS_ICMPV4_SET(&mask->misc3))
2898a8a1023SYevgeny Kliteynik 		return dr_matcher_supp_icmp_v4(&dmn->info.caps);
290de1facafSYevgeny Kliteynik 	else if (dr_mask_is_icmpv6_set(&mask->misc3))
2918a8a1023SYevgeny Kliteynik 		return dr_matcher_supp_icmp_v6(&dmn->info.caps);
292de1facafSYevgeny Kliteynik 
293de1facafSYevgeny Kliteynik 	return false;
294de1facafSYevgeny Kliteynik }
295de1facafSYevgeny Kliteynik 
dr_mask_is_wqe_metadata_set(struct mlx5dr_match_misc2 * misc2)296852f660bSAlex Vesker static bool dr_mask_is_wqe_metadata_set(struct mlx5dr_match_misc2 *misc2)
297852f660bSAlex Vesker {
298852f660bSAlex Vesker 	return misc2->metadata_reg_a;
299852f660bSAlex Vesker }
300852f660bSAlex Vesker 
dr_mask_is_reg_c_0_3_set(struct mlx5dr_match_misc2 * misc2)301852f660bSAlex Vesker static bool dr_mask_is_reg_c_0_3_set(struct mlx5dr_match_misc2 *misc2)
302852f660bSAlex Vesker {
303852f660bSAlex Vesker 	return (misc2->metadata_reg_c_0 || misc2->metadata_reg_c_1 ||
304852f660bSAlex Vesker 		misc2->metadata_reg_c_2 || misc2->metadata_reg_c_3);
305852f660bSAlex Vesker }
306852f660bSAlex Vesker 
dr_mask_is_reg_c_4_7_set(struct mlx5dr_match_misc2 * misc2)307852f660bSAlex Vesker static bool dr_mask_is_reg_c_4_7_set(struct mlx5dr_match_misc2 *misc2)
308852f660bSAlex Vesker {
309852f660bSAlex Vesker 	return (misc2->metadata_reg_c_4 || misc2->metadata_reg_c_5 ||
310852f660bSAlex Vesker 		misc2->metadata_reg_c_6 || misc2->metadata_reg_c_7);
311852f660bSAlex Vesker }
312852f660bSAlex Vesker 
dr_mask_is_gvmi_or_qpn_set(struct mlx5dr_match_misc * misc)313852f660bSAlex Vesker static bool dr_mask_is_gvmi_or_qpn_set(struct mlx5dr_match_misc *misc)
314852f660bSAlex Vesker {
315852f660bSAlex Vesker 	return (misc->source_sqn || misc->source_port);
316852f660bSAlex Vesker }
317852f660bSAlex Vesker 
dr_mask_is_flex_parser_id_0_3_set(u32 flex_parser_id,u32 flex_parser_value)318160e9cb3SYevgeny Kliteynik static bool dr_mask_is_flex_parser_id_0_3_set(u32 flex_parser_id,
319160e9cb3SYevgeny Kliteynik 					      u32 flex_parser_value)
320160e9cb3SYevgeny Kliteynik {
321160e9cb3SYevgeny Kliteynik 	if (flex_parser_id)
322160e9cb3SYevgeny Kliteynik 		return flex_parser_id <= DR_STE_MAX_FLEX_0_ID;
323160e9cb3SYevgeny Kliteynik 
324160e9cb3SYevgeny Kliteynik 	/* Using flex_parser 0 means that id is zero, thus value must be set. */
325160e9cb3SYevgeny Kliteynik 	return flex_parser_value;
326160e9cb3SYevgeny Kliteynik }
327160e9cb3SYevgeny Kliteynik 
dr_mask_is_flex_parser_0_3_set(struct mlx5dr_match_misc4 * misc4)328160e9cb3SYevgeny Kliteynik static bool dr_mask_is_flex_parser_0_3_set(struct mlx5dr_match_misc4 *misc4)
329160e9cb3SYevgeny Kliteynik {
330160e9cb3SYevgeny Kliteynik 	return (dr_mask_is_flex_parser_id_0_3_set(misc4->prog_sample_field_id_0,
331160e9cb3SYevgeny Kliteynik 						  misc4->prog_sample_field_value_0) ||
332160e9cb3SYevgeny Kliteynik 		dr_mask_is_flex_parser_id_0_3_set(misc4->prog_sample_field_id_1,
333160e9cb3SYevgeny Kliteynik 						  misc4->prog_sample_field_value_1) ||
334160e9cb3SYevgeny Kliteynik 		dr_mask_is_flex_parser_id_0_3_set(misc4->prog_sample_field_id_2,
335160e9cb3SYevgeny Kliteynik 						  misc4->prog_sample_field_value_2) ||
336160e9cb3SYevgeny Kliteynik 		dr_mask_is_flex_parser_id_0_3_set(misc4->prog_sample_field_id_3,
337160e9cb3SYevgeny Kliteynik 						  misc4->prog_sample_field_value_3));
338160e9cb3SYevgeny Kliteynik }
339160e9cb3SYevgeny Kliteynik 
dr_mask_is_flex_parser_id_4_7_set(u32 flex_parser_id)340160e9cb3SYevgeny Kliteynik static bool dr_mask_is_flex_parser_id_4_7_set(u32 flex_parser_id)
341160e9cb3SYevgeny Kliteynik {
342160e9cb3SYevgeny Kliteynik 	return flex_parser_id > DR_STE_MAX_FLEX_0_ID &&
343160e9cb3SYevgeny Kliteynik 	       flex_parser_id <= DR_STE_MAX_FLEX_1_ID;
344160e9cb3SYevgeny Kliteynik }
345160e9cb3SYevgeny Kliteynik 
dr_mask_is_flex_parser_4_7_set(struct mlx5dr_match_misc4 * misc4)346160e9cb3SYevgeny Kliteynik static bool dr_mask_is_flex_parser_4_7_set(struct mlx5dr_match_misc4 *misc4)
347160e9cb3SYevgeny Kliteynik {
348160e9cb3SYevgeny Kliteynik 	return (dr_mask_is_flex_parser_id_4_7_set(misc4->prog_sample_field_id_0) ||
349160e9cb3SYevgeny Kliteynik 		dr_mask_is_flex_parser_id_4_7_set(misc4->prog_sample_field_id_1) ||
350160e9cb3SYevgeny Kliteynik 		dr_mask_is_flex_parser_id_4_7_set(misc4->prog_sample_field_id_2) ||
351160e9cb3SYevgeny Kliteynik 		dr_mask_is_flex_parser_id_4_7_set(misc4->prog_sample_field_id_3));
352160e9cb3SYevgeny Kliteynik }
353160e9cb3SYevgeny Kliteynik 
dr_matcher_supp_tnl_mpls_over_gre(struct mlx5dr_cmd_caps * caps)35435ba005dSYevgeny Kliteynik static int dr_matcher_supp_tnl_mpls_over_gre(struct mlx5dr_cmd_caps *caps)
35535ba005dSYevgeny Kliteynik {
35635ba005dSYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_GRE_ENABLED;
35735ba005dSYevgeny Kliteynik }
35835ba005dSYevgeny Kliteynik 
dr_mask_is_tnl_mpls_over_gre(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)35935ba005dSYevgeny Kliteynik static bool dr_mask_is_tnl_mpls_over_gre(struct mlx5dr_match_param *mask,
36035ba005dSYevgeny Kliteynik 					 struct mlx5dr_domain *dmn)
36135ba005dSYevgeny Kliteynik {
36235ba005dSYevgeny Kliteynik 	return DR_MASK_IS_OUTER_MPLS_OVER_GRE_SET(&mask->misc2) &&
36335ba005dSYevgeny Kliteynik 	       dr_matcher_supp_tnl_mpls_over_gre(&dmn->info.caps);
36435ba005dSYevgeny Kliteynik }
36535ba005dSYevgeny Kliteynik 
dr_matcher_supp_tnl_mpls_over_udp(struct mlx5dr_cmd_caps * caps)36635ba005dSYevgeny Kliteynik static int dr_matcher_supp_tnl_mpls_over_udp(struct mlx5dr_cmd_caps *caps)
36735ba005dSYevgeny Kliteynik {
368c3fb0e28SYevgeny Kliteynik 	return caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_UDP_ENABLED;
36935ba005dSYevgeny Kliteynik }
37035ba005dSYevgeny Kliteynik 
dr_mask_is_tnl_mpls_over_udp(struct mlx5dr_match_param * mask,struct mlx5dr_domain * dmn)37135ba005dSYevgeny Kliteynik static bool dr_mask_is_tnl_mpls_over_udp(struct mlx5dr_match_param *mask,
37235ba005dSYevgeny Kliteynik 					 struct mlx5dr_domain *dmn)
37335ba005dSYevgeny Kliteynik {
37435ba005dSYevgeny Kliteynik 	return DR_MASK_IS_OUTER_MPLS_OVER_UDP_SET(&mask->misc2) &&
37535ba005dSYevgeny Kliteynik 	       dr_matcher_supp_tnl_mpls_over_udp(&dmn->info.caps);
37635ba005dSYevgeny Kliteynik }
37709753babSMuhammad Sammar 
dr_mask_is_tnl_header_0_1_set(struct mlx5dr_match_misc5 * misc5)37809753babSMuhammad Sammar static bool dr_mask_is_tnl_header_0_1_set(struct mlx5dr_match_misc5 *misc5)
37909753babSMuhammad Sammar {
38009753babSMuhammad Sammar 	return misc5->tunnel_header_0 || misc5->tunnel_header_1;
38109753babSMuhammad Sammar }
38209753babSMuhammad Sammar 
mlx5dr_matcher_select_builders(struct mlx5dr_matcher * matcher,struct mlx5dr_matcher_rx_tx * nic_matcher,enum mlx5dr_ipv outer_ipv,enum mlx5dr_ipv inner_ipv)383852f660bSAlex Vesker int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher,
384852f660bSAlex Vesker 				   struct mlx5dr_matcher_rx_tx *nic_matcher,
385667f2646SAlex Vesker 				   enum mlx5dr_ipv outer_ipv,
386667f2646SAlex Vesker 				   enum mlx5dr_ipv inner_ipv)
387852f660bSAlex Vesker {
388667f2646SAlex Vesker 	nic_matcher->ste_builder =
389667f2646SAlex Vesker 		nic_matcher->ste_builder_arr[outer_ipv][inner_ipv];
390667f2646SAlex Vesker 	nic_matcher->num_of_builders =
391667f2646SAlex Vesker 		nic_matcher->num_of_builders_arr[outer_ipv][inner_ipv];
392852f660bSAlex Vesker 
39386bb811bSAlex Vesker 	if (!nic_matcher->num_of_builders) {
394852f660bSAlex Vesker 		mlx5dr_dbg(matcher->tbl->dmn,
395852f660bSAlex Vesker 			   "Rule not supported on this matcher due to IP related fields\n");
396852f660bSAlex Vesker 		return -EINVAL;
397852f660bSAlex Vesker 	}
398852f660bSAlex Vesker 
399852f660bSAlex Vesker 	return 0;
400852f660bSAlex Vesker }
401852f660bSAlex Vesker 
dr_matcher_set_ste_builders(struct mlx5dr_matcher * matcher,struct mlx5dr_matcher_rx_tx * nic_matcher,enum mlx5dr_ipv outer_ipv,enum mlx5dr_ipv inner_ipv)402852f660bSAlex Vesker static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
403852f660bSAlex Vesker 				       struct mlx5dr_matcher_rx_tx *nic_matcher,
404667f2646SAlex Vesker 				       enum mlx5dr_ipv outer_ipv,
405667f2646SAlex Vesker 				       enum mlx5dr_ipv inner_ipv)
406852f660bSAlex Vesker {
407852f660bSAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
408852f660bSAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
4095212f9c6SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
410852f660bSAlex Vesker 	struct mlx5dr_match_param mask = {};
411990467f8SYevgeny Kliteynik 	bool allow_empty_match = false;
412852f660bSAlex Vesker 	struct mlx5dr_ste_build *sb;
413852f660bSAlex Vesker 	bool inner, rx;
414852f660bSAlex Vesker 	int idx = 0;
415852f660bSAlex Vesker 	int ret, i;
416852f660bSAlex Vesker 
417667f2646SAlex Vesker 	sb = nic_matcher->ste_builder_arr[outer_ipv][inner_ipv];
41846f2a8aeSYevgeny Kliteynik 	rx = nic_dmn->type == DR_DOMAIN_NIC_TYPE_RX;
419852f660bSAlex Vesker 
420852f660bSAlex Vesker 	/* Create a temporary mask to track and clear used mask fields */
421852f660bSAlex Vesker 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_OUTER)
422852f660bSAlex Vesker 		mask.outer = matcher->mask.outer;
423852f660bSAlex Vesker 
424852f660bSAlex Vesker 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_MISC)
425852f660bSAlex Vesker 		mask.misc = matcher->mask.misc;
426852f660bSAlex Vesker 
427852f660bSAlex Vesker 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_INNER)
428852f660bSAlex Vesker 		mask.inner = matcher->mask.inner;
429852f660bSAlex Vesker 
430852f660bSAlex Vesker 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_MISC2)
431852f660bSAlex Vesker 		mask.misc2 = matcher->mask.misc2;
432852f660bSAlex Vesker 
433852f660bSAlex Vesker 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_MISC3)
434852f660bSAlex Vesker 		mask.misc3 = matcher->mask.misc3;
435852f660bSAlex Vesker 
436160e9cb3SYevgeny Kliteynik 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_MISC4)
437160e9cb3SYevgeny Kliteynik 		mask.misc4 = matcher->mask.misc4;
438160e9cb3SYevgeny Kliteynik 
4398c2b4feeSMuhammad Sammar 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_MISC5)
4408c2b4feeSMuhammad Sammar 		mask.misc5 = matcher->mask.misc5;
4418c2b4feeSMuhammad Sammar 
442852f660bSAlex Vesker 	ret = mlx5dr_ste_build_pre_check(dmn, matcher->match_criteria,
443852f660bSAlex Vesker 					 &matcher->mask, NULL);
444852f660bSAlex Vesker 	if (ret)
445852f660bSAlex Vesker 		return ret;
446852f660bSAlex Vesker 
447990467f8SYevgeny Kliteynik 	/* Optimize RX pipe by reducing source port match, since
448990467f8SYevgeny Kliteynik 	 * the FDB RX part is connected only to the wire.
449990467f8SYevgeny Kliteynik 	 */
450990467f8SYevgeny Kliteynik 	if (dmn->type == MLX5DR_DOMAIN_TYPE_FDB &&
451990467f8SYevgeny Kliteynik 	    rx && mask.misc.source_port) {
452990467f8SYevgeny Kliteynik 		mask.misc.source_port = 0;
453990467f8SYevgeny Kliteynik 		mask.misc.source_eswitch_owner_vhca_id = 0;
454990467f8SYevgeny Kliteynik 		allow_empty_match = true;
455990467f8SYevgeny Kliteynik 	}
456990467f8SYevgeny Kliteynik 
457852f660bSAlex Vesker 	/* Outer */
458852f660bSAlex Vesker 	if (matcher->match_criteria & (DR_MATCHER_CRITERIA_OUTER |
459852f660bSAlex Vesker 				       DR_MATCHER_CRITERIA_MISC |
460852f660bSAlex Vesker 				       DR_MATCHER_CRITERIA_MISC2 |
46109753babSMuhammad Sammar 				       DR_MATCHER_CRITERIA_MISC3 |
46209753babSMuhammad Sammar 				       DR_MATCHER_CRITERIA_MISC5)) {
463852f660bSAlex Vesker 		inner = false;
464852f660bSAlex Vesker 
465852f660bSAlex Vesker 		if (dr_mask_is_wqe_metadata_set(&mask.misc2))
4665212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_general_purpose(ste_ctx, &sb[idx++],
4675212f9c6SYevgeny Kliteynik 							 &mask, inner, rx);
468852f660bSAlex Vesker 
469852f660bSAlex Vesker 		if (dr_mask_is_reg_c_0_3_set(&mask.misc2))
4705212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_register_0(ste_ctx, &sb[idx++],
4715212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
472852f660bSAlex Vesker 
473852f660bSAlex Vesker 		if (dr_mask_is_reg_c_4_7_set(&mask.misc2))
4745212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_register_1(ste_ctx, &sb[idx++],
4755212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
476852f660bSAlex Vesker 
477852f660bSAlex Vesker 		if (dr_mask_is_gvmi_or_qpn_set(&mask.misc) &&
478852f660bSAlex Vesker 		    (dmn->type == MLX5DR_DOMAIN_TYPE_FDB ||
479852f660bSAlex Vesker 		     dmn->type == MLX5DR_DOMAIN_TYPE_NIC_RX)) {
4805212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_src_gvmi_qpn(ste_ctx, &sb[idx++],
4815212f9c6SYevgeny Kliteynik 						      &mask, dmn, inner, rx);
482852f660bSAlex Vesker 		}
483852f660bSAlex Vesker 
484852f660bSAlex Vesker 		if (dr_mask_is_smac_set(&mask.outer) &&
485852f660bSAlex Vesker 		    dr_mask_is_dmac_set(&mask.outer)) {
4865212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_src_dst(ste_ctx, &sb[idx++],
4875212f9c6SYevgeny Kliteynik 							&mask, inner, rx);
488852f660bSAlex Vesker 		}
489852f660bSAlex Vesker 
490852f660bSAlex Vesker 		if (dr_mask_is_smac_set(&mask.outer))
4915212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_src(ste_ctx, &sb[idx++],
4925212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
493852f660bSAlex Vesker 
494852f660bSAlex Vesker 		if (DR_MASK_IS_L2_DST(mask.outer, mask.misc, outer))
4955212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_dst(ste_ctx, &sb[idx++],
4965212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
497852f660bSAlex Vesker 
498667f2646SAlex Vesker 		if (outer_ipv == DR_RULE_IPV6) {
499ffb0753bSYevgeny Kliteynik 			if (DR_MASK_IS_DST_IP_SET(&mask.outer))
5005212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
5015212f9c6SYevgeny Kliteynik 								 &mask, inner, rx);
502852f660bSAlex Vesker 
503ffb0753bSYevgeny Kliteynik 			if (DR_MASK_IS_SRC_IP_SET(&mask.outer))
5045212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
5055212f9c6SYevgeny Kliteynik 								 &mask, inner, rx);
506852f660bSAlex Vesker 
507852f660bSAlex Vesker 			if (DR_MASK_IS_ETH_L4_SET(mask.outer, mask.misc, outer))
5085212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_ipv6_l3_l4(ste_ctx, &sb[idx++],
5095212f9c6SYevgeny Kliteynik 								&mask, inner, rx);
510852f660bSAlex Vesker 		} else {
511852f660bSAlex Vesker 			if (dr_mask_is_ipv4_5_tuple_set(&mask.outer))
5125212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv4_5_tuple(ste_ctx, &sb[idx++],
5135212f9c6SYevgeny Kliteynik 								     &mask, inner, rx);
514852f660bSAlex Vesker 
5155c422bfaSYevgeny Kliteynik 			if (dr_mask_is_ttl_set(&mask.outer) ||
5165c422bfaSYevgeny Kliteynik 			    dr_mask_is_ipv4_ihl_set(&mask.outer))
5175212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv4_misc(ste_ctx, &sb[idx++],
5185212f9c6SYevgeny Kliteynik 								  &mask, inner, rx);
519852f660bSAlex Vesker 		}
520852f660bSAlex Vesker 
5218a8a1023SYevgeny Kliteynik 		if (dr_mask_is_tnl_vxlan_gpe(&mask, dmn))
5225212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_tnl_vxlan_gpe(ste_ctx, &sb[idx++],
5235212f9c6SYevgeny Kliteynik 						       &mask, inner, rx);
5243442e033SYevgeny Kliteynik 		else if (dr_mask_is_tnl_geneve(&mask, dmn)) {
5255212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_tnl_geneve(ste_ctx, &sb[idx++],
5265212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
5273442e033SYevgeny Kliteynik 			if (dr_mask_is_tnl_geneve_tlv_opt(&mask.misc3))
5283442e033SYevgeny Kliteynik 				mlx5dr_ste_build_tnl_geneve_tlv_opt(ste_ctx, &sb[idx++],
5293442e033SYevgeny Kliteynik 								    &mask, &dmn->info.caps,
5303442e033SYevgeny Kliteynik 								    inner, rx);
531f59464e2SYevgeny Kliteynik 			if (dr_mask_is_tnl_geneve_tlv_opt_exist_set(&mask.misc, dmn))
532f59464e2SYevgeny Kliteynik 				mlx5dr_ste_build_tnl_geneve_tlv_opt_exist(ste_ctx, &sb[idx++],
533f59464e2SYevgeny Kliteynik 									  &mask, &dmn->info.caps,
534f59464e2SYevgeny Kliteynik 									  inner, rx);
535df9dd15aSYevgeny Kliteynik 		} else if (dr_mask_is_tnl_gtpu_any(&mask, dmn)) {
536df9dd15aSYevgeny Kliteynik 			if (dr_mask_is_tnl_gtpu_flex_parser_0(&mask, dmn))
537df9dd15aSYevgeny Kliteynik 				mlx5dr_ste_build_tnl_gtpu_flex_parser_0(ste_ctx, &sb[idx++],
538df9dd15aSYevgeny Kliteynik 									&mask, &dmn->info.caps,
539df9dd15aSYevgeny Kliteynik 									inner, rx);
540df9dd15aSYevgeny Kliteynik 
541df9dd15aSYevgeny Kliteynik 			if (dr_mask_is_tnl_gtpu_flex_parser_1(&mask, dmn))
542df9dd15aSYevgeny Kliteynik 				mlx5dr_ste_build_tnl_gtpu_flex_parser_1(ste_ctx, &sb[idx++],
543df9dd15aSYevgeny Kliteynik 									&mask, &dmn->info.caps,
544df9dd15aSYevgeny Kliteynik 									inner, rx);
545df9dd15aSYevgeny Kliteynik 
546df9dd15aSYevgeny Kliteynik 			if (dr_mask_is_tnl_gtpu(&mask, dmn))
547df9dd15aSYevgeny Kliteynik 				mlx5dr_ste_build_tnl_gtpu(ste_ctx, &sb[idx++],
548df9dd15aSYevgeny Kliteynik 							  &mask, inner, rx);
54909753babSMuhammad Sammar 		} else if (dr_mask_is_tnl_header_0_1_set(&mask.misc5)) {
55009753babSMuhammad Sammar 			mlx5dr_ste_build_tnl_header_0_1(ste_ctx, &sb[idx++],
55109753babSMuhammad Sammar 							&mask, inner, rx);
5523442e033SYevgeny Kliteynik 		}
553df9dd15aSYevgeny Kliteynik 
554852f660bSAlex Vesker 		if (DR_MASK_IS_ETH_L4_MISC_SET(mask.misc3, outer))
5555212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l4_misc(ste_ctx, &sb[idx++],
5565212f9c6SYevgeny Kliteynik 						     &mask, inner, rx);
557852f660bSAlex Vesker 
558852f660bSAlex Vesker 		if (DR_MASK_IS_FIRST_MPLS_SET(mask.misc2, outer))
5595212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_mpls(ste_ctx, &sb[idx++],
5605212f9c6SYevgeny Kliteynik 					      &mask, inner, rx);
561852f660bSAlex Vesker 
56235ba005dSYevgeny Kliteynik 		if (dr_mask_is_tnl_mpls_over_gre(&mask, dmn))
56335ba005dSYevgeny Kliteynik 			mlx5dr_ste_build_tnl_mpls_over_gre(ste_ctx, &sb[idx++],
56435ba005dSYevgeny Kliteynik 							   &mask, &dmn->info.caps,
56535ba005dSYevgeny Kliteynik 							   inner, rx);
56635ba005dSYevgeny Kliteynik 		else if (dr_mask_is_tnl_mpls_over_udp(&mask, dmn))
56735ba005dSYevgeny Kliteynik 			mlx5dr_ste_build_tnl_mpls_over_udp(ste_ctx, &sb[idx++],
56835ba005dSYevgeny Kliteynik 							   &mask, &dmn->info.caps,
56935ba005dSYevgeny Kliteynik 							   inner, rx);
570852f660bSAlex Vesker 
5714923938dSYevgeny Kliteynik 		if (dr_mask_is_icmp(&mask, dmn))
5724923938dSYevgeny Kliteynik 			mlx5dr_ste_build_icmp(ste_ctx, &sb[idx++],
573852f660bSAlex Vesker 					      &mask, &dmn->info.caps,
574852f660bSAlex Vesker 					      inner, rx);
5754923938dSYevgeny Kliteynik 
576de1facafSYevgeny Kliteynik 		if (dr_mask_is_tnl_gre_set(&mask.misc))
5775212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_tnl_gre(ste_ctx, &sb[idx++],
5785212f9c6SYevgeny Kliteynik 						 &mask, inner, rx);
579852f660bSAlex Vesker 	}
580852f660bSAlex Vesker 
581852f660bSAlex Vesker 	/* Inner */
582852f660bSAlex Vesker 	if (matcher->match_criteria & (DR_MATCHER_CRITERIA_INNER |
583852f660bSAlex Vesker 				       DR_MATCHER_CRITERIA_MISC |
584852f660bSAlex Vesker 				       DR_MATCHER_CRITERIA_MISC2 |
585852f660bSAlex Vesker 				       DR_MATCHER_CRITERIA_MISC3)) {
586852f660bSAlex Vesker 		inner = true;
587852f660bSAlex Vesker 
588852f660bSAlex Vesker 		if (dr_mask_is_eth_l2_tnl_set(&mask.misc))
5895212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_tnl(ste_ctx, &sb[idx++],
5905212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
591852f660bSAlex Vesker 
592852f660bSAlex Vesker 		if (dr_mask_is_smac_set(&mask.inner) &&
593852f660bSAlex Vesker 		    dr_mask_is_dmac_set(&mask.inner)) {
5945212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_src_dst(ste_ctx, &sb[idx++],
595852f660bSAlex Vesker 							&mask, inner, rx);
596852f660bSAlex Vesker 		}
597852f660bSAlex Vesker 
598852f660bSAlex Vesker 		if (dr_mask_is_smac_set(&mask.inner))
5995212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_src(ste_ctx, &sb[idx++],
6005212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
601852f660bSAlex Vesker 
602852f660bSAlex Vesker 		if (DR_MASK_IS_L2_DST(mask.inner, mask.misc, inner))
6035212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l2_dst(ste_ctx, &sb[idx++],
6045212f9c6SYevgeny Kliteynik 						    &mask, inner, rx);
605852f660bSAlex Vesker 
606667f2646SAlex Vesker 		if (inner_ipv == DR_RULE_IPV6) {
607ffb0753bSYevgeny Kliteynik 			if (DR_MASK_IS_DST_IP_SET(&mask.inner))
6085212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
6095212f9c6SYevgeny Kliteynik 								 &mask, inner, rx);
610852f660bSAlex Vesker 
611ffb0753bSYevgeny Kliteynik 			if (DR_MASK_IS_SRC_IP_SET(&mask.inner))
6125212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
6135212f9c6SYevgeny Kliteynik 								 &mask, inner, rx);
614852f660bSAlex Vesker 
615852f660bSAlex Vesker 			if (DR_MASK_IS_ETH_L4_SET(mask.inner, mask.misc, inner))
6165212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_ipv6_l3_l4(ste_ctx, &sb[idx++],
6175212f9c6SYevgeny Kliteynik 								&mask, inner, rx);
618852f660bSAlex Vesker 		} else {
619852f660bSAlex Vesker 			if (dr_mask_is_ipv4_5_tuple_set(&mask.inner))
6205212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv4_5_tuple(ste_ctx, &sb[idx++],
6215212f9c6SYevgeny Kliteynik 								     &mask, inner, rx);
622852f660bSAlex Vesker 
6235c422bfaSYevgeny Kliteynik 			if (dr_mask_is_ttl_set(&mask.inner) ||
6245c422bfaSYevgeny Kliteynik 			    dr_mask_is_ipv4_ihl_set(&mask.inner))
6255212f9c6SYevgeny Kliteynik 				mlx5dr_ste_build_eth_l3_ipv4_misc(ste_ctx, &sb[idx++],
6265212f9c6SYevgeny Kliteynik 								  &mask, inner, rx);
627852f660bSAlex Vesker 		}
628852f660bSAlex Vesker 
629852f660bSAlex Vesker 		if (DR_MASK_IS_ETH_L4_MISC_SET(mask.misc3, inner))
6305212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_eth_l4_misc(ste_ctx, &sb[idx++],
6315212f9c6SYevgeny Kliteynik 						     &mask, inner, rx);
632852f660bSAlex Vesker 
633852f660bSAlex Vesker 		if (DR_MASK_IS_FIRST_MPLS_SET(mask.misc2, inner))
6345212f9c6SYevgeny Kliteynik 			mlx5dr_ste_build_mpls(ste_ctx, &sb[idx++],
6355212f9c6SYevgeny Kliteynik 					      &mask, inner, rx);
636852f660bSAlex Vesker 
63735ba005dSYevgeny Kliteynik 		if (dr_mask_is_tnl_mpls_over_gre(&mask, dmn))
63835ba005dSYevgeny Kliteynik 			mlx5dr_ste_build_tnl_mpls_over_gre(ste_ctx, &sb[idx++],
63935ba005dSYevgeny Kliteynik 							   &mask, &dmn->info.caps,
64035ba005dSYevgeny Kliteynik 							   inner, rx);
64135ba005dSYevgeny Kliteynik 		else if (dr_mask_is_tnl_mpls_over_udp(&mask, dmn))
64235ba005dSYevgeny Kliteynik 			mlx5dr_ste_build_tnl_mpls_over_udp(ste_ctx, &sb[idx++],
64335ba005dSYevgeny Kliteynik 							   &mask, &dmn->info.caps,
64435ba005dSYevgeny Kliteynik 							   inner, rx);
645852f660bSAlex Vesker 	}
646160e9cb3SYevgeny Kliteynik 
647160e9cb3SYevgeny Kliteynik 	if (matcher->match_criteria & DR_MATCHER_CRITERIA_MISC4) {
648160e9cb3SYevgeny Kliteynik 		if (dr_mask_is_flex_parser_0_3_set(&mask.misc4))
649160e9cb3SYevgeny Kliteynik 			mlx5dr_ste_build_flex_parser_0(ste_ctx, &sb[idx++],
650160e9cb3SYevgeny Kliteynik 						       &mask, false, rx);
651160e9cb3SYevgeny Kliteynik 
652160e9cb3SYevgeny Kliteynik 		if (dr_mask_is_flex_parser_4_7_set(&mask.misc4))
653160e9cb3SYevgeny Kliteynik 			mlx5dr_ste_build_flex_parser_1(ste_ctx, &sb[idx++],
654160e9cb3SYevgeny Kliteynik 						       &mask, false, rx);
655160e9cb3SYevgeny Kliteynik 	}
656160e9cb3SYevgeny Kliteynik 
657852f660bSAlex Vesker 	/* Empty matcher, takes all */
658990467f8SYevgeny Kliteynik 	if ((!idx && allow_empty_match) ||
659990467f8SYevgeny Kliteynik 	    matcher->match_criteria == DR_MATCHER_CRITERIA_EMPTY)
660852f660bSAlex Vesker 		mlx5dr_ste_build_empty_always_hit(&sb[idx++], rx);
661852f660bSAlex Vesker 
662852f660bSAlex Vesker 	if (idx == 0) {
663b7d0db55SErez Shitrit 		mlx5dr_err(dmn, "Cannot generate any valid rules from mask\n");
664852f660bSAlex Vesker 		return -EINVAL;
665852f660bSAlex Vesker 	}
666852f660bSAlex Vesker 
667852f660bSAlex Vesker 	/* Check that all mask fields were consumed */
668852f660bSAlex Vesker 	for (i = 0; i < sizeof(struct mlx5dr_match_param); i++) {
669852f660bSAlex Vesker 		if (((u8 *)&mask)[i] != 0) {
670ffdc8ec0SAlex Vesker 			mlx5dr_dbg(dmn, "Mask contains unsupported parameters\n");
671852f660bSAlex Vesker 			return -EOPNOTSUPP;
672852f660bSAlex Vesker 		}
673852f660bSAlex Vesker 	}
674852f660bSAlex Vesker 
675667f2646SAlex Vesker 	nic_matcher->ste_builder = sb;
676667f2646SAlex Vesker 	nic_matcher->num_of_builders_arr[outer_ipv][inner_ipv] = idx;
677852f660bSAlex Vesker 
678852f660bSAlex Vesker 	return 0;
679852f660bSAlex Vesker }
680852f660bSAlex Vesker 
dr_nic_matcher_connect(struct mlx5dr_domain * dmn,struct mlx5dr_matcher_rx_tx * curr_nic_matcher,struct mlx5dr_matcher_rx_tx * next_nic_matcher,struct mlx5dr_matcher_rx_tx * prev_nic_matcher)681cc2295cdSYevgeny Kliteynik static int dr_nic_matcher_connect(struct mlx5dr_domain *dmn,
682852f660bSAlex Vesker 				  struct mlx5dr_matcher_rx_tx *curr_nic_matcher,
683852f660bSAlex Vesker 				  struct mlx5dr_matcher_rx_tx *next_nic_matcher,
684852f660bSAlex Vesker 				  struct mlx5dr_matcher_rx_tx *prev_nic_matcher)
685852f660bSAlex Vesker {
686852f660bSAlex Vesker 	struct mlx5dr_table_rx_tx *nic_tbl = curr_nic_matcher->nic_tbl;
687852f660bSAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_tbl->nic_dmn;
688852f660bSAlex Vesker 	struct mlx5dr_htbl_connect_info info;
689852f660bSAlex Vesker 	struct mlx5dr_ste_htbl *prev_htbl;
690852f660bSAlex Vesker 	int ret;
691852f660bSAlex Vesker 
692852f660bSAlex Vesker 	/* Connect end anchor hash table to next_htbl or to the default address */
693852f660bSAlex Vesker 	if (next_nic_matcher) {
694852f660bSAlex Vesker 		info.type = CONNECT_HIT;
695852f660bSAlex Vesker 		info.hit_next_htbl = next_nic_matcher->s_htbl;
696852f660bSAlex Vesker 	} else {
697852f660bSAlex Vesker 		info.type = CONNECT_MISS;
698852f660bSAlex Vesker 		info.miss_icm_addr = nic_tbl->default_icm_addr;
699852f660bSAlex Vesker 	}
700852f660bSAlex Vesker 	ret = mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn,
701852f660bSAlex Vesker 						curr_nic_matcher->e_anchor,
702852f660bSAlex Vesker 						&info, info.type == CONNECT_HIT);
703852f660bSAlex Vesker 	if (ret)
704852f660bSAlex Vesker 		return ret;
705852f660bSAlex Vesker 
706852f660bSAlex Vesker 	/* Connect start hash table to end anchor */
707852f660bSAlex Vesker 	info.type = CONNECT_MISS;
7085c4f9b6eSRongwei Liu 	info.miss_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(curr_nic_matcher->e_anchor->chunk);
709852f660bSAlex Vesker 	ret = mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn,
710852f660bSAlex Vesker 						curr_nic_matcher->s_htbl,
711852f660bSAlex Vesker 						&info, false);
712852f660bSAlex Vesker 	if (ret)
713852f660bSAlex Vesker 		return ret;
714852f660bSAlex Vesker 
715852f660bSAlex Vesker 	/* Connect previous hash table to matcher start hash table */
716852f660bSAlex Vesker 	if (prev_nic_matcher)
717852f660bSAlex Vesker 		prev_htbl = prev_nic_matcher->e_anchor;
718852f660bSAlex Vesker 	else
719852f660bSAlex Vesker 		prev_htbl = nic_tbl->s_anchor;
720852f660bSAlex Vesker 
721852f660bSAlex Vesker 	info.type = CONNECT_HIT;
722852f660bSAlex Vesker 	info.hit_next_htbl = curr_nic_matcher->s_htbl;
723852f660bSAlex Vesker 	ret = mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn, prev_htbl,
724852f660bSAlex Vesker 						&info, true);
725852f660bSAlex Vesker 	if (ret)
726852f660bSAlex Vesker 		return ret;
727852f660bSAlex Vesker 
728852f660bSAlex Vesker 	/* Update the pointing ste and next hash table */
729*597534bdSRongwei Liu 	curr_nic_matcher->s_htbl->pointing_ste = prev_htbl->chunk->ste_arr;
730*597534bdSRongwei Liu 	prev_htbl->chunk->ste_arr[0].next_htbl = curr_nic_matcher->s_htbl;
731852f660bSAlex Vesker 
732852f660bSAlex Vesker 	if (next_nic_matcher) {
733*597534bdSRongwei Liu 		next_nic_matcher->s_htbl->pointing_ste =
734*597534bdSRongwei Liu 			curr_nic_matcher->e_anchor->chunk->ste_arr;
735*597534bdSRongwei Liu 		curr_nic_matcher->e_anchor->chunk->ste_arr[0].next_htbl =
736*597534bdSRongwei Liu 			next_nic_matcher->s_htbl;
737852f660bSAlex Vesker 	}
738852f660bSAlex Vesker 
739852f660bSAlex Vesker 	return 0;
740852f660bSAlex Vesker }
741852f660bSAlex Vesker 
mlx5dr_matcher_add_to_tbl_nic(struct mlx5dr_domain * dmn,struct mlx5dr_matcher_rx_tx * nic_matcher)742cc2295cdSYevgeny Kliteynik int mlx5dr_matcher_add_to_tbl_nic(struct mlx5dr_domain *dmn,
743cc2295cdSYevgeny Kliteynik 				  struct mlx5dr_matcher_rx_tx *nic_matcher)
744852f660bSAlex Vesker {
745cc2295cdSYevgeny Kliteynik 	struct mlx5dr_matcher_rx_tx *next_nic_matcher, *prev_nic_matcher, *tmp_nic_matcher;
746cc2295cdSYevgeny Kliteynik 	struct mlx5dr_table_rx_tx *nic_tbl = nic_matcher->nic_tbl;
747852f660bSAlex Vesker 	bool first = true;
748852f660bSAlex Vesker 	int ret;
749852f660bSAlex Vesker 
750cc2295cdSYevgeny Kliteynik 	/* If the nic matcher is already on its parent nic table list,
751cc2295cdSYevgeny Kliteynik 	 * then it is already connected to the chain of nic matchers.
752cc2295cdSYevgeny Kliteynik 	 */
753cc2295cdSYevgeny Kliteynik 	if (!list_empty(&nic_matcher->list_node))
754cc2295cdSYevgeny Kliteynik 		return 0;
755cc2295cdSYevgeny Kliteynik 
756cc2295cdSYevgeny Kliteynik 	next_nic_matcher = NULL;
757cc2295cdSYevgeny Kliteynik 	list_for_each_entry(tmp_nic_matcher, &nic_tbl->nic_matcher_list, list_node) {
758cc2295cdSYevgeny Kliteynik 		if (tmp_nic_matcher->prio >= nic_matcher->prio) {
759cc2295cdSYevgeny Kliteynik 			next_nic_matcher = tmp_nic_matcher;
760852f660bSAlex Vesker 			break;
761852f660bSAlex Vesker 		}
762852f660bSAlex Vesker 		first = false;
763852f660bSAlex Vesker 	}
764852f660bSAlex Vesker 
765cc2295cdSYevgeny Kliteynik 	prev_nic_matcher = NULL;
766cc2295cdSYevgeny Kliteynik 	if (next_nic_matcher && !first)
767cc2295cdSYevgeny Kliteynik 		prev_nic_matcher = list_prev_entry(next_nic_matcher, list_node);
768852f660bSAlex Vesker 	else if (!first)
769cc2295cdSYevgeny Kliteynik 		prev_nic_matcher = list_last_entry(&nic_tbl->nic_matcher_list,
770cc2295cdSYevgeny Kliteynik 						   struct mlx5dr_matcher_rx_tx,
77108fac109SYevgeny Kliteynik 						   list_node);
772852f660bSAlex Vesker 
773cc2295cdSYevgeny Kliteynik 	ret = dr_nic_matcher_connect(dmn, nic_matcher,
774cc2295cdSYevgeny Kliteynik 				     next_nic_matcher, prev_nic_matcher);
775852f660bSAlex Vesker 	if (ret)
776852f660bSAlex Vesker 		return ret;
777852f660bSAlex Vesker 
778cc2295cdSYevgeny Kliteynik 	if (prev_nic_matcher)
779cc2295cdSYevgeny Kliteynik 		list_add(&nic_matcher->list_node, &prev_nic_matcher->list_node);
780cc2295cdSYevgeny Kliteynik 	else if (next_nic_matcher)
781cc2295cdSYevgeny Kliteynik 		list_add_tail(&nic_matcher->list_node, &next_nic_matcher->list_node);
782852f660bSAlex Vesker 	else
783cc2295cdSYevgeny Kliteynik 		list_add(&nic_matcher->list_node, &nic_matcher->nic_tbl->nic_matcher_list);
784852f660bSAlex Vesker 
785cc2295cdSYevgeny Kliteynik 	return ret;
786852f660bSAlex Vesker }
787852f660bSAlex Vesker 
dr_matcher_uninit_nic(struct mlx5dr_matcher_rx_tx * nic_matcher)788852f660bSAlex Vesker static void dr_matcher_uninit_nic(struct mlx5dr_matcher_rx_tx *nic_matcher)
789852f660bSAlex Vesker {
790852f660bSAlex Vesker 	mlx5dr_htbl_put(nic_matcher->s_htbl);
791852f660bSAlex Vesker 	mlx5dr_htbl_put(nic_matcher->e_anchor);
792852f660bSAlex Vesker }
793852f660bSAlex Vesker 
dr_matcher_uninit_fdb(struct mlx5dr_matcher * matcher)794852f660bSAlex Vesker static void dr_matcher_uninit_fdb(struct mlx5dr_matcher *matcher)
795852f660bSAlex Vesker {
796852f660bSAlex Vesker 	dr_matcher_uninit_nic(&matcher->rx);
797852f660bSAlex Vesker 	dr_matcher_uninit_nic(&matcher->tx);
798852f660bSAlex Vesker }
799852f660bSAlex Vesker 
dr_matcher_uninit(struct mlx5dr_matcher * matcher)800852f660bSAlex Vesker static void dr_matcher_uninit(struct mlx5dr_matcher *matcher)
801852f660bSAlex Vesker {
802852f660bSAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
803852f660bSAlex Vesker 
804852f660bSAlex Vesker 	switch (dmn->type) {
805852f660bSAlex Vesker 	case MLX5DR_DOMAIN_TYPE_NIC_RX:
806852f660bSAlex Vesker 		dr_matcher_uninit_nic(&matcher->rx);
807852f660bSAlex Vesker 		break;
808852f660bSAlex Vesker 	case MLX5DR_DOMAIN_TYPE_NIC_TX:
809852f660bSAlex Vesker 		dr_matcher_uninit_nic(&matcher->tx);
810852f660bSAlex Vesker 		break;
811852f660bSAlex Vesker 	case MLX5DR_DOMAIN_TYPE_FDB:
812852f660bSAlex Vesker 		dr_matcher_uninit_fdb(matcher);
813852f660bSAlex Vesker 		break;
814852f660bSAlex Vesker 	default:
815852f660bSAlex Vesker 		WARN_ON(true);
816852f660bSAlex Vesker 		break;
817852f660bSAlex Vesker 	}
818852f660bSAlex Vesker }
819852f660bSAlex Vesker 
dr_matcher_set_all_ste_builders(struct mlx5dr_matcher * matcher,struct mlx5dr_matcher_rx_tx * nic_matcher)820667f2646SAlex Vesker static int dr_matcher_set_all_ste_builders(struct mlx5dr_matcher *matcher,
821852f660bSAlex Vesker 					   struct mlx5dr_matcher_rx_tx *nic_matcher)
822852f660bSAlex Vesker {
823852f660bSAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
824852f660bSAlex Vesker 
825667f2646SAlex Vesker 	dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV4, DR_RULE_IPV4);
826667f2646SAlex Vesker 	dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV4, DR_RULE_IPV6);
827667f2646SAlex Vesker 	dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV6, DR_RULE_IPV4);
828667f2646SAlex Vesker 	dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV6, DR_RULE_IPV6);
829852f660bSAlex Vesker 
830667f2646SAlex Vesker 	if (!nic_matcher->ste_builder) {
831b7d0db55SErez Shitrit 		mlx5dr_err(dmn, "Cannot generate IPv4 or IPv6 rules with given mask\n");
832852f660bSAlex Vesker 		return -EINVAL;
833852f660bSAlex Vesker 	}
834852f660bSAlex Vesker 
835667f2646SAlex Vesker 	return 0;
836667f2646SAlex Vesker }
837667f2646SAlex Vesker 
dr_matcher_init_nic(struct mlx5dr_matcher * matcher,struct mlx5dr_matcher_rx_tx * nic_matcher)838667f2646SAlex Vesker static int dr_matcher_init_nic(struct mlx5dr_matcher *matcher,
839667f2646SAlex Vesker 			       struct mlx5dr_matcher_rx_tx *nic_matcher)
840667f2646SAlex Vesker {
841667f2646SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
842667f2646SAlex Vesker 	int ret;
843667f2646SAlex Vesker 
844cc2295cdSYevgeny Kliteynik 	nic_matcher->prio = matcher->prio;
845cc2295cdSYevgeny Kliteynik 	INIT_LIST_HEAD(&nic_matcher->list_node);
846cc2295cdSYevgeny Kliteynik 
847667f2646SAlex Vesker 	ret = dr_matcher_set_all_ste_builders(matcher, nic_matcher);
848667f2646SAlex Vesker 	if (ret)
849667f2646SAlex Vesker 		return ret;
850852f660bSAlex Vesker 
851852f660bSAlex Vesker 	nic_matcher->e_anchor = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool,
852852f660bSAlex Vesker 						      DR_CHUNK_SIZE_1,
853852f660bSAlex Vesker 						      MLX5DR_STE_LU_TYPE_DONT_CARE,
854852f660bSAlex Vesker 						      0);
855852f660bSAlex Vesker 	if (!nic_matcher->e_anchor)
856852f660bSAlex Vesker 		return -ENOMEM;
857852f660bSAlex Vesker 
858852f660bSAlex Vesker 	nic_matcher->s_htbl = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool,
859852f660bSAlex Vesker 						    DR_CHUNK_SIZE_1,
860852f660bSAlex Vesker 						    nic_matcher->ste_builder[0].lu_type,
861852f660bSAlex Vesker 						    nic_matcher->ste_builder[0].byte_mask);
862852f660bSAlex Vesker 	if (!nic_matcher->s_htbl) {
863852f660bSAlex Vesker 		ret = -ENOMEM;
864852f660bSAlex Vesker 		goto free_e_htbl;
865852f660bSAlex Vesker 	}
866852f660bSAlex Vesker 
867852f660bSAlex Vesker 	/* make sure the tables exist while empty */
868852f660bSAlex Vesker 	mlx5dr_htbl_get(nic_matcher->s_htbl);
869852f660bSAlex Vesker 	mlx5dr_htbl_get(nic_matcher->e_anchor);
870852f660bSAlex Vesker 
871852f660bSAlex Vesker 	return 0;
872852f660bSAlex Vesker 
873852f660bSAlex Vesker free_e_htbl:
874852f660bSAlex Vesker 	mlx5dr_ste_htbl_free(nic_matcher->e_anchor);
875852f660bSAlex Vesker 	return ret;
876852f660bSAlex Vesker }
877852f660bSAlex Vesker 
dr_matcher_init_fdb(struct mlx5dr_matcher * matcher)878852f660bSAlex Vesker static int dr_matcher_init_fdb(struct mlx5dr_matcher *matcher)
879852f660bSAlex Vesker {
880852f660bSAlex Vesker 	int ret;
881852f660bSAlex Vesker 
882852f660bSAlex Vesker 	ret = dr_matcher_init_nic(matcher, &matcher->rx);
883852f660bSAlex Vesker 	if (ret)
884852f660bSAlex Vesker 		return ret;
885852f660bSAlex Vesker 
886852f660bSAlex Vesker 	ret = dr_matcher_init_nic(matcher, &matcher->tx);
887852f660bSAlex Vesker 	if (ret)
888852f660bSAlex Vesker 		goto uninit_nic_rx;
889852f660bSAlex Vesker 
890852f660bSAlex Vesker 	return 0;
891852f660bSAlex Vesker 
892852f660bSAlex Vesker uninit_nic_rx:
893852f660bSAlex Vesker 	dr_matcher_uninit_nic(&matcher->rx);
894852f660bSAlex Vesker 	return ret;
895852f660bSAlex Vesker }
896852f660bSAlex Vesker 
dr_matcher_copy_param(struct mlx5dr_matcher * matcher,struct mlx5dr_match_parameters * mask)89784dfac39SYevgeny Kliteynik static int dr_matcher_copy_param(struct mlx5dr_matcher *matcher,
898852f660bSAlex Vesker 				 struct mlx5dr_match_parameters *mask)
899852f660bSAlex Vesker {
90084dfac39SYevgeny Kliteynik 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
901941f1979SMuhammad Sammar 	struct mlx5dr_match_parameters consumed_mask;
90284dfac39SYevgeny Kliteynik 	int i, ret = 0;
903852f660bSAlex Vesker 
904852f660bSAlex Vesker 	if (matcher->match_criteria >= DR_MATCHER_CRITERIA_MAX) {
905b7d0db55SErez Shitrit 		mlx5dr_err(dmn, "Invalid match criteria attribute\n");
906852f660bSAlex Vesker 		return -EINVAL;
907852f660bSAlex Vesker 	}
908852f660bSAlex Vesker 
909852f660bSAlex Vesker 	if (mask) {
910699d531fSMuhammad Sammar 		if (mask->match_sz > DR_SZ_MATCH_PARAM) {
911b7d0db55SErez Shitrit 			mlx5dr_err(dmn, "Invalid match size attribute\n");
912852f660bSAlex Vesker 			return -EINVAL;
913852f660bSAlex Vesker 		}
914941f1979SMuhammad Sammar 
915941f1979SMuhammad Sammar 		consumed_mask.match_buf = kzalloc(mask->match_sz, GFP_KERNEL);
916941f1979SMuhammad Sammar 		if (!consumed_mask.match_buf)
917941f1979SMuhammad Sammar 			return -ENOMEM;
918941f1979SMuhammad Sammar 
919941f1979SMuhammad Sammar 		consumed_mask.match_sz = mask->match_sz;
920941f1979SMuhammad Sammar 		memcpy(consumed_mask.match_buf, mask->match_buf, mask->match_sz);
921852f660bSAlex Vesker 		mlx5dr_ste_copy_param(matcher->match_criteria,
92284dfac39SYevgeny Kliteynik 				      &matcher->mask, &consumed_mask, true);
92384dfac39SYevgeny Kliteynik 
92484dfac39SYevgeny Kliteynik 		/* Check that all mask data was consumed */
92584dfac39SYevgeny Kliteynik 		for (i = 0; i < consumed_mask.match_sz; i++) {
92684dfac39SYevgeny Kliteynik 			if (!((u8 *)consumed_mask.match_buf)[i])
92784dfac39SYevgeny Kliteynik 				continue;
92884dfac39SYevgeny Kliteynik 
92984dfac39SYevgeny Kliteynik 			mlx5dr_dbg(dmn,
93084dfac39SYevgeny Kliteynik 				   "Match param mask contains unsupported parameters\n");
93184dfac39SYevgeny Kliteynik 			ret = -EOPNOTSUPP;
93284dfac39SYevgeny Kliteynik 			break;
933852f660bSAlex Vesker 		}
934852f660bSAlex Vesker 
93584dfac39SYevgeny Kliteynik 		kfree(consumed_mask.match_buf);
93684dfac39SYevgeny Kliteynik 	}
93784dfac39SYevgeny Kliteynik 
93884dfac39SYevgeny Kliteynik 	return ret;
93984dfac39SYevgeny Kliteynik }
94084dfac39SYevgeny Kliteynik 
dr_matcher_init(struct mlx5dr_matcher * matcher,struct mlx5dr_match_parameters * mask)94184dfac39SYevgeny Kliteynik static int dr_matcher_init(struct mlx5dr_matcher *matcher,
94284dfac39SYevgeny Kliteynik 			   struct mlx5dr_match_parameters *mask)
94384dfac39SYevgeny Kliteynik {
94484dfac39SYevgeny Kliteynik 	struct mlx5dr_table *tbl = matcher->tbl;
94584dfac39SYevgeny Kliteynik 	struct mlx5dr_domain *dmn = tbl->dmn;
94684dfac39SYevgeny Kliteynik 	int ret;
94784dfac39SYevgeny Kliteynik 
94884dfac39SYevgeny Kliteynik 	ret = dr_matcher_copy_param(matcher, mask);
94984dfac39SYevgeny Kliteynik 	if (ret)
95084dfac39SYevgeny Kliteynik 		return ret;
95184dfac39SYevgeny Kliteynik 
952852f660bSAlex Vesker 	switch (dmn->type) {
953852f660bSAlex Vesker 	case MLX5DR_DOMAIN_TYPE_NIC_RX:
954852f660bSAlex Vesker 		matcher->rx.nic_tbl = &tbl->rx;
955852f660bSAlex Vesker 		ret = dr_matcher_init_nic(matcher, &matcher->rx);
956852f660bSAlex Vesker 		break;
957852f660bSAlex Vesker 	case MLX5DR_DOMAIN_TYPE_NIC_TX:
958852f660bSAlex Vesker 		matcher->tx.nic_tbl = &tbl->tx;
959852f660bSAlex Vesker 		ret = dr_matcher_init_nic(matcher, &matcher->tx);
960852f660bSAlex Vesker 		break;
961852f660bSAlex Vesker 	case MLX5DR_DOMAIN_TYPE_FDB:
962852f660bSAlex Vesker 		matcher->rx.nic_tbl = &tbl->rx;
963852f660bSAlex Vesker 		matcher->tx.nic_tbl = &tbl->tx;
964852f660bSAlex Vesker 		ret = dr_matcher_init_fdb(matcher);
965852f660bSAlex Vesker 		break;
966852f660bSAlex Vesker 	default:
967852f660bSAlex Vesker 		WARN_ON(true);
968941f1979SMuhammad Sammar 		ret = -EINVAL;
969852f660bSAlex Vesker 	}
970852f660bSAlex Vesker 
971852f660bSAlex Vesker 	return ret;
972852f660bSAlex Vesker }
973852f660bSAlex Vesker 
dr_matcher_add_to_dbg_list(struct mlx5dr_matcher * matcher)974cc2295cdSYevgeny Kliteynik static void dr_matcher_add_to_dbg_list(struct mlx5dr_matcher *matcher)
975cc2295cdSYevgeny Kliteynik {
976cc2295cdSYevgeny Kliteynik 	mutex_lock(&matcher->tbl->dmn->dump_info.dbg_mutex);
977cc2295cdSYevgeny Kliteynik 	list_add(&matcher->list_node, &matcher->tbl->matcher_list);
978cc2295cdSYevgeny Kliteynik 	mutex_unlock(&matcher->tbl->dmn->dump_info.dbg_mutex);
979cc2295cdSYevgeny Kliteynik }
980cc2295cdSYevgeny Kliteynik 
dr_matcher_remove_from_dbg_list(struct mlx5dr_matcher * matcher)981cc2295cdSYevgeny Kliteynik static void dr_matcher_remove_from_dbg_list(struct mlx5dr_matcher *matcher)
982cc2295cdSYevgeny Kliteynik {
983cc2295cdSYevgeny Kliteynik 	mutex_lock(&matcher->tbl->dmn->dump_info.dbg_mutex);
984cc2295cdSYevgeny Kliteynik 	list_del(&matcher->list_node);
985cc2295cdSYevgeny Kliteynik 	mutex_unlock(&matcher->tbl->dmn->dump_info.dbg_mutex);
986cc2295cdSYevgeny Kliteynik }
987cc2295cdSYevgeny Kliteynik 
988852f660bSAlex Vesker struct mlx5dr_matcher *
mlx5dr_matcher_create(struct mlx5dr_table * tbl,u32 priority,u8 match_criteria_enable,struct mlx5dr_match_parameters * mask)989852f660bSAlex Vesker mlx5dr_matcher_create(struct mlx5dr_table *tbl,
990f6409299SHamdan Igbaria 		      u32 priority,
991852f660bSAlex Vesker 		      u8 match_criteria_enable,
992852f660bSAlex Vesker 		      struct mlx5dr_match_parameters *mask)
993852f660bSAlex Vesker {
994852f660bSAlex Vesker 	struct mlx5dr_matcher *matcher;
995852f660bSAlex Vesker 	int ret;
996852f660bSAlex Vesker 
997852f660bSAlex Vesker 	refcount_inc(&tbl->refcount);
998852f660bSAlex Vesker 
999852f660bSAlex Vesker 	matcher = kzalloc(sizeof(*matcher), GFP_KERNEL);
1000852f660bSAlex Vesker 	if (!matcher)
1001852f660bSAlex Vesker 		goto dec_ref;
1002852f660bSAlex Vesker 
1003852f660bSAlex Vesker 	matcher->tbl = tbl;
1004852f660bSAlex Vesker 	matcher->prio = priority;
1005852f660bSAlex Vesker 	matcher->match_criteria = match_criteria_enable;
1006852f660bSAlex Vesker 	refcount_set(&matcher->refcount, 1);
100708fac109SYevgeny Kliteynik 	INIT_LIST_HEAD(&matcher->list_node);
10089222f0b2SMuhammad Sammar 	INIT_LIST_HEAD(&matcher->dbg_rule_list);
1009852f660bSAlex Vesker 
1010ed03a418SAlex Vesker 	mlx5dr_domain_lock(tbl->dmn);
1011852f660bSAlex Vesker 
1012852f660bSAlex Vesker 	ret = dr_matcher_init(matcher, mask);
1013852f660bSAlex Vesker 	if (ret)
1014852f660bSAlex Vesker 		goto free_matcher;
1015852f660bSAlex Vesker 
1016cc2295cdSYevgeny Kliteynik 	dr_matcher_add_to_dbg_list(matcher);
1017852f660bSAlex Vesker 
1018ed03a418SAlex Vesker 	mlx5dr_domain_unlock(tbl->dmn);
1019852f660bSAlex Vesker 
1020852f660bSAlex Vesker 	return matcher;
1021852f660bSAlex Vesker 
1022852f660bSAlex Vesker free_matcher:
1023ed03a418SAlex Vesker 	mlx5dr_domain_unlock(tbl->dmn);
1024852f660bSAlex Vesker 	kfree(matcher);
1025852f660bSAlex Vesker dec_ref:
1026852f660bSAlex Vesker 	refcount_dec(&tbl->refcount);
1027852f660bSAlex Vesker 	return NULL;
1028852f660bSAlex Vesker }
1029852f660bSAlex Vesker 
dr_matcher_disconnect_nic(struct mlx5dr_domain * dmn,struct mlx5dr_table_rx_tx * nic_tbl,struct mlx5dr_matcher_rx_tx * next_nic_matcher,struct mlx5dr_matcher_rx_tx * prev_nic_matcher)1030cc2295cdSYevgeny Kliteynik static int dr_matcher_disconnect_nic(struct mlx5dr_domain *dmn,
1031852f660bSAlex Vesker 				     struct mlx5dr_table_rx_tx *nic_tbl,
1032852f660bSAlex Vesker 				     struct mlx5dr_matcher_rx_tx *next_nic_matcher,
1033852f660bSAlex Vesker 				     struct mlx5dr_matcher_rx_tx *prev_nic_matcher)
1034852f660bSAlex Vesker {
1035852f660bSAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_tbl->nic_dmn;
1036852f660bSAlex Vesker 	struct mlx5dr_htbl_connect_info info;
1037852f660bSAlex Vesker 	struct mlx5dr_ste_htbl *prev_anchor;
1038852f660bSAlex Vesker 
1039852f660bSAlex Vesker 	if (prev_nic_matcher)
1040852f660bSAlex Vesker 		prev_anchor = prev_nic_matcher->e_anchor;
1041852f660bSAlex Vesker 	else
1042852f660bSAlex Vesker 		prev_anchor = nic_tbl->s_anchor;
1043852f660bSAlex Vesker 
1044852f660bSAlex Vesker 	/* Connect previous anchor hash table to next matcher or to the default address */
1045852f660bSAlex Vesker 	if (next_nic_matcher) {
1046852f660bSAlex Vesker 		info.type = CONNECT_HIT;
1047852f660bSAlex Vesker 		info.hit_next_htbl = next_nic_matcher->s_htbl;
1048*597534bdSRongwei Liu 		next_nic_matcher->s_htbl->pointing_ste = prev_anchor->chunk->ste_arr;
1049*597534bdSRongwei Liu 		prev_anchor->chunk->ste_arr[0].next_htbl = next_nic_matcher->s_htbl;
1050852f660bSAlex Vesker 	} else {
1051852f660bSAlex Vesker 		info.type = CONNECT_MISS;
1052852f660bSAlex Vesker 		info.miss_icm_addr = nic_tbl->default_icm_addr;
1053*597534bdSRongwei Liu 		prev_anchor->chunk->ste_arr[0].next_htbl = NULL;
1054852f660bSAlex Vesker 	}
1055852f660bSAlex Vesker 
1056852f660bSAlex Vesker 	return mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn, prev_anchor,
1057852f660bSAlex Vesker 						 &info, true);
1058852f660bSAlex Vesker }
1059852f660bSAlex Vesker 
mlx5dr_matcher_remove_from_tbl_nic(struct mlx5dr_domain * dmn,struct mlx5dr_matcher_rx_tx * nic_matcher)1060cc2295cdSYevgeny Kliteynik int mlx5dr_matcher_remove_from_tbl_nic(struct mlx5dr_domain *dmn,
1061cc2295cdSYevgeny Kliteynik 				       struct mlx5dr_matcher_rx_tx *nic_matcher)
1062852f660bSAlex Vesker {
1063cc2295cdSYevgeny Kliteynik 	struct mlx5dr_matcher_rx_tx *prev_nic_matcher, *next_nic_matcher;
1064cc2295cdSYevgeny Kliteynik 	struct mlx5dr_table_rx_tx *nic_tbl = nic_matcher->nic_tbl;
1065cc2295cdSYevgeny Kliteynik 	int ret;
1066852f660bSAlex Vesker 
1067cc2295cdSYevgeny Kliteynik 	/* If the nic matcher is not on its parent nic table list,
1068cc2295cdSYevgeny Kliteynik 	 * then it is detached - no need to disconnect it.
1069cc2295cdSYevgeny Kliteynik 	 */
1070cc2295cdSYevgeny Kliteynik 	if (list_empty(&nic_matcher->list_node))
1071cc2295cdSYevgeny Kliteynik 		return 0;
1072cc2295cdSYevgeny Kliteynik 
1073cc2295cdSYevgeny Kliteynik 	if (list_is_last(&nic_matcher->list_node, &nic_tbl->nic_matcher_list))
1074cc2295cdSYevgeny Kliteynik 		next_nic_matcher = NULL;
1075852f660bSAlex Vesker 	else
1076cc2295cdSYevgeny Kliteynik 		next_nic_matcher = list_next_entry(nic_matcher, list_node);
1077852f660bSAlex Vesker 
1078cc2295cdSYevgeny Kliteynik 	if (nic_matcher->list_node.prev == &nic_tbl->nic_matcher_list)
1079cc2295cdSYevgeny Kliteynik 		prev_nic_matcher = NULL;
1080852f660bSAlex Vesker 	else
1081cc2295cdSYevgeny Kliteynik 		prev_nic_matcher = list_prev_entry(nic_matcher, list_node);
1082852f660bSAlex Vesker 
1083cc2295cdSYevgeny Kliteynik 	ret = dr_matcher_disconnect_nic(dmn, nic_tbl, next_nic_matcher, prev_nic_matcher);
1084852f660bSAlex Vesker 	if (ret)
1085852f660bSAlex Vesker 		return ret;
1086852f660bSAlex Vesker 
1087cc2295cdSYevgeny Kliteynik 	list_del_init(&nic_matcher->list_node);
1088852f660bSAlex Vesker 	return 0;
1089852f660bSAlex Vesker }
1090852f660bSAlex Vesker 
mlx5dr_matcher_destroy(struct mlx5dr_matcher * matcher)1091852f660bSAlex Vesker int mlx5dr_matcher_destroy(struct mlx5dr_matcher *matcher)
1092852f660bSAlex Vesker {
1093852f660bSAlex Vesker 	struct mlx5dr_table *tbl = matcher->tbl;
1094852f660bSAlex Vesker 
1095b5412827SYevgeny Kliteynik 	if (WARN_ON_ONCE(refcount_read(&matcher->refcount) > 1))
1096852f660bSAlex Vesker 		return -EBUSY;
1097852f660bSAlex Vesker 
1098ed03a418SAlex Vesker 	mlx5dr_domain_lock(tbl->dmn);
1099852f660bSAlex Vesker 
1100cc2295cdSYevgeny Kliteynik 	dr_matcher_remove_from_dbg_list(matcher);
1101852f660bSAlex Vesker 	dr_matcher_uninit(matcher);
1102852f660bSAlex Vesker 	refcount_dec(&matcher->tbl->refcount);
1103852f660bSAlex Vesker 
1104ed03a418SAlex Vesker 	mlx5dr_domain_unlock(tbl->dmn);
1105852f660bSAlex Vesker 	kfree(matcher);
1106852f660bSAlex Vesker 
1107852f660bSAlex Vesker 	return 0;
1108852f660bSAlex Vesker }
1109