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