Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2022 NVIDIA Corporation & Affiliates
3 : : */
4 : :
5 : : #include "mlx5dr_internal.h"
6 : :
7 : : #define GTP_PDU_SC 0x85
8 : : #define BAD_PORT 0xBAD
9 : : #define ETH_TYPE_IPV4_VXLAN 0x0800
10 : : #define ETH_TYPE_IPV6_VXLAN 0x86DD
11 : : #define UDP_VXLAN_PORT 4789
12 : : #define UDP_VXLAN_GPE_PORT 4790
13 : : #define UDP_GTPU_PORT 2152
14 : : #define UDP_PORT_MPLS 6635
15 : : #define UDP_GENEVE_PORT 6081
16 : : #define UDP_ROCEV2_PORT 4791
17 : : #define DR_FLOW_LAYER_TUNNEL_NO_MPLS (MLX5_FLOW_LAYER_TUNNEL & ~MLX5_FLOW_LAYER_MPLS)
18 : :
19 : : #define STE_NO_VLAN 0x0
20 : : #define STE_SVLAN 0x1
21 : : #define STE_CVLAN 0x2
22 : : #define STE_NO_L3 0x0
23 : : #define STE_IPV4 0x1
24 : : #define STE_IPV6 0x2
25 : : #define STE_NO_L4 0x0
26 : : #define STE_TCP 0x1
27 : : #define STE_UDP 0x2
28 : : #define STE_ICMP 0x3
29 : : #define STE_NO_TUN 0x0
30 : : #define STE_ESP 0x3
31 : :
32 : : #define MLX5DR_DEFINER_QUOTA_BLOCK 0
33 : : #define MLX5DR_DEFINER_QUOTA_PASS 2
34 : :
35 : : /* Setter function based on bit offset and mask, for 32bit DW*/
36 : : #define _DR_SET_32(p, v, byte_off, bit_off, mask) \
37 : : do { \
38 : : u32 _v = v; \
39 : : *((rte_be32_t *)(p) + ((byte_off) / 4)) = \
40 : : rte_cpu_to_be_32((rte_be_to_cpu_32(*((u32 *)(p) + \
41 : : ((byte_off) / 4))) & \
42 : : (~((mask) << (bit_off)))) | \
43 : : (((_v) & (mask)) << \
44 : : (bit_off))); \
45 : : } while (0)
46 : :
47 : : /* Setter function based on bit offset and mask */
48 : : #define DR_SET(p, v, byte_off, bit_off, mask) \
49 : : do { \
50 : : if (unlikely((bit_off) < 0)) { \
51 : : u32 _bit_off = -1 * (bit_off); \
52 : : u32 second_dw_mask = (mask) & ((1 << _bit_off) - 1); \
53 : : _DR_SET_32(p, (v) >> _bit_off, byte_off, 0, (mask) >> _bit_off); \
54 : : _DR_SET_32(p, (v) & second_dw_mask, (byte_off) + DW_SIZE, \
55 : : (bit_off) % BITS_IN_DW, second_dw_mask); \
56 : : } else { \
57 : : _DR_SET_32(p, v, byte_off, (bit_off), (mask)); \
58 : : } \
59 : : } while (0)
60 : :
61 : : /* Setter function based on byte offset to directly set FULL BE32 value */
62 : : #define DR_SET_BE32(p, v, byte_off, bit_off, mask) \
63 : : (*((rte_be32_t *)((uint8_t *)(p) + (byte_off))) = (v))
64 : :
65 : : /* Setter function based on byte offset to directly set FULL BE32 value from ptr */
66 : : #define DR_SET_BE32P(p, v_ptr, byte_off, bit_off, mask) \
67 : : memcpy((uint8_t *)(p) + (byte_off), v_ptr, 4)
68 : :
69 : : /* Setter function based on byte offset to directly set FULL BE16 value */
70 : : #define DR_SET_BE16(p, v, byte_off, bit_off, mask) \
71 : : (*((rte_be16_t *)((uint8_t *)(p) + (byte_off))) = (v))
72 : :
73 : : /* Setter function based on byte offset to directly set FULL BE16 value from ptr */
74 : : #define DR_SET_BE16P(p, v_ptr, byte_off, bit_off, mask) \
75 : : memcpy((uint8_t *)(p) + (byte_off), v_ptr, 2)
76 : :
77 : : #define DR_CALC_FNAME(field, inner) \
78 : : ((inner) ? MLX5DR_DEFINER_FNAME_##field##_I : \
79 : : MLX5DR_DEFINER_FNAME_##field##_O)
80 : :
81 : : #define DR_CALC_SET_HDR(fc, hdr, field) \
82 : : do { \
83 : : (fc)->bit_mask = __mlx5_mask(definer_hl, hdr.field); \
84 : : (fc)->bit_off = __mlx5_dw_bit_off(definer_hl, hdr.field); \
85 : : (fc)->byte_off = MLX5_BYTE_OFF(definer_hl, hdr.field); \
86 : : } while (0)
87 : :
88 : : /* Helper to calculate data used by DR_SET */
89 : : #define DR_CALC_SET(fc, hdr, field, is_inner) \
90 : : do { \
91 : : if (is_inner) { \
92 : : DR_CALC_SET_HDR(fc, hdr##_inner, field); \
93 : : } else { \
94 : : DR_CALC_SET_HDR(fc, hdr##_outer, field); \
95 : : } \
96 : : } while (0)
97 : :
98 : : #define DR_GET(typ, p, fld) \
99 : : ((rte_be_to_cpu_32(*((const rte_be32_t *)(p) + \
100 : : __mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \
101 : : __mlx5_mask(typ, fld))
102 : :
103 : : struct mlx5dr_definer_sel_ctrl {
104 : : uint8_t allowed_full_dw; /* Full DW selectors cover all offsets */
105 : : uint8_t allowed_lim_dw; /* Limited DW selectors cover offset < 64 */
106 : : uint8_t allowed_bytes; /* Bytes selectors, up to offset 255 */
107 : : uint8_t used_full_dw;
108 : : uint8_t used_lim_dw;
109 : : uint8_t used_bytes;
110 : : uint8_t full_dw_selector[DW_SELECTORS];
111 : : uint8_t lim_dw_selector[DW_SELECTORS_LIMITED];
112 : : uint8_t byte_selector[BYTE_SELECTORS];
113 : : };
114 : :
115 : : struct mlx5dr_definer_conv_data {
116 : : struct mlx5dr_context *ctx;
117 : : struct mlx5dr_definer_fc *fc;
118 : : uint8_t relaxed;
119 : : uint8_t tunnel;
120 : : uint8_t mpls_idx;
121 : : uint8_t geneve_opt_ok_idx;
122 : : uint8_t geneve_opt_data_idx;
123 : : enum rte_flow_item_type last_item;
124 : : };
125 : :
126 : : /* Xmacro used to create generic item setter from items */
127 : : #define LIST_OF_FIELDS_INFO \
128 : : X(SET_BE16, eth_type, v->hdr.ether_type, rte_flow_item_eth) \
129 : : X(SET_BE32P, eth_smac_47_16, &v->hdr.src_addr.addr_bytes[0], rte_flow_item_eth) \
130 : : X(SET_BE16P, eth_smac_15_0, &v->hdr.src_addr.addr_bytes[4], rte_flow_item_eth) \
131 : : X(SET_BE32P, eth_dmac_47_16, &v->hdr.dst_addr.addr_bytes[0], rte_flow_item_eth) \
132 : : X(SET_BE16P, eth_dmac_15_0, &v->hdr.dst_addr.addr_bytes[4], rte_flow_item_eth) \
133 : : X(SET_BE16, tci, v->hdr.vlan_tci, rte_flow_item_vlan) \
134 : : X(SET, ipv4_ihl, v->ihl, rte_ipv4_hdr) \
135 : : X(SET, ipv4_tos, v->type_of_service, rte_ipv4_hdr) \
136 : : X(SET, ipv4_time_to_live, v->time_to_live, rte_ipv4_hdr) \
137 : : X(SET_BE32, ipv4_dst_addr, v->dst_addr, rte_ipv4_hdr) \
138 : : X(SET_BE32, ipv4_src_addr, v->src_addr, rte_ipv4_hdr) \
139 : : X(SET, ipv4_next_proto, v->next_proto_id, rte_ipv4_hdr) \
140 : : X(SET, ipv4_version, STE_IPV4, rte_ipv4_hdr) \
141 : : X(SET_BE16, ipv4_frag, v->fragment_offset, rte_ipv4_hdr) \
142 : : X(SET_BE16, ipv4_len, v->total_length, rte_ipv4_hdr) \
143 : : X(SET, ip_fragmented, !!v->fragment_offset, rte_ipv4_hdr) \
144 : : X(SET_BE16, ipv6_payload_len, v->hdr.payload_len, rte_flow_item_ipv6) \
145 : : X(SET, ipv6_proto, v->hdr.proto, rte_flow_item_ipv6) \
146 : : X(SET, ipv6_routing_hdr, IPPROTO_ROUTING, rte_flow_item_ipv6) \
147 : : X(SET, ipv6_hop_limits, v->hdr.hop_limits, rte_flow_item_ipv6) \
148 : : X(SET_BE32P, ipv6_src_addr_127_96, &v->hdr.src_addr[0], rte_flow_item_ipv6) \
149 : : X(SET_BE32P, ipv6_src_addr_95_64, &v->hdr.src_addr[4], rte_flow_item_ipv6) \
150 : : X(SET_BE32P, ipv6_src_addr_63_32, &v->hdr.src_addr[8], rte_flow_item_ipv6) \
151 : : X(SET_BE32P, ipv6_src_addr_31_0, &v->hdr.src_addr[12], rte_flow_item_ipv6) \
152 : : X(SET_BE32P, ipv6_dst_addr_127_96, &v->hdr.dst_addr[0], rte_flow_item_ipv6) \
153 : : X(SET_BE32P, ipv6_dst_addr_95_64, &v->hdr.dst_addr[4], rte_flow_item_ipv6) \
154 : : X(SET_BE32P, ipv6_dst_addr_63_32, &v->hdr.dst_addr[8], rte_flow_item_ipv6) \
155 : : X(SET_BE32P, ipv6_dst_addr_31_0, &v->hdr.dst_addr[12], rte_flow_item_ipv6) \
156 : : X(SET, ipv6_version, STE_IPV6, rte_flow_item_ipv6) \
157 : : X(SET, ipv6_frag, v->has_frag_ext, rte_flow_item_ipv6) \
158 : : X(SET, icmp_protocol, STE_ICMP, rte_flow_item_icmp) \
159 : : X(SET, udp_protocol, STE_UDP, rte_flow_item_udp) \
160 : : X(SET_BE16, udp_src_port, v->hdr.src_port, rte_flow_item_udp) \
161 : : X(SET_BE16, udp_dst_port, v->hdr.dst_port, rte_flow_item_udp) \
162 : : X(SET, tcp_flags, v->hdr.tcp_flags, rte_flow_item_tcp) \
163 : : X(SET, tcp_protocol, STE_TCP, rte_flow_item_tcp) \
164 : : X(SET_BE16, tcp_src_port, v->hdr.src_port, rte_flow_item_tcp) \
165 : : X(SET_BE16, tcp_dst_port, v->hdr.dst_port, rte_flow_item_tcp) \
166 : : X(SET, gtp_udp_port, UDP_GTPU_PORT, rte_flow_item_gtp) \
167 : : X(SET_BE32, gtp_teid, v->hdr.teid, rte_flow_item_gtp) \
168 : : X(SET, gtp_msg_type, v->hdr.msg_type, rte_flow_item_gtp) \
169 : : X(SET, gtp_ext_flag, !!v->hdr.gtp_hdr_info, rte_flow_item_gtp) \
170 : : X(SET, gtp_next_ext_hdr, GTP_PDU_SC, rte_flow_item_gtp_psc) \
171 : : X(SET, gtp_ext_hdr_pdu, v->hdr.type, rte_flow_item_gtp_psc) \
172 : : X(SET, gtp_ext_hdr_qfi, v->hdr.qfi, rte_flow_item_gtp_psc) \
173 : : X(SET, vxlan_flags, v->flags, rte_flow_item_vxlan) \
174 : : X(SET, vxlan_udp_port, UDP_VXLAN_PORT, rte_flow_item_vxlan) \
175 : : X(SET, vxlan_gpe_udp_port, UDP_VXLAN_GPE_PORT, rte_flow_item_vxlan_gpe) \
176 : : X(SET, vxlan_gpe_flags, v->flags, rte_flow_item_vxlan_gpe) \
177 : : X(SET, vxlan_gpe_protocol, v->protocol, rte_flow_item_vxlan_gpe) \
178 : : X(SET, vxlan_gpe_rsvd1, v->rsvd1, rte_flow_item_vxlan_gpe) \
179 : : X(SET, mpls_udp_port, UDP_PORT_MPLS, rte_flow_item_mpls) \
180 : : X(SET, source_qp, v->queue, mlx5_rte_flow_item_sq) \
181 : : X(SET, tag, v->data, rte_flow_item_tag) \
182 : : X(SET, metadata, v->data, rte_flow_item_meta) \
183 : : X(SET_BE16, geneve_protocol, v->protocol, rte_flow_item_geneve) \
184 : : X(SET, geneve_udp_port, UDP_GENEVE_PORT, rte_flow_item_geneve) \
185 : : X(SET_BE16, geneve_ctrl, v->ver_opt_len_o_c_rsvd0, rte_flow_item_geneve) \
186 : : X(SET_BE16, gre_c_ver, v->c_rsvd0_ver, rte_flow_item_gre) \
187 : : X(SET_BE16, gre_protocol_type, v->protocol, rte_flow_item_gre) \
188 : : X(SET, ipv4_protocol_gre, IPPROTO_GRE, rte_flow_item_gre) \
189 : : X(SET_BE32, gre_opt_key, v->key.key, rte_flow_item_gre_opt) \
190 : : X(SET_BE32, gre_opt_seq, v->sequence.sequence, rte_flow_item_gre_opt) \
191 : : X(SET_BE16, gre_opt_checksum, v->checksum_rsvd.checksum, rte_flow_item_gre_opt) \
192 : : X(SET, meter_color, rte_col_2_mlx5_col(v->color), rte_flow_item_meter_color) \
193 : : X(SET_BE32, ipsec_spi, v->hdr.spi, rte_flow_item_esp) \
194 : : X(SET_BE32, ipsec_sequence_number, v->hdr.seq, rte_flow_item_esp) \
195 : : X(SET, ib_l4_udp_port, UDP_ROCEV2_PORT, rte_flow_item_ib_bth) \
196 : : X(SET, ib_l4_opcode, v->hdr.opcode, rte_flow_item_ib_bth) \
197 : : X(SET, random_number, v->value, rte_flow_item_random) \
198 : : X(SET, ib_l4_bth_a, v->hdr.a, rte_flow_item_ib_bth) \
199 : :
200 : : /* Item set function format */
201 : : #define X(set_type, func_name, value, item_type) \
202 : : static void mlx5dr_definer_##func_name##_set( \
203 : : struct mlx5dr_definer_fc *fc, \
204 : : const void *item_spec, \
205 : : uint8_t *tag) \
206 : : { \
207 : : __rte_unused const struct item_type *v = item_spec; \
208 : : DR_##set_type(tag, value, fc->byte_off, fc->bit_off, fc->bit_mask); \
209 : : }
210 [ # # # # : 0 : LIST_OF_FIELDS_INFO
# # # # #
# # # #
# ]
211 : : #undef X
212 : :
213 : : static void
214 : 0 : mlx5dr_definer_ones_set(struct mlx5dr_definer_fc *fc,
215 : : __rte_unused const void *item_spec,
216 : : __rte_unused uint8_t *tag)
217 : : {
218 [ # # # # : 0 : DR_SET(tag, -1, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
219 : 0 : }
220 : :
221 : : static void
222 : 0 : mlx5dr_definer_eth_first_vlan_q_set(struct mlx5dr_definer_fc *fc,
223 : : const void *item_spec,
224 : : uint8_t *tag)
225 : : {
226 : : const struct rte_flow_item_eth *v = item_spec;
227 : : uint8_t vlan_type;
228 : :
229 : 0 : vlan_type = v->has_vlan ? STE_CVLAN : STE_NO_VLAN;
230 : :
231 [ # # # # : 0 : DR_SET(tag, vlan_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
232 : 0 : }
233 : :
234 : : static void
235 : 0 : mlx5dr_definer_first_vlan_q_set(struct mlx5dr_definer_fc *fc,
236 : : const void *item_spec,
237 : : uint8_t *tag)
238 : : {
239 : : const struct rte_flow_item_vlan *v = item_spec;
240 : : uint8_t vlan_type;
241 : :
242 [ # # ]: 0 : vlan_type = v->has_more_vlan ? STE_SVLAN : STE_CVLAN;
243 : :
244 [ # # # # : 0 : DR_SET(tag, vlan_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
245 : 0 : }
246 : :
247 : : static void
248 : 0 : mlx5dr_definer_conntrack_mask(struct mlx5dr_definer_fc *fc,
249 : : const void *item_spec,
250 : : uint8_t *tag)
251 : : {
252 : : const struct rte_flow_item_conntrack *m = item_spec;
253 : : uint32_t reg_mask = 0;
254 : :
255 [ # # ]: 0 : if (m->flags & (RTE_FLOW_CONNTRACK_PKT_STATE_VALID |
256 : : RTE_FLOW_CONNTRACK_PKT_STATE_INVALID |
257 : : RTE_FLOW_CONNTRACK_PKT_STATE_DISABLED))
258 : : reg_mask |= (MLX5_CT_SYNDROME_VALID | MLX5_CT_SYNDROME_INVALID |
259 : : MLX5_CT_SYNDROME_TRAP);
260 : :
261 [ # # ]: 0 : if (m->flags & RTE_FLOW_CONNTRACK_PKT_STATE_CHANGED)
262 : 0 : reg_mask |= MLX5_CT_SYNDROME_STATE_CHANGE;
263 : :
264 [ # # ]: 0 : if (m->flags & RTE_FLOW_CONNTRACK_PKT_STATE_BAD)
265 : 0 : reg_mask |= MLX5_CT_SYNDROME_BAD_PACKET;
266 : :
267 [ # # # # : 0 : DR_SET(tag, reg_mask, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
268 : 0 : }
269 : :
270 : : static void
271 : 0 : mlx5dr_definer_conntrack_tag(struct mlx5dr_definer_fc *fc,
272 : : const void *item_spec,
273 : : uint8_t *tag)
274 : : {
275 : : const struct rte_flow_item_conntrack *v = item_spec;
276 : : uint32_t reg_value = 0;
277 : :
278 : : /* The conflict should be checked in the validation. */
279 : 0 : if (v->flags & RTE_FLOW_CONNTRACK_PKT_STATE_VALID)
280 : : reg_value |= MLX5_CT_SYNDROME_VALID;
281 : :
282 [ # # ]: 0 : if (v->flags & RTE_FLOW_CONNTRACK_PKT_STATE_CHANGED)
283 : : reg_value |= MLX5_CT_SYNDROME_STATE_CHANGE;
284 : :
285 [ # # ]: 0 : if (v->flags & RTE_FLOW_CONNTRACK_PKT_STATE_INVALID)
286 : 0 : reg_value |= MLX5_CT_SYNDROME_INVALID;
287 : :
288 [ # # ]: 0 : if (v->flags & RTE_FLOW_CONNTRACK_PKT_STATE_DISABLED)
289 : 0 : reg_value |= MLX5_CT_SYNDROME_TRAP;
290 : :
291 [ # # ]: 0 : if (v->flags & RTE_FLOW_CONNTRACK_PKT_STATE_BAD)
292 : 0 : reg_value |= MLX5_CT_SYNDROME_BAD_PACKET;
293 : :
294 [ # # # # : 0 : DR_SET(tag, reg_value, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
295 : 0 : }
296 : :
297 : : static void
298 : 0 : mlx5dr_definer_ptype_l2_set(struct mlx5dr_definer_fc *fc,
299 : : const void *item_spec,
300 : : uint8_t *tag)
301 : : {
302 : 0 : bool inner = (fc->fname == MLX5DR_DEFINER_FNAME_PTYPE_L2_I);
303 : : const struct rte_flow_item_ptype *v = item_spec;
304 : 0 : uint32_t packet_type = v->packet_type &
305 [ # # ]: 0 : (inner ? RTE_PTYPE_INNER_L2_MASK : RTE_PTYPE_L2_MASK);
306 : : uint8_t l2_type = STE_NO_VLAN;
307 : :
308 [ # # # # ]: 0 : if (packet_type == (inner ? RTE_PTYPE_INNER_L2_ETHER : RTE_PTYPE_L2_ETHER))
309 : : l2_type = STE_NO_VLAN;
310 [ # # # # ]: 0 : else if (packet_type == (inner ? RTE_PTYPE_INNER_L2_ETHER_VLAN : RTE_PTYPE_L2_ETHER_VLAN))
311 : : l2_type = STE_CVLAN;
312 [ # # # # ]: 0 : else if (packet_type == (inner ? RTE_PTYPE_INNER_L2_ETHER_QINQ : RTE_PTYPE_L2_ETHER_QINQ))
313 : : l2_type = STE_SVLAN;
314 : :
315 [ # # # # : 0 : DR_SET(tag, l2_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
316 : 0 : }
317 : :
318 : : static void
319 : 0 : mlx5dr_definer_ptype_l3_set(struct mlx5dr_definer_fc *fc,
320 : : const void *item_spec,
321 : : uint8_t *tag)
322 : : {
323 : 0 : bool inner = (fc->fname == MLX5DR_DEFINER_FNAME_PTYPE_L3_I);
324 : : const struct rte_flow_item_ptype *v = item_spec;
325 : 0 : uint32_t packet_type = v->packet_type &
326 [ # # ]: 0 : (inner ? RTE_PTYPE_INNER_L3_MASK : RTE_PTYPE_L3_MASK);
327 : : uint8_t l3_type = STE_NO_L3;
328 : :
329 [ # # # # ]: 0 : if (packet_type == (inner ? RTE_PTYPE_INNER_L3_IPV4 : RTE_PTYPE_L3_IPV4))
330 : : l3_type = STE_IPV4;
331 [ # # # # ]: 0 : else if (packet_type == (inner ? RTE_PTYPE_INNER_L3_IPV6 : RTE_PTYPE_L3_IPV6))
332 : : l3_type = STE_IPV6;
333 : :
334 [ # # # # : 0 : DR_SET(tag, l3_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
335 : 0 : }
336 : :
337 : : static void
338 : 0 : mlx5dr_definer_ptype_l4_set(struct mlx5dr_definer_fc *fc,
339 : : const void *item_spec,
340 : : uint8_t *tag)
341 : : {
342 : 0 : bool inner = (fc->fname == MLX5DR_DEFINER_FNAME_PTYPE_L4_I);
343 : : const struct rte_flow_item_ptype *v = item_spec;
344 : 0 : uint32_t packet_type = v->packet_type &
345 [ # # ]: 0 : (inner ? RTE_PTYPE_INNER_L4_MASK : RTE_PTYPE_L4_MASK);
346 : : uint8_t l4_type = STE_NO_L4;
347 : :
348 [ # # # # ]: 0 : if (packet_type == (inner ? RTE_PTYPE_INNER_L4_TCP : RTE_PTYPE_L4_TCP))
349 : : l4_type = STE_TCP;
350 [ # # # # ]: 0 : else if (packet_type == (inner ? RTE_PTYPE_INNER_L4_UDP : RTE_PTYPE_L4_UDP))
351 : : l4_type = STE_UDP;
352 [ # # # # ]: 0 : else if (packet_type == (inner ? RTE_PTYPE_INNER_L4_ICMP : RTE_PTYPE_L4_ICMP))
353 : : l4_type = STE_ICMP;
354 : :
355 [ # # # # : 0 : DR_SET(tag, l4_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
356 : 0 : }
357 : :
358 : : static void
359 : 0 : mlx5dr_definer_ptype_tunnel_set(struct mlx5dr_definer_fc *fc,
360 : : const void *item_spec,
361 : : uint8_t *tag)
362 : : {
363 : : const struct rte_flow_item_ptype *v = item_spec;
364 : 0 : uint32_t packet_type = v->packet_type & RTE_PTYPE_TUNNEL_MASK;
365 : : uint8_t tun_type = STE_NO_TUN;
366 : :
367 [ # # ]: 0 : if (packet_type == RTE_PTYPE_TUNNEL_ESP)
368 : : tun_type = STE_ESP;
369 : :
370 [ # # # # : 0 : DR_SET(tag, tun_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
371 : 0 : }
372 : :
373 : : static void
374 : 0 : mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc,
375 : : const void *item_spec,
376 : : uint8_t *tag)
377 : : {
378 : 0 : bool inner = (fc->fname == MLX5DR_DEFINER_FNAME_PTYPE_FRAG_I);
379 : : const struct rte_flow_item_ptype *v = item_spec;
380 : 0 : uint32_t packet_type = v->packet_type &
381 [ # # ]: 0 : (inner ? RTE_PTYPE_INNER_L4_FRAG : RTE_PTYPE_L4_FRAG);
382 : :
383 [ # # # # : 0 : DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
384 : 0 : }
385 : :
386 : : static void
387 : 0 : mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc,
388 : : const void *item_spec,
389 : : uint8_t *tag)
390 : : {
391 : 0 : bool inner = (fc->fname == MLX5DR_DEFINER_FNAME_INTEGRITY_I);
392 : : const struct rte_flow_item_integrity *v = item_spec;
393 : : uint32_t ok1_bits = 0;
394 : :
395 [ # # ]: 0 : if (v->l3_ok)
396 [ # # ]: 0 : ok1_bits |= inner ? BIT(MLX5DR_DEFINER_OKS1_SECOND_L3_OK) :
397 : : BIT(MLX5DR_DEFINER_OKS1_FIRST_L3_OK);
398 : :
399 [ # # ]: 0 : if (v->ipv4_csum_ok)
400 [ # # ]: 0 : ok1_bits |= inner ? BIT(MLX5DR_DEFINER_OKS1_SECOND_IPV4_CSUM_OK) :
401 : : BIT(MLX5DR_DEFINER_OKS1_FIRST_IPV4_CSUM_OK);
402 : :
403 [ # # ]: 0 : if (v->l4_ok)
404 [ # # ]: 0 : ok1_bits |= inner ? BIT(MLX5DR_DEFINER_OKS1_SECOND_L4_OK) |
405 : : BIT(MLX5DR_DEFINER_OKS1_SECOND_L4_CSUM_OK) :
406 : : BIT(MLX5DR_DEFINER_OKS1_FIRST_L4_OK) |
407 : : BIT(MLX5DR_DEFINER_OKS1_FIRST_L4_CSUM_OK);
408 : :
409 [ # # ]: 0 : if (v->l4_csum_ok)
410 [ # # ]: 0 : ok1_bits |= inner ? BIT(MLX5DR_DEFINER_OKS1_SECOND_L4_CSUM_OK) :
411 : : BIT(MLX5DR_DEFINER_OKS1_FIRST_L4_CSUM_OK);
412 : :
413 [ # # # # : 0 : DR_SET(tag, ok1_bits, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
414 : 0 : }
415 : :
416 : : static void
417 : 0 : mlx5dr_definer_ipv6_routing_ext_set(struct mlx5dr_definer_fc *fc,
418 : : const void *item,
419 : : uint8_t *tag)
420 : : {
421 : : const struct rte_flow_item_ipv6_routing_ext *v = item;
422 : : uint32_t val;
423 : :
424 : 0 : val = v->hdr.next_hdr << __mlx5_dw_bit_off(header_ipv6_routing_ext, next_hdr);
425 : 0 : val |= v->hdr.type << __mlx5_dw_bit_off(header_ipv6_routing_ext, type);
426 : 0 : val |= v->hdr.segments_left <<
427 : : __mlx5_dw_bit_off(header_ipv6_routing_ext, segments_left);
428 [ # # ]: 0 : DR_SET(tag, val, fc->byte_off, 0, fc->bit_mask);
429 : 0 : }
430 : :
431 : : static void
432 : 0 : mlx5dr_definer_flex_parser_set(struct mlx5dr_definer_fc *fc,
433 : : const void *item,
434 : : uint8_t *tag, bool is_inner)
435 : : {
436 : : const struct rte_flow_item_flex *flex = item;
437 : : uint32_t byte_off, val, idx;
438 : : int ret;
439 : :
440 : 0 : val = 0;
441 : : byte_off = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_0);
442 : 0 : idx = fc->fname - MLX5DR_DEFINER_FNAME_FLEX_PARSER_0;
443 : 0 : byte_off -= idx * sizeof(uint32_t);
444 : 0 : ret = mlx5_flex_get_parser_value_per_byte_off(flex, flex->handle, byte_off,
445 : : false, is_inner, &val);
446 [ # # # # ]: 0 : if (ret == -1 || !val)
447 : 0 : return;
448 : :
449 [ # # ]: 0 : DR_SET(tag, val, fc->byte_off, 0, fc->bit_mask);
450 : : }
451 : :
452 : : static void
453 : 0 : mlx5dr_definer_flex_parser_inner_set(struct mlx5dr_definer_fc *fc,
454 : : const void *item,
455 : : uint8_t *tag)
456 : : {
457 : 0 : mlx5dr_definer_flex_parser_set(fc, item, tag, true);
458 : 0 : }
459 : :
460 : : static void
461 : 0 : mlx5dr_definer_flex_parser_outer_set(struct mlx5dr_definer_fc *fc,
462 : : const void *item,
463 : : uint8_t *tag)
464 : : {
465 : 0 : mlx5dr_definer_flex_parser_set(fc, item, tag, false);
466 : 0 : }
467 : :
468 : : static void
469 : 0 : mlx5dr_definer_gre_key_set(struct mlx5dr_definer_fc *fc,
470 : : const void *item_spec,
471 : : uint8_t *tag)
472 : : {
473 : : const rte_be32_t *v = item_spec;
474 : :
475 : 0 : DR_SET_BE32(tag, *v, fc->byte_off, fc->bit_off, fc->bit_mask);
476 : 0 : }
477 : :
478 : : static void
479 : 0 : mlx5dr_definer_vxlan_vni_set(struct mlx5dr_definer_fc *fc,
480 : : const void *item_spec,
481 : : uint8_t *tag)
482 : : {
483 : : const struct rte_flow_item_vxlan *v = item_spec;
484 : :
485 : 0 : memcpy(tag + fc->byte_off, v->vni, sizeof(v->vni));
486 : 0 : }
487 : :
488 : : static void
489 : 0 : mlx5dr_definer_ipv6_tos_set(struct mlx5dr_definer_fc *fc,
490 : : const void *item_spec,
491 : : uint8_t *tag)
492 : : {
493 : : const struct rte_flow_item_ipv6 *v = item_spec;
494 [ # # ]: 0 : uint8_t tos = DR_GET(header_ipv6_vtc, &v->hdr.vtc_flow, tos);
495 : :
496 [ # # # # : 0 : DR_SET(tag, tos, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
497 : 0 : }
498 : :
499 : : static void
500 : 0 : mlx5dr_definer_icmp_dw1_set(struct mlx5dr_definer_fc *fc,
501 : : const void *item_spec,
502 : : uint8_t *tag)
503 : : {
504 : : const struct rte_flow_item_icmp *v = item_spec;
505 : : rte_be32_t icmp_dw1;
506 : :
507 : 0 : icmp_dw1 = (v->hdr.icmp_type << __mlx5_dw_bit_off(header_icmp, type)) |
508 : 0 : (v->hdr.icmp_code << __mlx5_dw_bit_off(header_icmp, code)) |
509 [ # # ]: 0 : (rte_be_to_cpu_16(v->hdr.icmp_cksum) << __mlx5_dw_bit_off(header_icmp, cksum));
510 : :
511 [ # # # # : 0 : DR_SET(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
512 : 0 : }
513 : :
514 : : static void
515 : 0 : mlx5dr_definer_icmp_dw2_set(struct mlx5dr_definer_fc *fc,
516 : : const void *item_spec,
517 : : uint8_t *tag)
518 : : {
519 : : const struct rte_flow_item_icmp *v = item_spec;
520 : : rte_be32_t icmp_dw2;
521 : :
522 [ # # ]: 0 : icmp_dw2 = (rte_be_to_cpu_16(v->hdr.icmp_ident) << __mlx5_dw_bit_off(header_icmp, ident)) |
523 [ # # ]: 0 : (rte_be_to_cpu_16(v->hdr.icmp_seq_nb) << __mlx5_dw_bit_off(header_icmp, seq_nb));
524 : :
525 [ # # # # : 0 : DR_SET(tag, icmp_dw2, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
526 : 0 : }
527 : :
528 : : static void
529 : 0 : mlx5dr_definer_icmp6_dw1_set(struct mlx5dr_definer_fc *fc,
530 : : const void *item_spec,
531 : : uint8_t *tag)
532 : : {
533 : : const struct rte_flow_item_icmp6 *v = item_spec;
534 : : rte_be32_t icmp_dw1;
535 : :
536 : 0 : icmp_dw1 = (v->type << __mlx5_dw_bit_off(header_icmp, type)) |
537 : 0 : (v->code << __mlx5_dw_bit_off(header_icmp, code)) |
538 [ # # ]: 0 : (rte_be_to_cpu_16(v->checksum) << __mlx5_dw_bit_off(header_icmp, cksum));
539 : :
540 [ # # # # : 0 : DR_SET(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
541 : 0 : }
542 : :
543 : : static void
544 : 0 : mlx5dr_definer_icmp6_echo_dw1_mask_set(struct mlx5dr_definer_fc *fc,
545 : : __rte_unused const void *item_spec,
546 : : uint8_t *tag)
547 : : {
548 : 0 : const struct rte_flow_item_icmp6 spec = {0xFF, 0xFF, 0x0};
549 : 0 : mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag);
550 : 0 : }
551 : :
552 : : static void
553 : 0 : mlx5dr_definer_icmp6_echo_request_dw1_set(struct mlx5dr_definer_fc *fc,
554 : : __rte_unused const void *item_spec,
555 : : uint8_t *tag)
556 : : {
557 : 0 : const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REQUEST, 0, 0};
558 : 0 : mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag);
559 : 0 : }
560 : :
561 : : static void
562 : 0 : mlx5dr_definer_icmp6_echo_reply_dw1_set(struct mlx5dr_definer_fc *fc,
563 : : __rte_unused const void *item_spec,
564 : : uint8_t *tag)
565 : : {
566 : 0 : const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REPLY, 0, 0};
567 : 0 : mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag);
568 : 0 : }
569 : :
570 : : static void
571 : 0 : mlx5dr_definer_icmp6_echo_dw2_set(struct mlx5dr_definer_fc *fc,
572 : : const void *item_spec,
573 : : uint8_t *tag)
574 : : {
575 : : const struct rte_flow_item_icmp6_echo *v = item_spec;
576 : : rte_be32_t dw2;
577 : :
578 [ # # ]: 0 : dw2 = (rte_be_to_cpu_16(v->hdr.identifier) << __mlx5_dw_bit_off(header_icmp, ident)) |
579 [ # # ]: 0 : (rte_be_to_cpu_16(v->hdr.sequence) << __mlx5_dw_bit_off(header_icmp, seq_nb));
580 : :
581 [ # # # # : 0 : DR_SET(tag, dw2, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
582 : 0 : }
583 : :
584 : : static void
585 : 0 : mlx5dr_definer_ipv6_flow_label_set(struct mlx5dr_definer_fc *fc,
586 : : const void *item_spec,
587 : : uint8_t *tag)
588 : : {
589 : : const struct rte_flow_item_ipv6 *v = item_spec;
590 [ # # ]: 0 : uint32_t flow_label = DR_GET(header_ipv6_vtc, &v->hdr.vtc_flow, flow_label);
591 : :
592 [ # # # # : 0 : DR_SET(tag, flow_label, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
593 : 0 : }
594 : :
595 : : static void
596 : 0 : mlx5dr_definer_vport_set(struct mlx5dr_definer_fc *fc,
597 : : const void *item_spec,
598 : : uint8_t *tag)
599 : : {
600 : : const struct rte_flow_item_ethdev *v = item_spec;
601 : : const struct flow_hw_port_info *port_info;
602 : : uint32_t regc_value;
603 : :
604 [ # # ]: 0 : port_info = flow_hw_conv_port_id(v->port_id);
605 [ # # ]: 0 : if (unlikely(!port_info))
606 : : regc_value = BAD_PORT;
607 : : else
608 : 0 : regc_value = port_info->regc_value >> fc->bit_off;
609 : :
610 : : /* Bit offset is set to 0 to since regc value is 32bit */
611 [ # # # # : 0 : DR_SET(tag, regc_value, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
612 : 0 : }
613 : :
614 : : static struct mlx5dr_definer_fc *
615 : 0 : mlx5dr_definer_get_mpls_fc(struct mlx5dr_definer_conv_data *cd, bool inner)
616 : : {
617 : 0 : uint8_t mpls_idx = cd->mpls_idx;
618 : : struct mlx5dr_definer_fc *fc;
619 : :
620 [ # # # # : 0 : switch (mpls_idx) {
# # ]
621 : 0 : case 0:
622 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(MPLS0, inner)];
623 : 0 : DR_CALC_SET_HDR(fc, mpls_inner, mpls0_label);
624 : 0 : break;
625 : 0 : case 1:
626 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(MPLS1, inner)];
627 : 0 : DR_CALC_SET_HDR(fc, mpls_inner, mpls1_label);
628 : 0 : break;
629 : 0 : case 2:
630 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(MPLS2, inner)];
631 : 0 : DR_CALC_SET_HDR(fc, mpls_inner, mpls2_label);
632 : 0 : break;
633 : 0 : case 3:
634 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(MPLS3, inner)];
635 : 0 : DR_CALC_SET_HDR(fc, mpls_inner, mpls3_label);
636 : 0 : break;
637 : 0 : case 4:
638 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(MPLS4, inner)];
639 : 0 : DR_CALC_SET_HDR(fc, mpls_inner, mpls4_label);
640 : 0 : break;
641 : 0 : default:
642 : 0 : rte_errno = ENOTSUP;
643 : 0 : DR_LOG(ERR, "MPLS index %d is not supported", mpls_idx);
644 : 0 : return NULL;
645 : : }
646 : :
647 : : return fc;
648 : : }
649 : :
650 : : static struct mlx5dr_definer_fc *
651 : 0 : mlx5dr_definer_get_mpls_oks_fc(struct mlx5dr_definer_conv_data *cd, bool inner)
652 : : {
653 : 0 : uint8_t mpls_idx = cd->mpls_idx;
654 : : struct mlx5dr_definer_fc *fc;
655 : :
656 [ # # # # : 0 : switch (mpls_idx) {
# # ]
657 : 0 : case 0:
658 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(OKS2_MPLS0, inner)];
659 : 0 : DR_CALC_SET_HDR(fc, oks2, second_mpls0_qualifier);
660 : 0 : break;
661 : 0 : case 1:
662 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(OKS2_MPLS1, inner)];
663 : 0 : DR_CALC_SET_HDR(fc, oks2, second_mpls1_qualifier);
664 : 0 : break;
665 : 0 : case 2:
666 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(OKS2_MPLS2, inner)];
667 : 0 : DR_CALC_SET_HDR(fc, oks2, second_mpls2_qualifier);
668 : 0 : break;
669 : 0 : case 3:
670 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(OKS2_MPLS3, inner)];
671 : 0 : DR_CALC_SET_HDR(fc, oks2, second_mpls3_qualifier);
672 : 0 : break;
673 : 0 : case 4:
674 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(OKS2_MPLS4, inner)];
675 : 0 : DR_CALC_SET_HDR(fc, oks2, second_mpls4_qualifier);
676 : 0 : break;
677 : 0 : default:
678 : 0 : rte_errno = ENOTSUP;
679 : 0 : DR_LOG(ERR, "MPLS index %d is not supported", mpls_idx);
680 : 0 : return NULL;
681 : : }
682 : :
683 : : return fc;
684 : : }
685 : :
686 : : static void
687 : 0 : mlx5dr_definer_mpls_label_set(struct mlx5dr_definer_fc *fc,
688 : : const void *item_spec,
689 : : uint8_t *tag)
690 : : {
691 : : const struct rte_flow_item_mpls *v = item_spec;
692 : :
693 : 0 : memcpy(tag + fc->byte_off, v->label_tc_s, sizeof(v->label_tc_s));
694 : 0 : memcpy(tag + fc->byte_off + sizeof(v->label_tc_s), &v->ttl, sizeof(v->ttl));
695 : 0 : }
696 : :
697 : : static void
698 : 0 : mlx5dr_definer_geneve_vni_set(struct mlx5dr_definer_fc *fc,
699 : : const void *item_spec,
700 : : uint8_t *tag)
701 : : {
702 : : const struct rte_flow_item_geneve *v = item_spec;
703 : :
704 : 0 : memcpy(tag + fc->byte_off, v->vni, sizeof(v->vni));
705 : 0 : }
706 : :
707 : : static void
708 : 0 : mlx5dr_definer_geneve_opt_ctrl_set(struct mlx5dr_definer_fc *fc,
709 : : const void *item_spec,
710 : : uint8_t *tag)
711 : : {
712 : : const struct rte_flow_item_geneve_opt *v = item_spec;
713 : : uint32_t dw0 = 0;
714 : :
715 : 0 : dw0 |= v->option_type << __mlx5_dw_bit_off(header_geneve_opt, type);
716 [ # # ]: 0 : dw0 |= rte_cpu_to_be_16(v->option_class) << __mlx5_dw_bit_off(header_geneve_opt, class);
717 [ # # # # : 0 : DR_SET(tag, dw0, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
718 : 0 : }
719 : :
720 : : static void
721 : 0 : mlx5dr_definer_geneve_opt_data_set(struct mlx5dr_definer_fc *fc,
722 : : const void *item_spec,
723 : : uint8_t *tag)
724 : : {
725 : : const struct rte_flow_item_geneve_opt *v = item_spec;
726 : :
727 : 0 : DR_SET_BE32(tag, v->data[fc->extra_data], fc->byte_off, fc->bit_off, fc->bit_mask);
728 : 0 : }
729 : :
730 : : static void
731 : 0 : mlx5dr_definer_ib_l4_qp_set(struct mlx5dr_definer_fc *fc,
732 : : const void *item_spec,
733 : : uint8_t *tag)
734 : : {
735 : : const struct rte_flow_item_ib_bth *v = item_spec;
736 : :
737 : 0 : memcpy(tag + fc->byte_off, &v->hdr.dst_qp, sizeof(v->hdr.dst_qp));
738 : 0 : }
739 : :
740 : : static void
741 : 0 : mlx5dr_definer_vxlan_gpe_vni_set(struct mlx5dr_definer_fc *fc,
742 : : const void *item_spec,
743 : : uint8_t *tag)
744 : : {
745 : : const struct rte_flow_item_vxlan_gpe *v = item_spec;
746 : :
747 : 0 : memcpy(tag + fc->byte_off, v->vni, sizeof(v->vni));
748 : 0 : }
749 : :
750 : : static void
751 : 0 : mlx5dr_definer_vxlan_gpe_rsvd0_set(struct mlx5dr_definer_fc *fc,
752 : : const void *item_spec,
753 : : uint8_t *tag)
754 : : {
755 : : const struct rte_flow_item_vxlan_gpe *v = item_spec;
756 : : uint16_t rsvd0;
757 : :
758 : 0 : rsvd0 = (v->rsvd0[0] << 8 | v->rsvd0[1]);
759 [ # # # # : 0 : DR_SET(tag, rsvd0, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
760 : 0 : }
761 : :
762 : : static int
763 : 0 : mlx5dr_definer_conv_item_eth(struct mlx5dr_definer_conv_data *cd,
764 : : struct rte_flow_item *item,
765 : : int item_idx)
766 : : {
767 : 0 : const struct rte_flow_item_eth *m = item->mask;
768 : 0 : uint8_t empty_mac[RTE_ETHER_ADDR_LEN] = {0};
769 : : struct mlx5dr_definer_fc *fc;
770 : 0 : bool inner = cd->tunnel;
771 : :
772 [ # # ]: 0 : if (!m)
773 : : return 0;
774 : :
775 [ # # ]: 0 : if (m->reserved) {
776 : 0 : rte_errno = ENOTSUP;
777 : 0 : return rte_errno;
778 : : }
779 : :
780 [ # # ]: 0 : if (m->hdr.ether_type) {
781 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)];
782 : 0 : fc->item_idx = item_idx;
783 : 0 : fc->tag_set = &mlx5dr_definer_eth_type_set;
784 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_ethertype, inner);
785 : : }
786 : :
787 : : /* Check SMAC 47_16 */
788 [ # # ]: 0 : if (memcmp(m->hdr.src_addr.addr_bytes, empty_mac, 4)) {
789 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(ETH_SMAC_48_16, inner)];
790 : 0 : fc->item_idx = item_idx;
791 : 0 : fc->tag_set = &mlx5dr_definer_eth_smac_47_16_set;
792 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2_src, smac_47_16, inner);
793 : : }
794 : :
795 : : /* Check SMAC 15_0 */
796 [ # # ]: 0 : if (memcmp(m->hdr.src_addr.addr_bytes + 4, empty_mac + 4, 2)) {
797 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(ETH_SMAC_15_0, inner)];
798 : 0 : fc->item_idx = item_idx;
799 : 0 : fc->tag_set = &mlx5dr_definer_eth_smac_15_0_set;
800 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2_src, smac_15_0, inner);
801 : : }
802 : :
803 : : /* Check DMAC 47_16 */
804 [ # # ]: 0 : if (memcmp(m->hdr.dst_addr.addr_bytes, empty_mac, 4)) {
805 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(ETH_DMAC_48_16, inner)];
806 : 0 : fc->item_idx = item_idx;
807 : 0 : fc->tag_set = &mlx5dr_definer_eth_dmac_47_16_set;
808 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, dmac_47_16, inner);
809 : : }
810 : :
811 : : /* Check DMAC 15_0 */
812 [ # # ]: 0 : if (memcmp(m->hdr.dst_addr.addr_bytes + 4, empty_mac + 4, 2)) {
813 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(ETH_DMAC_15_0, inner)];
814 : 0 : fc->item_idx = item_idx;
815 : 0 : fc->tag_set = &mlx5dr_definer_eth_dmac_15_0_set;
816 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, dmac_15_0, inner);
817 : : }
818 : :
819 [ # # ]: 0 : if (m->has_vlan) {
820 : : /* Mark packet as tagged (CVLAN) */
821 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(VLAN_TYPE, inner)];
822 : 0 : fc->item_idx = item_idx;
823 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
824 : 0 : fc->tag_set = &mlx5dr_definer_eth_first_vlan_q_set;
825 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, first_vlan_qualifier, inner);
826 : : }
827 : :
828 : : return 0;
829 : : }
830 : :
831 : : static int
832 : 0 : mlx5dr_definer_conv_item_vlan(struct mlx5dr_definer_conv_data *cd,
833 : : struct rte_flow_item *item,
834 : : int item_idx)
835 : : {
836 : 0 : const struct rte_flow_item_vlan *m = item->mask;
837 : : struct mlx5dr_definer_fc *fc;
838 : 0 : bool inner = cd->tunnel;
839 : :
840 [ # # ]: 0 : if (!m)
841 : : return 0;
842 : :
843 [ # # ]: 0 : if (m->reserved) {
844 : 0 : rte_errno = ENOTSUP;
845 : 0 : return rte_errno;
846 : : }
847 : :
848 [ # # # # ]: 0 : if (!cd->relaxed || m->has_more_vlan) {
849 : : /* Mark packet as tagged (CVLAN or SVLAN) even if TCI is not specified.*/
850 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(VLAN_TYPE, inner)];
851 : 0 : fc->item_idx = item_idx;
852 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
853 : 0 : fc->tag_set = &mlx5dr_definer_first_vlan_q_set;
854 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, first_vlan_qualifier, inner);
855 : : }
856 : :
857 [ # # ]: 0 : if (m->hdr.vlan_tci) {
858 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(VLAN_TCI, inner)];
859 : 0 : fc->item_idx = item_idx;
860 : 0 : fc->tag_set = &mlx5dr_definer_tci_set;
861 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, tci, inner);
862 : : }
863 : :
864 [ # # ]: 0 : if (m->hdr.eth_proto) {
865 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)];
866 : 0 : fc->item_idx = item_idx;
867 : 0 : fc->tag_set = &mlx5dr_definer_eth_type_set;
868 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_ethertype, inner);
869 : : }
870 : :
871 : : return 0;
872 : : }
873 : :
874 : : static int
875 : 0 : mlx5dr_definer_conv_item_ipv4(struct mlx5dr_definer_conv_data *cd,
876 : : struct rte_flow_item *item,
877 : : int item_idx)
878 : : {
879 : 0 : const struct rte_ipv4_hdr *m = item->mask;
880 : 0 : const struct rte_ipv4_hdr *l = item->last;
881 : : struct mlx5dr_definer_fc *fc;
882 : 0 : bool inner = cd->tunnel;
883 : :
884 [ # # ]: 0 : if (!cd->relaxed) {
885 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
886 : 0 : fc->item_idx = item_idx;
887 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_version_set;
888 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
889 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_type, inner);
890 : :
891 : : /* Overwrite - Unset ethertype if present */
892 [ # # ]: 0 : memset(&cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)], 0, sizeof(*fc));
893 : : }
894 : :
895 [ # # ]: 0 : if (!m)
896 : : return 0;
897 : :
898 [ # # # # : 0 : if (m->packet_id || m->hdr_checksum ||
# # ]
899 [ # # # # ]: 0 : (l && (l->next_proto_id || l->type_of_service))) {
900 : 0 : rte_errno = ENOTSUP;
901 : 0 : return rte_errno;
902 : : }
903 : :
904 [ # # ]: 0 : if (m->version) {
905 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
906 : 0 : fc->item_idx = item_idx;
907 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_version_set;
908 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
909 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_type, inner);
910 : : }
911 : :
912 [ # # ]: 0 : if (m->fragment_offset) {
913 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_FRAG, inner)];
914 : 0 : fc->item_idx = item_idx;
915 [ # # # # ]: 0 : if (rte_be_to_cpu_16(m->fragment_offset) == 0x3fff) {
916 : 0 : fc->tag_set = &mlx5dr_definer_ip_fragmented_set;
917 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, ip_fragmented, inner);
918 : : } else {
919 [ # # # # ]: 0 : fc->is_range = l && l->fragment_offset;
920 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_frag_set;
921 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, ipv4_frag, inner);
922 : : }
923 : : }
924 : :
925 [ # # ]: 0 : if (m->next_proto_id) {
926 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
927 : 0 : fc->item_idx = item_idx;
928 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_next_proto_set;
929 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
930 : : }
931 : :
932 [ # # ]: 0 : if (m->total_length) {
933 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_LEN, inner)];
934 : 0 : fc->item_idx = item_idx;
935 [ # # # # ]: 0 : fc->is_range = l && l->total_length;
936 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_len_set;
937 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, ipv4_total_length, inner);
938 : : }
939 : :
940 [ # # ]: 0 : if (m->dst_addr) {
941 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV4_DST, inner)];
942 : 0 : fc->item_idx = item_idx;
943 [ # # # # ]: 0 : fc->is_range = l && l->dst_addr;
944 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_dst_addr_set;
945 [ # # ]: 0 : DR_CALC_SET(fc, ipv4_src_dest, destination_address, inner);
946 : : }
947 : :
948 [ # # ]: 0 : if (m->src_addr) {
949 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV4_SRC, inner)];
950 : 0 : fc->item_idx = item_idx;
951 [ # # # # ]: 0 : fc->is_range = l && l->src_addr;
952 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_src_addr_set;
953 [ # # ]: 0 : DR_CALC_SET(fc, ipv4_src_dest, source_address, inner);
954 : : }
955 : :
956 [ # # ]: 0 : if (m->ihl) {
957 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV4_IHL, inner)];
958 : 0 : fc->item_idx = item_idx;
959 [ # # # # ]: 0 : fc->is_range = l && l->ihl;
960 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_ihl_set;
961 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, ihl, inner);
962 : : }
963 : :
964 [ # # ]: 0 : if (m->time_to_live) {
965 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_TTL, inner)];
966 : 0 : fc->item_idx = item_idx;
967 [ # # # # ]: 0 : fc->is_range = l && l->time_to_live;
968 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_time_to_live_set;
969 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, time_to_live_hop_limit, inner);
970 : : }
971 : :
972 [ # # ]: 0 : if (m->type_of_service) {
973 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_TOS, inner)];
974 : 0 : fc->item_idx = item_idx;
975 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_tos_set;
976 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, tos, inner);
977 : : }
978 : :
979 : : return 0;
980 : : }
981 : :
982 : : static int
983 : 0 : mlx5dr_definer_conv_item_ipv6(struct mlx5dr_definer_conv_data *cd,
984 : : struct rte_flow_item *item,
985 : : int item_idx)
986 : : {
987 : 0 : const struct rte_flow_item_ipv6 *m = item->mask;
988 : 0 : const struct rte_flow_item_ipv6 *l = item->last;
989 : : struct mlx5dr_definer_fc *fc;
990 : 0 : bool inner = cd->tunnel;
991 : :
992 [ # # ]: 0 : if (!cd->relaxed) {
993 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
994 : 0 : fc->item_idx = item_idx;
995 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_version_set;
996 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
997 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_type, inner);
998 : :
999 : : /* Overwrite - Unset ethertype if present */
1000 [ # # ]: 0 : memset(&cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)], 0, sizeof(*fc));
1001 : : }
1002 : :
1003 [ # # ]: 0 : if (!m)
1004 : : return 0;
1005 : :
1006 : 0 : if (m->has_hop_ext || m->has_route_ext || m->has_auth_ext ||
1007 : : m->has_esp_ext || m->has_dest_ext || m->has_mobil_ext ||
1008 [ # # # # ]: 0 : m->has_hip_ext || m->has_shim6_ext ||
1009 [ # # # # : 0 : (l && (l->has_frag_ext || l->hdr.vtc_flow || l->hdr.proto ||
# # # # ]
1010 [ # # ]: 0 : !is_mem_zero(l->hdr.src_addr, 16) ||
1011 : 0 : !is_mem_zero(l->hdr.dst_addr, 16)))) {
1012 : 0 : rte_errno = ENOTSUP;
1013 : 0 : return rte_errno;
1014 : : }
1015 : :
1016 [ # # ]: 0 : if (m->has_frag_ext) {
1017 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_FRAG, inner)];
1018 : 0 : fc->item_idx = item_idx;
1019 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_frag_set;
1020 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, ip_fragmented, inner);
1021 : : }
1022 : :
1023 [ # # # # ]: 0 : if (DR_GET(header_ipv6_vtc, &m->hdr.vtc_flow, version)) {
1024 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
1025 : 0 : fc->item_idx = item_idx;
1026 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_version_set;
1027 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1028 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_type, inner);
1029 : : }
1030 : :
1031 [ # # # # ]: 0 : if (DR_GET(header_ipv6_vtc, &m->hdr.vtc_flow, tos)) {
1032 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_TOS, inner)];
1033 : 0 : fc->item_idx = item_idx;
1034 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_tos_set;
1035 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, tos, inner);
1036 : : }
1037 : :
1038 [ # # # # ]: 0 : if (DR_GET(header_ipv6_vtc, &m->hdr.vtc_flow, flow_label)) {
1039 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_FLOW_LABEL, inner)];
1040 : 0 : fc->item_idx = item_idx;
1041 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_flow_label_set;
1042 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, flow_label, inner);
1043 : : }
1044 : :
1045 [ # # ]: 0 : if (m->hdr.payload_len) {
1046 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_LEN, inner)];
1047 : 0 : fc->item_idx = item_idx;
1048 [ # # # # ]: 0 : fc->is_range = l && l->hdr.payload_len;
1049 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_payload_len_set;
1050 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, ipv6_payload_length, inner);
1051 : : }
1052 : :
1053 [ # # ]: 0 : if (m->hdr.proto) {
1054 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
1055 : 0 : fc->item_idx = item_idx;
1056 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_proto_set;
1057 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
1058 : : }
1059 : :
1060 [ # # ]: 0 : if (m->hdr.hop_limits) {
1061 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_TTL, inner)];
1062 : 0 : fc->item_idx = item_idx;
1063 [ # # # # ]: 0 : fc->is_range = l && l->hdr.hop_limits;
1064 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_hop_limits_set;
1065 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, time_to_live_hop_limit, inner);
1066 : : }
1067 : :
1068 [ # # ]: 0 : if (!is_mem_zero(m->hdr.src_addr, 4)) {
1069 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_SRC_127_96, inner)];
1070 : 0 : fc->item_idx = item_idx;
1071 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_src_addr_127_96_set;
1072 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_src, ipv6_address_127_96, inner);
1073 : : }
1074 : :
1075 [ # # ]: 0 : if (!is_mem_zero(m->hdr.src_addr + 4, 4)) {
1076 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_SRC_95_64, inner)];
1077 : 0 : fc->item_idx = item_idx;
1078 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_src_addr_95_64_set;
1079 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_src, ipv6_address_95_64, inner);
1080 : : }
1081 : :
1082 [ # # ]: 0 : if (!is_mem_zero(m->hdr.src_addr + 8, 4)) {
1083 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_SRC_63_32, inner)];
1084 : 0 : fc->item_idx = item_idx;
1085 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_src_addr_63_32_set;
1086 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_src, ipv6_address_63_32, inner);
1087 : : }
1088 : :
1089 [ # # ]: 0 : if (!is_mem_zero(m->hdr.src_addr + 12, 4)) {
1090 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_SRC_31_0, inner)];
1091 : 0 : fc->item_idx = item_idx;
1092 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_src_addr_31_0_set;
1093 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_src, ipv6_address_31_0, inner);
1094 : : }
1095 : :
1096 [ # # ]: 0 : if (!is_mem_zero(m->hdr.dst_addr, 4)) {
1097 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_DST_127_96, inner)];
1098 : 0 : fc->item_idx = item_idx;
1099 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_dst_addr_127_96_set;
1100 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_dst, ipv6_address_127_96, inner);
1101 : : }
1102 : :
1103 [ # # ]: 0 : if (!is_mem_zero(m->hdr.dst_addr + 4, 4)) {
1104 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_DST_95_64, inner)];
1105 : 0 : fc->item_idx = item_idx;
1106 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_dst_addr_95_64_set;
1107 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_dst, ipv6_address_95_64, inner);
1108 : : }
1109 : :
1110 [ # # ]: 0 : if (!is_mem_zero(m->hdr.dst_addr + 8, 4)) {
1111 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_DST_63_32, inner)];
1112 : 0 : fc->item_idx = item_idx;
1113 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_dst_addr_63_32_set;
1114 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_dst, ipv6_address_63_32, inner);
1115 : : }
1116 : :
1117 [ # # ]: 0 : if (!is_mem_zero(m->hdr.dst_addr + 12, 4)) {
1118 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IPV6_DST_31_0, inner)];
1119 : 0 : fc->item_idx = item_idx;
1120 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_dst_addr_31_0_set;
1121 [ # # ]: 0 : DR_CALC_SET(fc, ipv6_dst, ipv6_address_31_0, inner);
1122 : : }
1123 : :
1124 : : return 0;
1125 : : }
1126 : :
1127 : : static int
1128 : 0 : mlx5dr_definer_conv_item_udp(struct mlx5dr_definer_conv_data *cd,
1129 : : struct rte_flow_item *item,
1130 : : int item_idx)
1131 : : {
1132 : 0 : const struct rte_flow_item_udp *m = item->mask;
1133 : 0 : const struct rte_flow_item_udp *l = item->last;
1134 : : struct mlx5dr_definer_fc *fc;
1135 : 0 : bool inner = cd->tunnel;
1136 : :
1137 : : /* Set match on L4 type UDP */
1138 [ # # ]: 0 : if (!cd->relaxed) {
1139 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
1140 [ # # ]: 0 : if (!fc->not_overwrite) {
1141 : 0 : fc->item_idx = item_idx;
1142 : 0 : fc->tag_set = &mlx5dr_definer_udp_protocol_set;
1143 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1144 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, inner);
1145 : : }
1146 : : }
1147 : :
1148 [ # # ]: 0 : if (!m)
1149 : : return 0;
1150 : :
1151 [ # # # # ]: 0 : if (m->hdr.dgram_cksum || m->hdr.dgram_len) {
1152 : 0 : rte_errno = ENOTSUP;
1153 : 0 : return rte_errno;
1154 : : }
1155 : :
1156 [ # # ]: 0 : if (m->hdr.src_port) {
1157 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(L4_SPORT, inner)];
1158 : 0 : fc->item_idx = item_idx;
1159 [ # # # # ]: 0 : fc->is_range = l && l->hdr.src_port;
1160 : 0 : fc->tag_set = &mlx5dr_definer_udp_src_port_set;
1161 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, source_port, inner);
1162 : : }
1163 : :
1164 [ # # ]: 0 : if (m->hdr.dst_port) {
1165 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, inner)];
1166 : 0 : fc->item_idx = item_idx;
1167 [ # # # # ]: 0 : fc->is_range = l && l->hdr.dst_port;
1168 : 0 : fc->tag_set = &mlx5dr_definer_udp_dst_port_set;
1169 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, destination_port, inner);
1170 : : }
1171 : :
1172 : : return 0;
1173 : : }
1174 : :
1175 : : static int
1176 : 0 : mlx5dr_definer_conv_item_tcp(struct mlx5dr_definer_conv_data *cd,
1177 : : struct rte_flow_item *item,
1178 : : int item_idx)
1179 : : {
1180 : 0 : const struct rte_flow_item_tcp *m = item->mask;
1181 : 0 : const struct rte_flow_item_tcp *l = item->last;
1182 : : struct mlx5dr_definer_fc *fc;
1183 : 0 : bool inner = cd->tunnel;
1184 : :
1185 : : /* Overwrite match on L4 type TCP */
1186 [ # # ]: 0 : if (!cd->relaxed) {
1187 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
1188 [ # # ]: 0 : if (!fc->not_overwrite) {
1189 : 0 : fc->item_idx = item_idx;
1190 : 0 : fc->tag_set = &mlx5dr_definer_tcp_protocol_set;
1191 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1192 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, inner);
1193 : : }
1194 : : }
1195 : :
1196 [ # # ]: 0 : if (!m)
1197 : : return 0;
1198 : :
1199 [ # # # # : 0 : if (m->hdr.sent_seq || m->hdr.recv_ack || m->hdr.data_off ||
# # ]
1200 [ # # # # : 0 : m->hdr.rx_win || m->hdr.cksum || m->hdr.tcp_urp) {
# # ]
1201 : 0 : rte_errno = ENOTSUP;
1202 : 0 : return rte_errno;
1203 : : }
1204 : :
1205 [ # # ]: 0 : if (m->hdr.tcp_flags) {
1206 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(TCP_FLAGS, inner)];
1207 : 0 : fc->item_idx = item_idx;
1208 [ # # # # ]: 0 : fc->is_range = l && l->hdr.tcp_flags;
1209 : 0 : fc->tag_set = &mlx5dr_definer_tcp_flags_set;
1210 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, tcp_flags, inner);
1211 : : }
1212 : :
1213 [ # # ]: 0 : if (m->hdr.src_port) {
1214 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(L4_SPORT, inner)];
1215 : 0 : fc->item_idx = item_idx;
1216 [ # # # # ]: 0 : fc->is_range = l && l->hdr.src_port;
1217 : 0 : fc->tag_set = &mlx5dr_definer_tcp_src_port_set;
1218 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, source_port, inner);
1219 : : }
1220 : :
1221 [ # # ]: 0 : if (m->hdr.dst_port) {
1222 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, inner)];
1223 : 0 : fc->item_idx = item_idx;
1224 [ # # # # ]: 0 : fc->is_range = l && l->hdr.dst_port;
1225 : 0 : fc->tag_set = &mlx5dr_definer_tcp_dst_port_set;
1226 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, destination_port, inner);
1227 : : }
1228 : :
1229 : : return 0;
1230 : : }
1231 : :
1232 : : static int
1233 : 0 : mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
1234 : : struct rte_flow_item *item,
1235 : : int item_idx)
1236 : : {
1237 : 0 : struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
1238 : 0 : const struct rte_flow_item_gtp *m = item->mask;
1239 : : struct mlx5dr_definer_fc *fc;
1240 : :
1241 [ # # ]: 0 : if (cd->tunnel) {
1242 : 0 : DR_LOG(ERR, "Inner GTPU item not supported");
1243 : 0 : rte_errno = ENOTSUP;
1244 : 0 : return rte_errno;
1245 : : }
1246 : :
1247 : : /* Overwrite GTPU dest port if not present */
1248 : 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, false)];
1249 [ # # # # ]: 0 : if (!fc->tag_set && !cd->relaxed) {
1250 : 0 : fc->item_idx = item_idx;
1251 : 0 : fc->tag_set = &mlx5dr_definer_gtp_udp_port_set;
1252 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1253 : 0 : DR_CALC_SET(fc, eth_l4, destination_port, false);
1254 : : }
1255 : :
1256 [ # # ]: 0 : if (!m)
1257 : : return 0;
1258 : :
1259 [ # # # # ]: 0 : if (m->hdr.plen || m->hdr.gtp_hdr_info & ~MLX5DR_DEFINER_GTP_EXT_HDR_BIT) {
1260 : 0 : rte_errno = ENOTSUP;
1261 : 0 : return rte_errno;
1262 : : }
1263 : :
1264 [ # # ]: 0 : if (m->hdr.teid) {
1265 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
1266 : 0 : rte_errno = ENOTSUP;
1267 : 0 : return rte_errno;
1268 : : }
1269 : : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_TEID];
1270 : 0 : fc->item_idx = item_idx;
1271 : 0 : fc->tag_set = &mlx5dr_definer_gtp_teid_set;
1272 : 0 : fc->bit_mask = __mlx5_mask(header_gtp, teid);
1273 : 0 : fc->byte_off = caps->format_select_gtpu_dw_1 * DW_SIZE;
1274 : : }
1275 : :
1276 [ # # ]: 0 : if (m->hdr.gtp_hdr_info) {
1277 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
1278 : 0 : rte_errno = ENOTSUP;
1279 : 0 : return rte_errno;
1280 : : }
1281 : : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_EXT_FLAG];
1282 : 0 : fc->item_idx = item_idx;
1283 : 0 : fc->tag_set = &mlx5dr_definer_gtp_ext_flag_set;
1284 : 0 : fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
1285 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
1286 : 0 : fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
1287 : : }
1288 : :
1289 : :
1290 [ # # ]: 0 : if (m->hdr.msg_type) {
1291 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
1292 : 0 : rte_errno = ENOTSUP;
1293 : 0 : return rte_errno;
1294 : : }
1295 : : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_MSG_TYPE];
1296 : 0 : fc->item_idx = item_idx;
1297 : 0 : fc->tag_set = &mlx5dr_definer_gtp_msg_type_set;
1298 : 0 : fc->bit_mask = __mlx5_mask(header_gtp, msg_type);
1299 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gtp, msg_type);
1300 : 0 : fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
1301 : : }
1302 : :
1303 : : return 0;
1304 : : }
1305 : :
1306 : : static int
1307 : 0 : mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
1308 : : struct rte_flow_item *item,
1309 : : int item_idx)
1310 : : {
1311 : 0 : struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
1312 : 0 : const struct rte_flow_item_gtp_psc *m = item->mask;
1313 : : struct mlx5dr_definer_fc *fc;
1314 : :
1315 : : /* Overwrite GTP extension flag to be 1 */
1316 [ # # ]: 0 : if (!cd->relaxed) {
1317 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
1318 : 0 : rte_errno = ENOTSUP;
1319 : 0 : return rte_errno;
1320 : : }
1321 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_EXT_FLAG];
1322 : 0 : fc->item_idx = item_idx;
1323 : 0 : fc->tag_set = &mlx5dr_definer_ones_set;
1324 : 0 : fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
1325 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
1326 : 0 : fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
1327 : : }
1328 : :
1329 : : /* Overwrite next extension header type */
1330 [ # # ]: 0 : if (!cd->relaxed) {
1331 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
1332 : 0 : rte_errno = ENOTSUP;
1333 : 0 : return rte_errno;
1334 : : }
1335 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_NEXT_EXT_HDR];
1336 : 0 : fc->item_idx = item_idx;
1337 : 0 : fc->tag_set = &mlx5dr_definer_gtp_next_ext_hdr_set;
1338 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1339 : 0 : fc->bit_mask = __mlx5_mask(header_opt_gtp, next_ext_hdr_type);
1340 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_opt_gtp, next_ext_hdr_type);
1341 : 0 : fc->byte_off = caps->format_select_gtpu_dw_2 * DW_SIZE;
1342 : : }
1343 : :
1344 [ # # ]: 0 : if (!m)
1345 : : return 0;
1346 : :
1347 [ # # ]: 0 : if (m->hdr.type) {
1348 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
1349 : 0 : rte_errno = ENOTSUP;
1350 : 0 : return rte_errno;
1351 : : }
1352 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_EXT_HDR_PDU];
1353 : 0 : fc->item_idx = item_idx;
1354 : 0 : fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_pdu_set;
1355 : 0 : fc->bit_mask = __mlx5_mask(header_gtp_psc, pdu_type);
1356 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, pdu_type);
1357 : 0 : fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
1358 : : }
1359 : :
1360 [ # # ]: 0 : if (m->hdr.qfi) {
1361 [ # # ]: 0 : if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
1362 : 0 : rte_errno = ENOTSUP;
1363 : 0 : return rte_errno;
1364 : : }
1365 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GTP_EXT_HDR_QFI];
1366 : 0 : fc->item_idx = item_idx;
1367 : 0 : fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_qfi_set;
1368 : 0 : fc->bit_mask = __mlx5_mask(header_gtp_psc, qfi);
1369 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, qfi);
1370 : 0 : fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
1371 : : }
1372 : :
1373 : : return 0;
1374 : : }
1375 : :
1376 : : static int
1377 : 0 : mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
1378 : : struct rte_flow_item *item,
1379 : : int item_idx)
1380 : : {
1381 : 0 : struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
1382 : 0 : const struct rte_flow_item_ethdev *m = item->mask;
1383 : : struct mlx5dr_definer_fc *fc;
1384 : :
1385 [ # # ]: 0 : if (m->port_id) {
1386 [ # # ]: 0 : if (!caps->wire_regc_mask) {
1387 : 0 : DR_LOG(ERR, "Port ID item not supported, missing wire REGC mask");
1388 : 0 : rte_errno = ENOTSUP;
1389 : 0 : return rte_errno;
1390 : : }
1391 : :
1392 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VPORT_REG_C_0];
1393 : 0 : fc->item_idx = item_idx;
1394 : 0 : fc->tag_set = &mlx5dr_definer_vport_set;
1395 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1396 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_0);
1397 : 0 : fc->bit_off = __builtin_ctz(caps->wire_regc_mask);
1398 : 0 : fc->bit_mask = caps->wire_regc_mask >> fc->bit_off;
1399 : : } else {
1400 : 0 : DR_LOG(ERR, "Pord ID item mask must specify ID mask");
1401 : 0 : rte_errno = EINVAL;
1402 : 0 : return rte_errno;
1403 : : }
1404 : :
1405 : 0 : return 0;
1406 : : }
1407 : :
1408 : : static int
1409 : 0 : mlx5dr_definer_conv_item_vxlan(struct mlx5dr_definer_conv_data *cd,
1410 : : struct rte_flow_item *item,
1411 : : int item_idx)
1412 : : {
1413 : 0 : const struct rte_flow_item_vxlan *m = item->mask;
1414 : : struct mlx5dr_definer_fc *fc;
1415 : 0 : bool inner = cd->tunnel;
1416 : :
1417 [ # # ]: 0 : if (inner) {
1418 : 0 : DR_LOG(ERR, "Inner VXLAN item not supported");
1419 : 0 : rte_errno = ENOTSUP;
1420 : 0 : return rte_errno;
1421 : : }
1422 : :
1423 : : /* In order to match on VXLAN we must match on ip_protocol and l4_dport */
1424 [ # # ]: 0 : if (!cd->relaxed) {
1425 : 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
1426 [ # # ]: 0 : if (!fc->tag_set) {
1427 : 0 : fc->item_idx = item_idx;
1428 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1429 : 0 : fc->tag_set = &mlx5dr_definer_udp_protocol_set;
1430 : 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, inner);
1431 : : }
1432 : :
1433 : 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, inner)];
1434 [ # # ]: 0 : if (!fc->tag_set) {
1435 : 0 : fc->item_idx = item_idx;
1436 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1437 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_udp_port_set;
1438 : 0 : DR_CALC_SET(fc, eth_l4, destination_port, inner);
1439 : : }
1440 : : }
1441 : :
1442 [ # # ]: 0 : if (!m)
1443 : : return 0;
1444 : :
1445 [ # # ]: 0 : if (m->flags) {
1446 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_FLAGS];
1447 : 0 : fc->item_idx = item_idx;
1448 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_flags_set;
1449 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
1450 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan, flags);
1451 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_vxlan, flags);
1452 : : }
1453 : :
1454 [ # # ]: 0 : if (!is_mem_zero(m->vni, 3)) {
1455 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_VNI];
1456 : 0 : fc->item_idx = item_idx;
1457 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_vni_set;
1458 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_1);
1459 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan, vni);
1460 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_vxlan, vni);
1461 : : }
1462 : :
1463 : : return 0;
1464 : : }
1465 : :
1466 : : static int
1467 : 0 : mlx5dr_definer_conv_item_mpls(struct mlx5dr_definer_conv_data *cd,
1468 : : struct rte_flow_item *item,
1469 : : int item_idx)
1470 : : {
1471 : 0 : const struct rte_flow_item_mpls *m = item->mask;
1472 : : struct mlx5dr_definer_fc *fc;
1473 : 0 : bool inner = cd->tunnel;
1474 : :
1475 [ # # ]: 0 : if (inner) {
1476 : 0 : DR_LOG(ERR, "Inner MPLS item not supported");
1477 : 0 : rte_errno = ENOTSUP;
1478 : 0 : return rte_errno;
1479 : : }
1480 : :
1481 [ # # ]: 0 : if (!cd->relaxed) {
1482 : : /* In order to match on MPLS we must match on ip_protocol and l4_dport. */
1483 : 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, false)];
1484 [ # # ]: 0 : if (!fc->tag_set) {
1485 : 0 : fc->item_idx = item_idx;
1486 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1487 : 0 : fc->tag_set = &mlx5dr_definer_udp_protocol_set;
1488 : 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, false);
1489 : : }
1490 : :
1491 : : /* Currently support only MPLSoUDP */
1492 : : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, false)];
1493 [ # # ]: 0 : if (!fc->tag_set) {
1494 : 0 : fc->item_idx = item_idx;
1495 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1496 : 0 : fc->tag_set = &mlx5dr_definer_mpls_udp_port_set;
1497 : 0 : DR_CALC_SET(fc, eth_l4, destination_port, false);
1498 : : }
1499 : : }
1500 : :
1501 [ # # # # : 0 : if (m && (!is_mem_zero(m->label_tc_s, 3) || m->ttl)) {
# # ]
1502 : : /* According to HW MPLSoUDP is handled as inner */
1503 : 0 : fc = mlx5dr_definer_get_mpls_fc(cd, true);
1504 [ # # ]: 0 : if (!fc)
1505 : 0 : return rte_errno;
1506 : :
1507 : 0 : fc->item_idx = item_idx;
1508 : 0 : fc->tag_set = &mlx5dr_definer_mpls_label_set;
1509 : : } else { /* Mask relevant oks2 bit, indicates MPLS label exists.
1510 : : * According to HW MPLSoUDP is handled as inner
1511 : : */
1512 : 0 : fc = mlx5dr_definer_get_mpls_oks_fc(cd, true);
1513 [ # # ]: 0 : if (!fc)
1514 : 0 : return rte_errno;
1515 : :
1516 : 0 : fc->item_idx = item_idx;
1517 : 0 : fc->tag_set = mlx5dr_definer_ones_set;
1518 : : }
1519 : :
1520 : : return 0;
1521 : : }
1522 : :
1523 : : static struct mlx5dr_definer_fc *
1524 : 0 : mlx5dr_definer_get_register_fc(struct mlx5dr_definer_conv_data *cd, int reg)
1525 : : {
1526 : : struct mlx5dr_definer_fc *fc;
1527 : :
1528 [ # # # # : 0 : switch (reg) {
# # # # #
# # # # #
# ]
1529 : 0 : case REG_C_0:
1530 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_0];
1531 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_0);
1532 : 0 : break;
1533 : 0 : case REG_C_1:
1534 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_1];
1535 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_1);
1536 : 0 : break;
1537 : 0 : case REG_C_2:
1538 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_2];
1539 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_2);
1540 : 0 : break;
1541 : 0 : case REG_C_3:
1542 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_3];
1543 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_3);
1544 : 0 : break;
1545 : 0 : case REG_C_4:
1546 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_4];
1547 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_4);
1548 : 0 : break;
1549 : 0 : case REG_C_5:
1550 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_5];
1551 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_5);
1552 : 0 : break;
1553 : 0 : case REG_C_6:
1554 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_6];
1555 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_6);
1556 : 0 : break;
1557 : 0 : case REG_C_7:
1558 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_7];
1559 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_7);
1560 : 0 : break;
1561 : 0 : case REG_C_8:
1562 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_8];
1563 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_8);
1564 : 0 : break;
1565 : 0 : case REG_C_9:
1566 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_9];
1567 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_9);
1568 : 0 : break;
1569 : 0 : case REG_C_10:
1570 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_10];
1571 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_10);
1572 : 0 : break;
1573 : 0 : case REG_C_11:
1574 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_11];
1575 : 0 : DR_CALC_SET_HDR(fc, registers, register_c_11);
1576 : 0 : break;
1577 : 0 : case REG_A:
1578 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_A];
1579 : 0 : DR_CALC_SET_HDR(fc, metadata, general_purpose);
1580 : 0 : break;
1581 : 0 : case REG_B:
1582 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_REG_B];
1583 : 0 : DR_CALC_SET_HDR(fc, metadata, metadata_to_cqe);
1584 : 0 : break;
1585 : 0 : default:
1586 : 0 : rte_errno = ENOTSUP;
1587 : 0 : return NULL;
1588 : : }
1589 : :
1590 : : return fc;
1591 : : }
1592 : :
1593 : : static int
1594 : 0 : mlx5dr_definer_conv_item_tag(struct mlx5dr_definer_conv_data *cd,
1595 : : struct rte_flow_item *item,
1596 : : int item_idx)
1597 : : {
1598 : 0 : const struct rte_flow_item_tag *m = item->mask;
1599 : 0 : const struct rte_flow_item_tag *v = item->spec;
1600 : 0 : const struct rte_flow_item_tag *l = item->last;
1601 : : struct mlx5dr_definer_fc *fc;
1602 : : int reg;
1603 : :
1604 [ # # ]: 0 : if (!m || !v)
1605 : : return 0;
1606 : :
1607 [ # # ]: 0 : if (item->type == RTE_FLOW_ITEM_TYPE_TAG)
1608 : 0 : reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
1609 : : RTE_FLOW_ITEM_TYPE_TAG,
1610 : 0 : v->index);
1611 : : else
1612 : 0 : reg = (int)v->index;
1613 : :
1614 [ # # ]: 0 : if (reg <= 0) {
1615 : 0 : DR_LOG(ERR, "Invalid register for item tag");
1616 : 0 : rte_errno = EINVAL;
1617 : 0 : return rte_errno;
1618 : : }
1619 : :
1620 : 0 : fc = mlx5dr_definer_get_register_fc(cd, reg);
1621 [ # # ]: 0 : if (!fc)
1622 : 0 : return rte_errno;
1623 : :
1624 : 0 : fc->item_idx = item_idx;
1625 [ # # # # ]: 0 : fc->is_range = l && l->index;
1626 : 0 : fc->tag_set = &mlx5dr_definer_tag_set;
1627 : :
1628 : 0 : return 0;
1629 : : }
1630 : :
1631 : : static void
1632 : 0 : mlx5dr_definer_quota_set(struct mlx5dr_definer_fc *fc,
1633 : : const void *item_data, uint8_t *tag)
1634 : : {
1635 : : /**
1636 : : * MLX5 PMD implements QUOTA with Meter object.
1637 : : * PMD Quota action translation implicitly increments
1638 : : * Meter register value after HW assigns it.
1639 : : * Meter register values are:
1640 : : * HW QUOTA(HW+1) QUOTA state
1641 : : * RED 0 1 (01b) BLOCK
1642 : : * YELLOW 1 2 (10b) PASS
1643 : : * GREEN 2 3 (11b) PASS
1644 : : *
1645 : : * Quota item checks Meter register bit 1 value to determine state:
1646 : : * SPEC MASK
1647 : : * PASS 2 (10b) 2 (10b)
1648 : : * BLOCK 0 (00b) 2 (10b)
1649 : : *
1650 : : * item_data is NULL when template quota item is non-masked:
1651 : : * .. / quota / ..
1652 : : */
1653 : :
1654 : : const struct rte_flow_item_quota *quota = item_data;
1655 : : uint32_t val;
1656 : :
1657 [ # # # # ]: 0 : if (quota && quota->state == RTE_FLOW_QUOTA_STATE_BLOCK)
1658 : : val = MLX5DR_DEFINER_QUOTA_BLOCK;
1659 : : else
1660 : : val = MLX5DR_DEFINER_QUOTA_PASS;
1661 : :
1662 [ # # # # : 0 : DR_SET(tag, val, fc->byte_off, fc->bit_off, fc->bit_mask);
# # # # ]
1663 : 0 : }
1664 : :
1665 : : static int
1666 : 0 : mlx5dr_definer_conv_item_quota(struct mlx5dr_definer_conv_data *cd,
1667 : : __rte_unused struct rte_flow_item *item,
1668 : : int item_idx)
1669 : : {
1670 : : int mtr_reg =
1671 : 0 : flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_METER_COLOR,
1672 : : 0);
1673 : : struct mlx5dr_definer_fc *fc;
1674 : :
1675 [ # # ]: 0 : if (mtr_reg < 0) {
1676 : 0 : rte_errno = EINVAL;
1677 : 0 : return rte_errno;
1678 : : }
1679 : :
1680 : 0 : fc = mlx5dr_definer_get_register_fc(cd, mtr_reg);
1681 [ # # ]: 0 : if (!fc)
1682 : 0 : return rte_errno;
1683 : :
1684 : 0 : fc->tag_set = &mlx5dr_definer_quota_set;
1685 : 0 : fc->item_idx = item_idx;
1686 : 0 : return 0;
1687 : : }
1688 : :
1689 : : static int
1690 : 0 : mlx5dr_definer_conv_item_metadata(struct mlx5dr_definer_conv_data *cd,
1691 : : struct rte_flow_item *item,
1692 : : int item_idx)
1693 : : {
1694 : 0 : const struct rte_flow_item_meta *m = item->mask;
1695 : 0 : const struct rte_flow_item_meta *l = item->last;
1696 : : struct mlx5dr_definer_fc *fc;
1697 : : int reg;
1698 : :
1699 [ # # ]: 0 : if (!m)
1700 : : return 0;
1701 : :
1702 : 0 : reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_META, -1);
1703 : : if (reg <= 0) {
1704 : 0 : DR_LOG(ERR, "Invalid register for item metadata");
1705 : 0 : rte_errno = EINVAL;
1706 : 0 : return rte_errno;
1707 : : }
1708 : :
1709 : 0 : fc = mlx5dr_definer_get_register_fc(cd, reg);
1710 [ # # ]: 0 : if (!fc)
1711 : 0 : return rte_errno;
1712 : :
1713 : 0 : fc->item_idx = item_idx;
1714 [ # # # # ]: 0 : fc->is_range = l && l->data;
1715 : 0 : fc->tag_set = &mlx5dr_definer_metadata_set;
1716 : :
1717 : 0 : return 0;
1718 : : }
1719 : :
1720 : : static int
1721 : : mlx5dr_definer_conv_item_sq(struct mlx5dr_definer_conv_data *cd,
1722 : : struct rte_flow_item *item,
1723 : : int item_idx)
1724 : : {
1725 : 0 : const struct mlx5_rte_flow_item_sq *m = item->mask;
1726 : : struct mlx5dr_definer_fc *fc;
1727 : :
1728 [ # # ]: 0 : if (!m)
1729 : : return 0;
1730 : :
1731 [ # # ]: 0 : if (m->queue) {
1732 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_SOURCE_QP];
1733 : 0 : fc->item_idx = item_idx;
1734 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1735 : 0 : fc->tag_set = &mlx5dr_definer_source_qp_set;
1736 : 0 : DR_CALC_SET_HDR(fc, source_qp_gvmi, source_qp);
1737 : : }
1738 : :
1739 : : return 0;
1740 : : }
1741 : :
1742 : : static int
1743 : 0 : mlx5dr_definer_conv_item_gre(struct mlx5dr_definer_conv_data *cd,
1744 : : struct rte_flow_item *item,
1745 : : int item_idx)
1746 : : {
1747 : 0 : const struct rte_flow_item_gre *m = item->mask;
1748 : : struct mlx5dr_definer_fc *fc;
1749 : 0 : bool inner = cd->tunnel;
1750 : :
1751 [ # # ]: 0 : if (inner) {
1752 : 0 : DR_LOG(ERR, "Inner GRE item not supported");
1753 : 0 : rte_errno = ENOTSUP;
1754 : 0 : return rte_errno;
1755 : : }
1756 : :
1757 [ # # ]: 0 : if (!cd->relaxed) {
1758 : 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
1759 : 0 : fc->item_idx = item_idx;
1760 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1761 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_protocol_gre_set;
1762 : 0 : DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
1763 : : }
1764 : :
1765 [ # # ]: 0 : if (!m)
1766 : : return 0;
1767 : :
1768 [ # # ]: 0 : if (m->c_rsvd0_ver) {
1769 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_C_VER];
1770 : 0 : fc->item_idx = item_idx;
1771 : 0 : fc->tag_set = &mlx5dr_definer_gre_c_ver_set;
1772 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
1773 : 0 : fc->bit_mask = __mlx5_mask(header_gre, c_rsvd0_ver);
1774 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gre, c_rsvd0_ver);
1775 : : }
1776 : :
1777 [ # # ]: 0 : if (m->protocol) {
1778 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_PROTOCOL];
1779 : 0 : fc->item_idx = item_idx;
1780 : 0 : fc->tag_set = &mlx5dr_definer_gre_protocol_type_set;
1781 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
1782 : 0 : fc->byte_off += MLX5_BYTE_OFF(header_gre, gre_protocol);
1783 : 0 : fc->bit_mask = __mlx5_mask(header_gre, gre_protocol);
1784 : : fc->bit_off = __mlx5_dw_bit_off(header_gre, gre_protocol);
1785 : : }
1786 : :
1787 : : return 0;
1788 : : }
1789 : :
1790 : : static int
1791 : 0 : mlx5dr_definer_conv_item_gre_opt(struct mlx5dr_definer_conv_data *cd,
1792 : : struct rte_flow_item *item,
1793 : : int item_idx)
1794 : : {
1795 : 0 : const struct rte_flow_item_gre_opt *m = item->mask;
1796 : : struct mlx5dr_definer_fc *fc;
1797 : :
1798 [ # # ]: 0 : if (!cd->relaxed) {
1799 : 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, false)];
1800 [ # # ]: 0 : if (!fc->tag_set) {
1801 : 0 : fc->item_idx = item_idx;
1802 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1803 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_protocol_gre_set;
1804 : 0 : DR_CALC_SET(fc, eth_l3, protocol_next_header, false);
1805 : : }
1806 : : }
1807 : :
1808 [ # # ]: 0 : if (!m)
1809 : : return 0;
1810 : :
1811 [ # # ]: 0 : if (m->checksum_rsvd.checksum) {
1812 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_OPT_CHECKSUM];
1813 : 0 : fc->item_idx = item_idx;
1814 : 0 : fc->tag_set = &mlx5dr_definer_gre_opt_checksum_set;
1815 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_1);
1816 : : }
1817 : :
1818 [ # # ]: 0 : if (m->key.key) {
1819 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_OPT_KEY];
1820 : 0 : fc->item_idx = item_idx;
1821 : 0 : fc->tag_set = &mlx5dr_definer_gre_opt_key_set;
1822 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_2);
1823 : : }
1824 : :
1825 [ # # ]: 0 : if (m->sequence.sequence) {
1826 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_OPT_SEQ];
1827 : 0 : fc->item_idx = item_idx;
1828 : 0 : fc->tag_set = &mlx5dr_definer_gre_opt_seq_set;
1829 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_3);
1830 : : }
1831 : :
1832 : : return 0;
1833 : : }
1834 : :
1835 : : static int
1836 : 0 : mlx5dr_definer_conv_item_gre_key(struct mlx5dr_definer_conv_data *cd,
1837 : : struct rte_flow_item *item,
1838 : : int item_idx)
1839 : : {
1840 : 0 : const rte_be32_t *m = item->mask;
1841 : : struct mlx5dr_definer_fc *fc;
1842 : :
1843 [ # # ]: 0 : if (!cd->relaxed) {
1844 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_KEY_PRESENT];
1845 : 0 : fc->item_idx = item_idx;
1846 : 0 : fc->tag_set = &mlx5dr_definer_ones_set;
1847 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
1848 : 0 : fc->bit_mask = __mlx5_mask(header_gre, gre_k_present);
1849 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_gre, gre_k_present);
1850 : :
1851 : : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, false)];
1852 [ # # ]: 0 : if (!fc->tag_set) {
1853 : 0 : fc->item_idx = item_idx;
1854 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1855 : 0 : fc->tag_set = &mlx5dr_definer_ipv4_protocol_gre_set;
1856 : 0 : DR_CALC_SET(fc, eth_l3, protocol_next_header, false);
1857 : : }
1858 : : }
1859 : :
1860 [ # # ]: 0 : if (!m)
1861 : : return 0;
1862 : :
1863 [ # # ]: 0 : if (*m) {
1864 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GRE_OPT_KEY];
1865 : 0 : fc->item_idx = item_idx;
1866 : 0 : fc->tag_set = &mlx5dr_definer_gre_key_set;
1867 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_2);
1868 : : }
1869 : :
1870 : : return 0;
1871 : : }
1872 : :
1873 : : static int
1874 : 0 : mlx5dr_definer_conv_item_ptype(struct mlx5dr_definer_conv_data *cd,
1875 : : struct rte_flow_item *item,
1876 : : int item_idx)
1877 : : {
1878 : 0 : const struct rte_flow_item_ptype *m = item->mask;
1879 : : struct mlx5dr_definer_fc *fc;
1880 : :
1881 [ # # ]: 0 : if (!m)
1882 : : return 0;
1883 : :
1884 [ # # ]: 0 : if (!(m->packet_type &
1885 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK | RTE_PTYPE_TUNNEL_MASK |
1886 : : RTE_PTYPE_INNER_L2_MASK | RTE_PTYPE_INNER_L3_MASK | RTE_PTYPE_INNER_L4_MASK))) {
1887 : 0 : rte_errno = ENOTSUP;
1888 : 0 : return rte_errno;
1889 : : }
1890 : :
1891 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_L2_MASK) {
1892 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_L2, false)];
1893 : 0 : fc->item_idx = item_idx;
1894 : 0 : fc->tag_set = &mlx5dr_definer_ptype_l2_set;
1895 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1896 : 0 : DR_CALC_SET(fc, eth_l2, first_vlan_qualifier, false);
1897 : : }
1898 : :
1899 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_INNER_L2_MASK) {
1900 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_L2, true)];
1901 : 0 : fc->item_idx = item_idx;
1902 : 0 : fc->tag_set = &mlx5dr_definer_ptype_l2_set;
1903 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1904 : 0 : DR_CALC_SET(fc, eth_l2, first_vlan_qualifier, true);
1905 : : }
1906 : :
1907 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_L3_MASK) {
1908 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_L3, false)];
1909 : 0 : fc->item_idx = item_idx;
1910 : 0 : fc->tag_set = &mlx5dr_definer_ptype_l3_set;
1911 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1912 : 0 : DR_CALC_SET(fc, eth_l2, l3_type, false);
1913 : : }
1914 : :
1915 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_INNER_L3_MASK) {
1916 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_L3, true)];
1917 : 0 : fc->item_idx = item_idx;
1918 : 0 : fc->tag_set = &mlx5dr_definer_ptype_l3_set;
1919 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1920 : 0 : DR_CALC_SET(fc, eth_l2, l3_type, true);
1921 : : }
1922 : :
1923 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_L4_MASK) {
1924 : : /*
1925 : : * Fragmented IP (Internet Protocol) packet type.
1926 : : * Cannot be combined with Layer 4 Types (TCP/UDP).
1927 : : * The exact value must be specified in the mask.
1928 : : */
1929 [ # # ]: 0 : if (m->packet_type == RTE_PTYPE_L4_FRAG) {
1930 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_FRAG, false)];
1931 : 0 : fc->item_idx = item_idx;
1932 : 0 : fc->tag_set = &mlx5dr_definer_ptype_frag_set;
1933 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1934 : 0 : DR_CALC_SET(fc, eth_l2, ip_fragmented, false);
1935 : : } else {
1936 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_L4, false)];
1937 : 0 : fc->item_idx = item_idx;
1938 : 0 : fc->tag_set = &mlx5dr_definer_ptype_l4_set;
1939 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1940 : 0 : DR_CALC_SET(fc, eth_l2, l4_type, false);
1941 : : }
1942 : : }
1943 : :
1944 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_INNER_L4_MASK) {
1945 [ # # ]: 0 : if (m->packet_type == RTE_PTYPE_INNER_L4_FRAG) {
1946 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_FRAG, true)];
1947 : 0 : fc->item_idx = item_idx;
1948 : 0 : fc->tag_set = &mlx5dr_definer_ptype_frag_set;
1949 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1950 : 0 : DR_CALC_SET(fc, eth_l2, ip_fragmented, true);
1951 : : } else {
1952 : 0 : fc = &cd->fc[DR_CALC_FNAME(PTYPE_L4, true)];
1953 : 0 : fc->item_idx = item_idx;
1954 : 0 : fc->tag_set = &mlx5dr_definer_ptype_l4_set;
1955 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1956 : 0 : DR_CALC_SET(fc, eth_l2, l4_type, true);
1957 : : }
1958 : : }
1959 : :
1960 [ # # ]: 0 : if (m->packet_type & RTE_PTYPE_TUNNEL_MASK) {
1961 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_PTYPE_TUNNEL];
1962 : 0 : fc->item_idx = item_idx;
1963 : 0 : fc->tag_set = &mlx5dr_definer_ptype_tunnel_set;
1964 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
1965 : 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, false);
1966 : : }
1967 : :
1968 : : return 0;
1969 : : }
1970 : :
1971 : : static int
1972 : 0 : mlx5dr_definer_conv_item_integrity(struct mlx5dr_definer_conv_data *cd,
1973 : : struct rte_flow_item *item,
1974 : : int item_idx)
1975 : : {
1976 : 0 : const struct rte_flow_item_integrity *m = item->mask;
1977 : : struct mlx5dr_definer_fc *fc;
1978 : :
1979 [ # # ]: 0 : if (!m)
1980 : : return 0;
1981 : :
1982 [ # # ]: 0 : if (m->packet_ok || m->l2_ok || m->l2_crc_ok || m->l3_len_ok) {
1983 : 0 : rte_errno = ENOTSUP;
1984 : 0 : return rte_errno;
1985 : : }
1986 : :
1987 [ # # ]: 0 : if (m->l3_ok || m->ipv4_csum_ok || m->l4_ok || m->l4_csum_ok) {
1988 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(INTEGRITY, m->level)];
1989 : 0 : fc->item_idx = item_idx;
1990 : 0 : fc->tag_set = &mlx5dr_definer_integrity_set;
1991 : 0 : DR_CALC_SET_HDR(fc, oks1, oks1_bits);
1992 : : }
1993 : :
1994 : : return 0;
1995 : : }
1996 : :
1997 : : static int
1998 : 0 : mlx5dr_definer_conv_item_conntrack(struct mlx5dr_definer_conv_data *cd,
1999 : : struct rte_flow_item *item,
2000 : : int item_idx)
2001 : : {
2002 : 0 : const struct rte_flow_item_conntrack *m = item->mask;
2003 : : struct mlx5dr_definer_fc *fc;
2004 : : int reg;
2005 : :
2006 [ # # ]: 0 : if (!m)
2007 : : return 0;
2008 : :
2009 : 0 : reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_CONNTRACK,
2010 : : -1);
2011 [ # # ]: 0 : if (reg <= 0) {
2012 : 0 : DR_LOG(ERR, "Invalid register for item conntrack");
2013 : 0 : rte_errno = EINVAL;
2014 : 0 : return rte_errno;
2015 : : }
2016 : :
2017 : 0 : fc = mlx5dr_definer_get_register_fc(cd, reg);
2018 [ # # ]: 0 : if (!fc)
2019 : 0 : return rte_errno;
2020 : :
2021 : 0 : fc->item_idx = item_idx;
2022 : 0 : fc->tag_mask_set = &mlx5dr_definer_conntrack_mask;
2023 : 0 : fc->tag_set = &mlx5dr_definer_conntrack_tag;
2024 : :
2025 : 0 : return 0;
2026 : : }
2027 : :
2028 : : static int
2029 : 0 : mlx5dr_definer_conv_item_icmp(struct mlx5dr_definer_conv_data *cd,
2030 : : struct rte_flow_item *item,
2031 : : int item_idx)
2032 : : {
2033 : 0 : const struct rte_flow_item_icmp *m = item->mask;
2034 : : struct mlx5dr_definer_fc *fc;
2035 : 0 : bool inner = cd->tunnel;
2036 : :
2037 : : /* Overwrite match on L4 type ICMP */
2038 [ # # ]: 0 : if (!cd->relaxed) {
2039 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2040 : 0 : fc->item_idx = item_idx;
2041 : 0 : fc->tag_set = &mlx5dr_definer_icmp_protocol_set;
2042 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2043 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l4_type, inner);
2044 : : }
2045 : :
2046 [ # # ]: 0 : if (!m)
2047 : : return 0;
2048 : :
2049 [ # # # # : 0 : if (m->hdr.icmp_type || m->hdr.icmp_code || m->hdr.icmp_cksum) {
# # ]
2050 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW1];
2051 : 0 : fc->item_idx = item_idx;
2052 : 0 : fc->tag_set = &mlx5dr_definer_icmp_dw1_set;
2053 : 0 : DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw1);
2054 : : }
2055 : :
2056 [ # # # # ]: 0 : if (m->hdr.icmp_ident || m->hdr.icmp_seq_nb) {
2057 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW2];
2058 : 0 : fc->item_idx = item_idx;
2059 : 0 : fc->tag_set = &mlx5dr_definer_icmp_dw2_set;
2060 : 0 : DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw2);
2061 : : }
2062 : :
2063 : : return 0;
2064 : : }
2065 : :
2066 : : static int
2067 : 0 : mlx5dr_definer_conv_item_icmp6(struct mlx5dr_definer_conv_data *cd,
2068 : : struct rte_flow_item *item,
2069 : : int item_idx)
2070 : : {
2071 : 0 : const struct rte_flow_item_icmp6 *m = item->mask;
2072 : : struct mlx5dr_definer_fc *fc;
2073 : 0 : bool inner = cd->tunnel;
2074 : :
2075 : : /* Overwrite match on L4 type ICMP6 */
2076 [ # # ]: 0 : if (!cd->relaxed) {
2077 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2078 : 0 : fc->item_idx = item_idx;
2079 : 0 : fc->tag_set = &mlx5dr_definer_icmp_protocol_set;
2080 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2081 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l4_type, inner);
2082 : : }
2083 : :
2084 [ # # ]: 0 : if (!m)
2085 : : return 0;
2086 : :
2087 [ # # # # ]: 0 : if (m->type || m->code || m->checksum) {
2088 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW1];
2089 : 0 : fc->item_idx = item_idx;
2090 : 0 : fc->tag_set = &mlx5dr_definer_icmp6_dw1_set;
2091 : 0 : DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw1);
2092 : : }
2093 : :
2094 : : return 0;
2095 : : }
2096 : :
2097 : : static int
2098 : 0 : mlx5dr_definer_conv_item_icmp6_echo(struct mlx5dr_definer_conv_data *cd,
2099 : : struct rte_flow_item *item,
2100 : : int item_idx)
2101 : : {
2102 : 0 : const struct rte_flow_item_icmp6_echo *m = item->mask;
2103 : : struct mlx5dr_definer_fc *fc;
2104 : 0 : bool inner = cd->tunnel;
2105 : :
2106 [ # # ]: 0 : if (!cd->relaxed) {
2107 : : /* Overwrite match on L4 type ICMP6 */
2108 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2109 : 0 : fc->item_idx = item_idx;
2110 : 0 : fc->tag_set = &mlx5dr_definer_icmp_protocol_set;
2111 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2112 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l4_type, inner);
2113 : :
2114 : : /* Set fixed type and code for icmp6 echo request/reply */
2115 : : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW1];
2116 : 0 : fc->item_idx = item_idx;
2117 : 0 : fc->tag_mask_set = &mlx5dr_definer_icmp6_echo_dw1_mask_set;
2118 [ # # ]: 0 : if (item->type == RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST)
2119 : 0 : fc->tag_set = &mlx5dr_definer_icmp6_echo_request_dw1_set;
2120 : : else /* RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY */
2121 : 0 : fc->tag_set = &mlx5dr_definer_icmp6_echo_reply_dw1_set;
2122 : 0 : DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw1);
2123 : : }
2124 : :
2125 [ # # ]: 0 : if (!m)
2126 : : return 0;
2127 : :
2128 : : /* Set identifier & sequence into icmp_dw2 */
2129 [ # # # # ]: 0 : if (m->hdr.identifier || m->hdr.sequence) {
2130 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW2];
2131 : 0 : fc->item_idx = item_idx;
2132 : 0 : fc->tag_set = &mlx5dr_definer_icmp6_echo_dw2_set;
2133 : 0 : DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw2);
2134 : : }
2135 : :
2136 : : return 0;
2137 : : }
2138 : :
2139 : : static int
2140 : 0 : mlx5dr_definer_conv_item_meter_color(struct mlx5dr_definer_conv_data *cd,
2141 : : struct rte_flow_item *item,
2142 : : int item_idx)
2143 : : {
2144 : 0 : const struct rte_flow_item_meter_color *m = item->mask;
2145 : : struct mlx5dr_definer_fc *fc;
2146 : : int reg;
2147 : :
2148 [ # # ]: 0 : if (!m)
2149 : : return 0;
2150 : :
2151 : 0 : reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
2152 : : RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
2153 : : MLX5_ASSERT(reg > 0);
2154 : :
2155 : 0 : fc = mlx5dr_definer_get_register_fc(cd, reg);
2156 [ # # ]: 0 : if (!fc)
2157 : 0 : return rte_errno;
2158 : :
2159 : 0 : fc->item_idx = item_idx;
2160 : 0 : fc->tag_set = &mlx5dr_definer_meter_color_set;
2161 : 0 : return 0;
2162 : : }
2163 : :
2164 : : static struct mlx5dr_definer_fc *
2165 : : mlx5dr_definer_get_flex_parser_fc(struct mlx5dr_definer_conv_data *cd, uint32_t byte_off)
2166 : : {
2167 : : uint32_t byte_off_fp7 = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_7);
2168 : : uint32_t byte_off_fp0 = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_0);
2169 : : enum mlx5dr_definer_fname fname = MLX5DR_DEFINER_FNAME_FLEX_PARSER_0;
2170 : : struct mlx5dr_definer_fc *fc;
2171 : : uint32_t idx;
2172 : :
2173 : 0 : if (byte_off < byte_off_fp7 || byte_off > byte_off_fp0) {
2174 : 0 : rte_errno = EINVAL;
2175 : : return NULL;
2176 : : }
2177 : 0 : idx = (byte_off_fp0 - byte_off) / (sizeof(uint32_t));
2178 : 0 : fname += (enum mlx5dr_definer_fname)idx;
2179 : 0 : fc = &cd->fc[fname];
2180 : 0 : fc->byte_off = byte_off;
2181 : 0 : fc->bit_mask = UINT32_MAX;
2182 : : return fc;
2183 : : }
2184 : :
2185 : : static int
2186 : 0 : mlx5dr_definer_conv_item_ipv6_routing_ext(struct mlx5dr_definer_conv_data *cd,
2187 : : struct rte_flow_item *item,
2188 : : int item_idx)
2189 : : {
2190 : 0 : const struct rte_flow_item_ipv6_routing_ext *m = item->mask;
2191 : : struct mlx5dr_definer_fc *fc;
2192 : 0 : bool inner = cd->tunnel;
2193 : : uint32_t byte_off;
2194 : :
2195 [ # # ]: 0 : if (!cd->relaxed) {
2196 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
2197 : 0 : fc->item_idx = item_idx;
2198 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_version_set;
2199 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2200 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l3_type, inner);
2201 : :
2202 : : /* Overwrite - Unset ethertype if present */
2203 [ # # # # ]: 0 : memset(&cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)], 0, sizeof(*fc));
2204 : :
2205 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2206 [ # # ]: 0 : if (!fc->tag_set) {
2207 : 0 : fc->item_idx = item_idx;
2208 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_routing_hdr_set;
2209 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2210 : 0 : fc->not_overwrite = 1;
2211 [ # # ]: 0 : DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
2212 : : }
2213 : : } else {
2214 : 0 : rte_errno = ENOTSUP;
2215 : 0 : return rte_errno;
2216 : : }
2217 : :
2218 [ # # ]: 0 : if (!m)
2219 : : return 0;
2220 : :
2221 [ # # # # ]: 0 : if (m->hdr.hdr_len || m->hdr.flags) {
2222 : 0 : rte_errno = ENOTSUP;
2223 : 0 : return rte_errno;
2224 : : }
2225 : :
2226 [ # # # # : 0 : if (m->hdr.next_hdr || m->hdr.type || m->hdr.segments_left) {
# # ]
2227 [ # # ]: 0 : byte_off = flow_hw_get_srh_flex_parser_byte_off_from_ctx(cd->ctx);
2228 : : fc = mlx5dr_definer_get_flex_parser_fc(cd, byte_off);
2229 : : if (!fc)
2230 : 0 : return rte_errno;
2231 : :
2232 : 0 : fc->item_idx = item_idx;
2233 : 0 : fc->tag_set = &mlx5dr_definer_ipv6_routing_ext_set;
2234 : : }
2235 : : return 0;
2236 : : }
2237 : :
2238 : : static int
2239 : 0 : mlx5dr_definer_conv_item_random(struct mlx5dr_definer_conv_data *cd,
2240 : : struct rte_flow_item *item,
2241 : : int item_idx)
2242 : : {
2243 : 0 : const struct rte_flow_item_random *m = item->mask;
2244 : 0 : const struct rte_flow_item_random *l = item->last;
2245 : : struct mlx5dr_definer_fc *fc;
2246 : :
2247 [ # # ]: 0 : if (!m)
2248 : : return 0;
2249 : :
2250 [ # # ]: 0 : if (m->value != (m->value & UINT16_MAX)) {
2251 : 0 : DR_LOG(ERR, "Random value is 16 bits only");
2252 : 0 : rte_errno = EINVAL;
2253 : 0 : return rte_errno;
2254 : : }
2255 : :
2256 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM];
2257 : 0 : fc->item_idx = item_idx;
2258 : 0 : fc->tag_set = &mlx5dr_definer_random_number_set;
2259 [ # # # # ]: 0 : fc->is_range = l && l->value;
2260 : 0 : DR_CALC_SET_HDR(fc, random_number, random_number);
2261 : :
2262 : 0 : return 0;
2263 : : }
2264 : :
2265 : : static int
2266 : 0 : mlx5dr_definer_conv_item_geneve(struct mlx5dr_definer_conv_data *cd,
2267 : : struct rte_flow_item *item,
2268 : : int item_idx)
2269 : : {
2270 : 0 : const struct rte_flow_item_geneve *m = item->mask;
2271 : : struct mlx5dr_definer_fc *fc;
2272 : 0 : bool inner = cd->tunnel;
2273 : :
2274 [ # # ]: 0 : if (inner) {
2275 : 0 : DR_LOG(ERR, "Inner GENEVE item not supported");
2276 : 0 : rte_errno = ENOTSUP;
2277 : 0 : return rte_errno;
2278 : : }
2279 : :
2280 : : /* In order to match on Geneve we must match on ip_protocol and l4_dport */
2281 [ # # ]: 0 : if (!cd->relaxed) {
2282 : 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2283 [ # # ]: 0 : if (!fc->tag_set) {
2284 : 0 : fc->item_idx = item_idx;
2285 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2286 : 0 : fc->tag_set = &mlx5dr_definer_udp_protocol_set;
2287 : 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, inner);
2288 : : }
2289 : :
2290 : 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, inner)];
2291 [ # # ]: 0 : if (!fc->tag_set) {
2292 : 0 : fc->item_idx = item_idx;
2293 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2294 : 0 : fc->tag_set = &mlx5dr_definer_geneve_udp_port_set;
2295 : 0 : DR_CALC_SET(fc, eth_l4, destination_port, inner);
2296 : : }
2297 : : }
2298 : :
2299 [ # # ]: 0 : if (!m)
2300 : : return 0;
2301 : :
2302 [ # # ]: 0 : if (m->rsvd1) {
2303 : 0 : rte_errno = ENOTSUP;
2304 : 0 : return rte_errno;
2305 : : }
2306 : :
2307 [ # # ]: 0 : if (m->ver_opt_len_o_c_rsvd0) {
2308 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GENEVE_CTRL];
2309 : 0 : fc->item_idx = item_idx;
2310 : 0 : fc->tag_set = &mlx5dr_definer_geneve_ctrl_set;
2311 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
2312 : 0 : fc->bit_mask = __mlx5_mask(header_geneve, ver_opt_len_o_c_rsvd);
2313 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_geneve, ver_opt_len_o_c_rsvd);
2314 : : }
2315 : :
2316 [ # # ]: 0 : if (m->protocol) {
2317 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GENEVE_PROTO];
2318 : 0 : fc->item_idx = item_idx;
2319 : 0 : fc->tag_set = &mlx5dr_definer_geneve_protocol_set;
2320 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
2321 : 0 : fc->byte_off += MLX5_BYTE_OFF(header_geneve, protocol_type);
2322 : 0 : fc->bit_mask = __mlx5_mask(header_geneve, protocol_type);
2323 : : fc->bit_off = __mlx5_dw_bit_off(header_geneve, protocol_type);
2324 : : }
2325 : :
2326 [ # # ]: 0 : if (!is_mem_zero(m->vni, 3)) {
2327 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GENEVE_VNI];
2328 : 0 : fc->item_idx = item_idx;
2329 : 0 : fc->tag_set = &mlx5dr_definer_geneve_vni_set;
2330 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_1);
2331 : 0 : fc->bit_mask = __mlx5_mask(header_geneve, vni);
2332 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_geneve, vni);
2333 : : }
2334 : :
2335 : : return 0;
2336 : : }
2337 : :
2338 : : static int
2339 : 0 : mlx5dr_definer_conv_item_geneve_opt(struct mlx5dr_definer_conv_data *cd,
2340 : : struct rte_flow_item *item,
2341 : : int item_idx)
2342 : : {
2343 : 0 : const struct rte_flow_item_geneve_opt *m = item->mask;
2344 : 0 : const struct rte_flow_item_geneve_opt *v = item->spec;
2345 : : struct mlx5_hl_data *hl_ok_bit, *hl_dws;
2346 : : struct mlx5dr_definer_fc *fc;
2347 : : uint8_t num_of_dws, i;
2348 : : bool ok_bit_on_class;
2349 : : int ret;
2350 : :
2351 [ # # # # : 0 : if (!m || !(m->option_class || m->option_type || m->data))
# # ]
2352 : : return 0;
2353 : :
2354 [ # # # # ]: 0 : if (!v || m->option_type != 0xff) {
2355 : 0 : DR_LOG(ERR, "Cannot match geneve opt without valid opt type");
2356 : 0 : goto out_not_supp;
2357 : : }
2358 : :
2359 [ # # ]: 0 : if (m->option_class && m->option_class != RTE_BE16(UINT16_MAX)) {
2360 : 0 : DR_LOG(ERR, "Geneve option class has invalid mask");
2361 : 0 : goto out_not_supp;
2362 : : }
2363 : :
2364 : 0 : ret = mlx5_get_geneve_hl_data(cd->ctx,
2365 : 0 : v->option_type,
2366 : 0 : v->option_class,
2367 : : &hl_ok_bit,
2368 : : &num_of_dws,
2369 : : &hl_dws,
2370 : : &ok_bit_on_class);
2371 [ # # ]: 0 : if (ret) {
2372 : 0 : DR_LOG(ERR, "Geneve opt type and class %d not supported", v->option_type);
2373 : 0 : goto out_not_supp;
2374 : : }
2375 : :
2376 [ # # # # ]: 0 : if (!ok_bit_on_class && m->option_class) {
2377 : : /* DW0 is used, we will match type, class */
2378 [ # # # # ]: 0 : if (!num_of_dws || hl_dws[0].dw_mask != UINT32_MAX) {
2379 : 0 : DR_LOG(ERR, "Geneve opt type %d DW0 not supported", v->option_type);
2380 : 0 : goto out_not_supp;
2381 : : }
2382 : :
2383 [ # # ]: 0 : if (MLX5DR_DEFINER_FNAME_GENEVE_OPT_DW_0 + cd->geneve_opt_data_idx >
2384 : : MLX5DR_DEFINER_FNAME_GENEVE_OPT_DW_7) {
2385 : 0 : DR_LOG(ERR, "Max match geneve opt DWs reached");
2386 : 0 : goto out_not_supp;
2387 : : }
2388 : :
2389 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GENEVE_OPT_DW_0 + cd->geneve_opt_data_idx++];
2390 : 0 : fc->item_idx = item_idx;
2391 : 0 : fc->tag_set = &mlx5dr_definer_geneve_opt_ctrl_set;
2392 : 0 : fc->byte_off = hl_dws[0].dw_offset * DW_SIZE;
2393 : 0 : fc->bit_mask = UINT32_MAX;
2394 : : } else {
2395 : : /* DW0 is not used, we must verify geneve opt type exists in packet */
2396 [ # # ]: 0 : if (!hl_ok_bit->dw_mask) {
2397 : 0 : DR_LOG(ERR, "Geneve opt OK bits not supported");
2398 : 0 : goto out_not_supp;
2399 : : }
2400 : :
2401 [ # # ]: 0 : if (MLX5DR_DEFINER_FNAME_GENEVE_OPT_OK_0 + cd->geneve_opt_ok_idx >
2402 : : MLX5DR_DEFINER_FNAME_GENEVE_OPT_OK_7) {
2403 : 0 : DR_LOG(ERR, "Max match geneve opt reached");
2404 : 0 : goto out_not_supp;
2405 : : }
2406 : :
2407 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GENEVE_OPT_OK_0 + cd->geneve_opt_ok_idx++];
2408 : 0 : fc->item_idx = item_idx;
2409 : 0 : fc->tag_set = &mlx5dr_definer_ones_set;
2410 : 0 : fc->byte_off = hl_ok_bit->dw_offset * DW_SIZE +
2411 : 0 : __builtin_clz(hl_ok_bit->dw_mask) / 8;
2412 : 0 : fc->bit_off = __builtin_ctz(hl_ok_bit->dw_mask);
2413 : 0 : fc->bit_mask = 0x1;
2414 : : }
2415 : :
2416 [ # # ]: 0 : for (i = 1; i < num_of_dws; i++) {
2417 : : /* Process each valid geneve option data DW1..N */
2418 [ # # ]: 0 : if (!m->data[i - 1])
2419 : 0 : continue;
2420 : :
2421 [ # # ]: 0 : if (hl_dws[i].dw_mask != UINT32_MAX) {
2422 : 0 : DR_LOG(ERR, "Matching Geneve opt data[%d] not supported", i - 1);
2423 : 0 : goto out_not_supp;
2424 : : }
2425 : :
2426 [ # # ]: 0 : if (MLX5DR_DEFINER_FNAME_GENEVE_OPT_DW_0 + cd->geneve_opt_data_idx >
2427 : : MLX5DR_DEFINER_FNAME_GENEVE_OPT_DW_7) {
2428 : 0 : DR_LOG(ERR, "Max match geneve options DWs reached");
2429 : 0 : goto out_not_supp;
2430 : : }
2431 : :
2432 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_GENEVE_OPT_DW_0 + cd->geneve_opt_data_idx++];
2433 : 0 : fc->item_idx = item_idx;
2434 : 0 : fc->tag_set = &mlx5dr_definer_geneve_opt_data_set;
2435 : 0 : fc->byte_off = hl_dws[i].dw_offset * DW_SIZE;
2436 : 0 : fc->bit_mask = m->data[i - 1];
2437 : : /* Use extra_data for data[] set offset */
2438 : 0 : fc->extra_data = i - 1;
2439 : : }
2440 : :
2441 : : return 0;
2442 : :
2443 : 0 : out_not_supp:
2444 : 0 : rte_errno = ENOTSUP;
2445 : 0 : return rte_errno;
2446 : : }
2447 : :
2448 : : static int
2449 : 0 : mlx5dr_definer_mt_set_fc(struct mlx5dr_match_template *mt,
2450 : : struct mlx5dr_definer_fc *fc,
2451 : : uint8_t *hl)
2452 : : {
2453 : : uint32_t fc_sz = 0, fcr_sz = 0;
2454 : : int i;
2455 : :
2456 [ # # ]: 0 : for (i = 0; i < MLX5DR_DEFINER_FNAME_MAX; i++)
2457 [ # # ]: 0 : if (fc[i].tag_set)
2458 [ # # ]: 0 : fc[i].is_range ? fcr_sz++ : fc_sz++;
2459 : :
2460 : 0 : mt->fc = simple_calloc(fc_sz + fcr_sz, sizeof(*mt->fc));
2461 [ # # ]: 0 : if (!mt->fc) {
2462 : 0 : rte_errno = ENOMEM;
2463 : 0 : return rte_errno;
2464 : : }
2465 : :
2466 : 0 : mt->fcr = mt->fc + fc_sz;
2467 : :
2468 [ # # ]: 0 : for (i = 0; i < MLX5DR_DEFINER_FNAME_MAX; i++) {
2469 [ # # ]: 0 : if (!fc[i].tag_set)
2470 : 0 : continue;
2471 : :
2472 : 0 : fc[i].fname = i;
2473 : :
2474 [ # # ]: 0 : if (fc[i].is_range) {
2475 : 0 : memcpy(&mt->fcr[mt->fcr_sz++], &fc[i], sizeof(*mt->fcr));
2476 : : } else {
2477 [ # # ]: 0 : memcpy(&mt->fc[mt->fc_sz++], &fc[i], sizeof(*mt->fc));
2478 [ # # # # : 0 : DR_SET(hl, -1, fc[i].byte_off, fc[i].bit_off, fc[i].bit_mask);
# # # # ]
2479 : : }
2480 : : }
2481 : :
2482 : : return 0;
2483 : : }
2484 : :
2485 : : static int
2486 : 0 : mlx5dr_definer_check_item_range_supp(struct rte_flow_item *item)
2487 : : {
2488 [ # # ]: 0 : if (!item->last)
2489 : : return 0;
2490 : :
2491 [ # # ]: 0 : switch ((int)item->type) {
2492 : : case RTE_FLOW_ITEM_TYPE_IPV4:
2493 : : case RTE_FLOW_ITEM_TYPE_IPV6:
2494 : : case RTE_FLOW_ITEM_TYPE_UDP:
2495 : : case RTE_FLOW_ITEM_TYPE_TCP:
2496 : : case RTE_FLOW_ITEM_TYPE_TAG:
2497 : : case RTE_FLOW_ITEM_TYPE_META:
2498 : : case MLX5_RTE_FLOW_ITEM_TYPE_TAG:
2499 : : case RTE_FLOW_ITEM_TYPE_RANDOM:
2500 : : return 0;
2501 : 0 : default:
2502 : 0 : DR_LOG(ERR, "Range not supported over item type %d", item->type);
2503 : 0 : rte_errno = ENOTSUP;
2504 : 0 : return rte_errno;
2505 : : }
2506 : : }
2507 : :
2508 : : static int
2509 : 0 : mlx5dr_definer_conv_item_esp(struct mlx5dr_definer_conv_data *cd,
2510 : : struct rte_flow_item *item,
2511 : : int item_idx)
2512 : : {
2513 : 0 : const struct rte_flow_item_esp *m = item->mask;
2514 : : struct mlx5dr_definer_fc *fc;
2515 : :
2516 [ # # ]: 0 : if (!m)
2517 : : return 0;
2518 [ # # ]: 0 : if (m->hdr.spi) {
2519 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ESP_SPI];
2520 : 0 : fc->item_idx = item_idx;
2521 : 0 : fc->tag_set = &mlx5dr_definer_ipsec_spi_set;
2522 : 0 : DR_CALC_SET_HDR(fc, ipsec, spi);
2523 : : }
2524 [ # # ]: 0 : if (m->hdr.seq) {
2525 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER];
2526 : 0 : fc->item_idx = item_idx;
2527 : 0 : fc->tag_set = &mlx5dr_definer_ipsec_sequence_number_set;
2528 : 0 : DR_CALC_SET_HDR(fc, ipsec, sequence_number);
2529 : : }
2530 : : return 0;
2531 : : }
2532 : :
2533 : : static void mlx5dr_definer_set_conv_tunnel(enum rte_flow_item_type cur_type,
2534 : : uint64_t item_flags,
2535 : : struct mlx5dr_definer_conv_data *cd)
2536 : : {
2537 : : /* Already tunnel nothing to change */
2538 [ # # ]: 0 : if (cd->tunnel)
2539 : : return;
2540 : :
2541 : : /* We can have more than one MPLS label at each level (inner/outer), so
2542 : : * consider tunnel only when it is already under tunnel or if we moved to the
2543 : : * second MPLS level.
2544 : : */
2545 [ # # ]: 0 : if (cur_type != RTE_FLOW_ITEM_TYPE_MPLS)
2546 : 0 : cd->tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
2547 : : else
2548 : 0 : cd->tunnel = !!(item_flags & DR_FLOW_LAYER_TUNNEL_NO_MPLS);
2549 : : }
2550 : :
2551 : : static int
2552 : 0 : mlx5dr_definer_conv_item_flex_parser(struct mlx5dr_definer_conv_data *cd,
2553 : : struct rte_flow_item *item,
2554 : : int item_idx)
2555 : : {
2556 : : uint32_t base_off = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_0);
2557 : : const struct rte_flow_item_flex *v, *m;
2558 : : enum mlx5dr_definer_fname fname;
2559 : : struct mlx5dr_definer_fc *fc;
2560 : : uint32_t i, mask, byte_off;
2561 : 0 : bool is_inner = cd->tunnel;
2562 : : int ret;
2563 : :
2564 : 0 : m = item->mask;
2565 : 0 : v = item->spec;
2566 : 0 : mask = 0;
2567 [ # # ]: 0 : for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
2568 : 0 : byte_off = base_off - i * sizeof(uint32_t);
2569 : 0 : ret = mlx5_flex_get_parser_value_per_byte_off(m, v->handle, byte_off,
2570 : : true, is_inner, &mask);
2571 [ # # ]: 0 : if (ret == -1) {
2572 : 0 : rte_errno = EINVAL;
2573 : 0 : return rte_errno;
2574 : : }
2575 : :
2576 [ # # ]: 0 : if (!mask)
2577 : 0 : continue;
2578 : :
2579 : : fname = MLX5DR_DEFINER_FNAME_FLEX_PARSER_0;
2580 : 0 : fname += (enum mlx5dr_definer_fname)i;
2581 : 0 : fc = &cd->fc[fname];
2582 : 0 : fc->byte_off = byte_off;
2583 : 0 : fc->item_idx = item_idx;
2584 [ # # ]: 0 : fc->tag_set = cd->tunnel ? &mlx5dr_definer_flex_parser_inner_set :
2585 : : &mlx5dr_definer_flex_parser_outer_set;
2586 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2587 : 0 : fc->bit_mask = mask;
2588 : : }
2589 : : return 0;
2590 : : }
2591 : :
2592 : : static int
2593 : 0 : mlx5dr_definer_conv_item_ib_l4(struct mlx5dr_definer_conv_data *cd,
2594 : : struct rte_flow_item *item,
2595 : : int item_idx)
2596 : : {
2597 : 0 : const struct rte_flow_item_ib_bth *m = item->mask;
2598 : : struct mlx5dr_definer_fc *fc;
2599 : 0 : bool inner = cd->tunnel;
2600 : :
2601 : : /* In order to match on RoCEv2(layer4 ib), we must match
2602 : : * on ip_protocol and l4_dport.
2603 : : */
2604 [ # # ]: 0 : if (!cd->relaxed) {
2605 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2606 [ # # ]: 0 : if (!fc->tag_set) {
2607 : 0 : fc->item_idx = item_idx;
2608 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2609 : 0 : fc->tag_set = &mlx5dr_definer_udp_protocol_set;
2610 [ # # ]: 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, inner);
2611 : : }
2612 : :
2613 [ # # ]: 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, inner)];
2614 [ # # ]: 0 : if (!fc->tag_set) {
2615 : 0 : fc->item_idx = item_idx;
2616 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2617 : 0 : fc->tag_set = &mlx5dr_definer_ib_l4_udp_port_set;
2618 [ # # ]: 0 : DR_CALC_SET(fc, eth_l4, destination_port, inner);
2619 : : }
2620 : : }
2621 : :
2622 [ # # ]: 0 : if (!m)
2623 : : return 0;
2624 : :
2625 [ # # ]: 0 : if (m->hdr.se || m->hdr.m || m->hdr.padcnt || m->hdr.tver ||
2626 [ # # # # : 0 : m->hdr.pkey || m->hdr.f || m->hdr.b || m->hdr.rsvd0 ||
# # ]
2627 [ # # ]: 0 : m->hdr.rsvd1 || !is_mem_zero(m->hdr.psn, 3)) {
2628 : 0 : rte_errno = ENOTSUP;
2629 : 0 : return rte_errno;
2630 : : }
2631 : :
2632 [ # # ]: 0 : if (m->hdr.opcode) {
2633 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_IB_L4_OPCODE];
2634 : 0 : fc->item_idx = item_idx;
2635 : 0 : fc->tag_set = &mlx5dr_definer_ib_l4_opcode_set;
2636 : 0 : DR_CALC_SET_HDR(fc, ib_l4, opcode);
2637 : : }
2638 : :
2639 [ # # ]: 0 : if (!is_mem_zero(m->hdr.dst_qp, 3)) {
2640 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_IB_L4_QPN];
2641 : 0 : fc->item_idx = item_idx;
2642 : 0 : fc->tag_set = &mlx5dr_definer_ib_l4_qp_set;
2643 : 0 : DR_CALC_SET_HDR(fc, ib_l4, qp);
2644 : : }
2645 : :
2646 [ # # ]: 0 : if (m->hdr.a) {
2647 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_IB_L4_A];
2648 : 0 : fc->item_idx = item_idx;
2649 : 0 : fc->tag_set = &mlx5dr_definer_ib_l4_bth_a_set;
2650 : 0 : DR_CALC_SET_HDR(fc, ib_l4, ackreq);
2651 : : }
2652 : :
2653 : : return 0;
2654 : : }
2655 : :
2656 : : static int
2657 : 0 : mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd,
2658 : : struct rte_flow_item *item,
2659 : : int item_idx)
2660 : : {
2661 : 0 : const struct rte_flow_item_vxlan_gpe *m = item->mask;
2662 : : struct mlx5dr_definer_fc *fc;
2663 : 0 : bool inner = cd->tunnel;
2664 : :
2665 [ # # ]: 0 : if (inner) {
2666 : 0 : DR_LOG(ERR, "Inner VXLAN GPE item not supported");
2667 : 0 : rte_errno = ENOTSUP;
2668 : 0 : return rte_errno;
2669 : : }
2670 : :
2671 : : /* In order to match on VXLAN GPE we must match on ip_protocol and l4_dport */
2672 [ # # ]: 0 : if (!cd->relaxed) {
2673 : 0 : fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
2674 [ # # ]: 0 : if (!fc->tag_set) {
2675 : 0 : fc->item_idx = item_idx;
2676 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2677 : 0 : fc->tag_set = &mlx5dr_definer_udp_protocol_set;
2678 : 0 : DR_CALC_SET(fc, eth_l2, l4_type_bwc, inner);
2679 : : }
2680 : :
2681 : 0 : fc = &cd->fc[DR_CALC_FNAME(L4_DPORT, inner)];
2682 [ # # ]: 0 : if (!fc->tag_set) {
2683 : 0 : fc->item_idx = item_idx;
2684 : 0 : fc->tag_mask_set = &mlx5dr_definer_ones_set;
2685 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_gpe_udp_port_set;
2686 : 0 : DR_CALC_SET(fc, eth_l4, destination_port, inner);
2687 : : }
2688 : : }
2689 : :
2690 [ # # ]: 0 : if (!m)
2691 : : return 0;
2692 : :
2693 [ # # ]: 0 : if (m->flags) {
2694 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_GPE_FLAGS];
2695 : 0 : fc->item_idx = item_idx;
2696 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_gpe_flags_set;
2697 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
2698 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan_gpe, flags);
2699 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, flags);
2700 : : }
2701 : :
2702 [ # # ]: 0 : if (!is_mem_zero(m->rsvd0, 2)) {
2703 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_GPE_RSVD0];
2704 : 0 : fc->item_idx = item_idx;
2705 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_gpe_rsvd0_set;
2706 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
2707 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan_gpe, rsvd0);
2708 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, rsvd0);
2709 : : }
2710 : :
2711 [ # # ]: 0 : if (m->protocol) {
2712 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_GPE_PROTO];
2713 : 0 : fc->item_idx = item_idx;
2714 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_gpe_protocol_set;
2715 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_0);
2716 : 0 : fc->byte_off += MLX5_BYTE_OFF(header_vxlan_gpe, protocol);
2717 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan_gpe, protocol);
2718 : : fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, protocol);
2719 : : }
2720 : :
2721 [ # # ]: 0 : if (!is_mem_zero(m->vni, 3)) {
2722 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_GPE_VNI];
2723 : 0 : fc->item_idx = item_idx;
2724 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_gpe_vni_set;
2725 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_1);
2726 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan_gpe, vni);
2727 : 0 : fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, vni);
2728 : : }
2729 : :
2730 [ # # ]: 0 : if (m->rsvd1) {
2731 : 0 : fc = &cd->fc[MLX5DR_DEFINER_FNAME_VXLAN_GPE_RSVD1];
2732 : 0 : fc->item_idx = item_idx;
2733 : 0 : fc->tag_set = &mlx5dr_definer_vxlan_gpe_rsvd1_set;
2734 : 0 : DR_CALC_SET_HDR(fc, tunnel_header, tunnel_header_1);
2735 : 0 : fc->bit_mask = __mlx5_mask(header_vxlan_gpe, rsvd1);
2736 : : fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, rsvd1);
2737 : : }
2738 : :
2739 : : return 0;
2740 : : }
2741 : :
2742 : : static int
2743 : 0 : mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
2744 : : struct mlx5dr_match_template *mt,
2745 : : uint8_t *hl)
2746 : : {
2747 : 0 : struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}};
2748 : 0 : struct mlx5dr_definer_conv_data cd = {0};
2749 : 0 : struct rte_flow_item *items = mt->items;
2750 : : uint64_t item_flags = 0;
2751 : : int i, ret;
2752 : :
2753 : 0 : cd.fc = fc;
2754 : 0 : cd.ctx = ctx;
2755 : 0 : cd.relaxed = mt->flags & MLX5DR_MATCH_TEMPLATE_FLAG_RELAXED_MATCH;
2756 : :
2757 : : /* Collect all RTE fields to the field array and set header layout */
2758 [ # # ]: 0 : for (i = 0; items->type != RTE_FLOW_ITEM_TYPE_END; i++, items++) {
2759 : : mlx5dr_definer_set_conv_tunnel(items->type, item_flags, &cd);
2760 : :
2761 : 0 : ret = mlx5dr_definer_check_item_range_supp(items);
2762 [ # # ]: 0 : if (ret)
2763 : 0 : return ret;
2764 : :
2765 [ # # # # : 0 : switch ((int)items->type) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
2766 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
2767 : 0 : ret = mlx5dr_definer_conv_item_eth(&cd, items, i);
2768 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_LAYER_INNER_L2 :
2769 : : MLX5_FLOW_LAYER_OUTER_L2;
2770 : 0 : break;
2771 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
2772 : 0 : ret = mlx5dr_definer_conv_item_vlan(&cd, items, i);
2773 : 0 : item_flags |= cd.tunnel ?
2774 [ # # ]: 0 : (MLX5_FLOW_LAYER_INNER_VLAN | MLX5_FLOW_LAYER_INNER_L2) :
2775 : : (MLX5_FLOW_LAYER_OUTER_VLAN | MLX5_FLOW_LAYER_OUTER_L2);
2776 : 0 : break;
2777 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
2778 : 0 : ret = mlx5dr_definer_conv_item_ipv4(&cd, items, i);
2779 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 :
2780 : : MLX5_FLOW_LAYER_OUTER_L3_IPV4;
2781 : 0 : break;
2782 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
2783 : 0 : ret = mlx5dr_definer_conv_item_ipv6(&cd, items, i);
2784 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 :
2785 : : MLX5_FLOW_LAYER_OUTER_L3_IPV6;
2786 : 0 : break;
2787 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
2788 : 0 : ret = mlx5dr_definer_conv_item_udp(&cd, items, i);
2789 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP :
2790 : : MLX5_FLOW_LAYER_OUTER_L4_UDP;
2791 : 0 : break;
2792 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
2793 : 0 : ret = mlx5dr_definer_conv_item_tcp(&cd, items, i);
2794 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP :
2795 : : MLX5_FLOW_LAYER_OUTER_L4_TCP;
2796 : 0 : break;
2797 : 0 : case RTE_FLOW_ITEM_TYPE_GTP:
2798 : 0 : ret = mlx5dr_definer_conv_item_gtp(&cd, items, i);
2799 : 0 : item_flags |= MLX5_FLOW_LAYER_GTP;
2800 : 0 : break;
2801 : 0 : case RTE_FLOW_ITEM_TYPE_GTP_PSC:
2802 : 0 : ret = mlx5dr_definer_conv_item_gtp_psc(&cd, items, i);
2803 : 0 : item_flags |= MLX5_FLOW_LAYER_GTP_PSC;
2804 : 0 : break;
2805 : 0 : case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
2806 : 0 : ret = mlx5dr_definer_conv_item_port(&cd, items, i);
2807 : 0 : item_flags |= MLX5_FLOW_ITEM_REPRESENTED_PORT;
2808 : 0 : mt->vport_item_id = i;
2809 : 0 : break;
2810 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN:
2811 : 0 : ret = mlx5dr_definer_conv_item_vxlan(&cd, items, i);
2812 : 0 : item_flags |= MLX5_FLOW_LAYER_VXLAN;
2813 : 0 : break;
2814 : : case MLX5_RTE_FLOW_ITEM_TYPE_SQ:
2815 : : ret = mlx5dr_definer_conv_item_sq(&cd, items, i);
2816 : 0 : item_flags |= MLX5_FLOW_ITEM_SQ;
2817 : 0 : break;
2818 : 0 : case RTE_FLOW_ITEM_TYPE_TAG:
2819 : : case MLX5_RTE_FLOW_ITEM_TYPE_TAG:
2820 : 0 : ret = mlx5dr_definer_conv_item_tag(&cd, items, i);
2821 : 0 : item_flags |= MLX5_FLOW_ITEM_TAG;
2822 : 0 : break;
2823 : 0 : case RTE_FLOW_ITEM_TYPE_META:
2824 : 0 : ret = mlx5dr_definer_conv_item_metadata(&cd, items, i);
2825 : 0 : item_flags |= MLX5_FLOW_ITEM_METADATA;
2826 : 0 : break;
2827 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
2828 : 0 : ret = mlx5dr_definer_conv_item_gre(&cd, items, i);
2829 : 0 : item_flags |= MLX5_FLOW_LAYER_GRE;
2830 : 0 : break;
2831 : 0 : case RTE_FLOW_ITEM_TYPE_GRE_OPTION:
2832 : 0 : ret = mlx5dr_definer_conv_item_gre_opt(&cd, items, i);
2833 : 0 : item_flags |= MLX5_FLOW_LAYER_GRE;
2834 : 0 : break;
2835 : 0 : case RTE_FLOW_ITEM_TYPE_GRE_KEY:
2836 : 0 : ret = mlx5dr_definer_conv_item_gre_key(&cd, items, i);
2837 : 0 : item_flags |= MLX5_FLOW_LAYER_GRE_KEY;
2838 : 0 : break;
2839 : 0 : case RTE_FLOW_ITEM_TYPE_INTEGRITY:
2840 : 0 : ret = mlx5dr_definer_conv_item_integrity(&cd, items, i);
2841 : 0 : item_flags |= MLX5_FLOW_ITEM_INTEGRITY;
2842 : 0 : break;
2843 : 0 : case RTE_FLOW_ITEM_TYPE_CONNTRACK:
2844 : 0 : ret = mlx5dr_definer_conv_item_conntrack(&cd, items, i);
2845 : 0 : break;
2846 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP:
2847 : 0 : ret = mlx5dr_definer_conv_item_icmp(&cd, items, i);
2848 : 0 : item_flags |= MLX5_FLOW_LAYER_ICMP;
2849 : 0 : break;
2850 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP6:
2851 : 0 : ret = mlx5dr_definer_conv_item_icmp6(&cd, items, i);
2852 : 0 : item_flags |= MLX5_FLOW_LAYER_ICMP6;
2853 : 0 : break;
2854 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST:
2855 : : case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY:
2856 : 0 : ret = mlx5dr_definer_conv_item_icmp6_echo(&cd, items, i);
2857 : 0 : item_flags |= MLX5_FLOW_LAYER_ICMP6;
2858 : 0 : break;
2859 : 0 : case RTE_FLOW_ITEM_TYPE_METER_COLOR:
2860 : 0 : ret = mlx5dr_definer_conv_item_meter_color(&cd, items, i);
2861 : 0 : item_flags |= MLX5_FLOW_ITEM_METER_COLOR;
2862 : 0 : break;
2863 : 0 : case RTE_FLOW_ITEM_TYPE_QUOTA:
2864 : 0 : ret = mlx5dr_definer_conv_item_quota(&cd, items, i);
2865 : 0 : item_flags |= MLX5_FLOW_ITEM_QUOTA;
2866 : 0 : break;
2867 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
2868 : 0 : ret = mlx5dr_definer_conv_item_ipv6_routing_ext(&cd, items, i);
2869 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT :
2870 : : MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT;
2871 : 0 : break;
2872 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
2873 : 0 : ret = mlx5dr_definer_conv_item_esp(&cd, items, i);
2874 : 0 : item_flags |= MLX5_FLOW_ITEM_ESP;
2875 : 0 : break;
2876 : 0 : case RTE_FLOW_ITEM_TYPE_FLEX:
2877 : 0 : ret = mlx5dr_definer_conv_item_flex_parser(&cd, items, i);
2878 [ # # ]: 0 : item_flags |= cd.tunnel ? MLX5_FLOW_ITEM_INNER_FLEX :
2879 : : MLX5_FLOW_ITEM_OUTER_FLEX;
2880 : 0 : break;
2881 : 0 : case RTE_FLOW_ITEM_TYPE_MPLS:
2882 : 0 : ret = mlx5dr_definer_conv_item_mpls(&cd, items, i);
2883 : 0 : item_flags |= MLX5_FLOW_LAYER_MPLS;
2884 : 0 : cd.mpls_idx++;
2885 : 0 : break;
2886 : 0 : case RTE_FLOW_ITEM_TYPE_GENEVE:
2887 : 0 : ret = mlx5dr_definer_conv_item_geneve(&cd, items, i);
2888 : 0 : item_flags |= MLX5_FLOW_LAYER_GENEVE;
2889 : 0 : break;
2890 : 0 : case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
2891 : 0 : ret = mlx5dr_definer_conv_item_geneve_opt(&cd, items, i);
2892 : 0 : item_flags |= MLX5_FLOW_LAYER_GENEVE_OPT;
2893 : 0 : break;
2894 : 0 : case RTE_FLOW_ITEM_TYPE_IB_BTH:
2895 : 0 : ret = mlx5dr_definer_conv_item_ib_l4(&cd, items, i);
2896 : 0 : item_flags |= MLX5_FLOW_ITEM_IB_BTH;
2897 : 0 : break;
2898 : 0 : case RTE_FLOW_ITEM_TYPE_PTYPE:
2899 : 0 : ret = mlx5dr_definer_conv_item_ptype(&cd, items, i);
2900 : 0 : item_flags |= MLX5_FLOW_ITEM_PTYPE;
2901 : 0 : break;
2902 : 0 : case RTE_FLOW_ITEM_TYPE_RANDOM:
2903 : 0 : ret = mlx5dr_definer_conv_item_random(&cd, items, i);
2904 : 0 : item_flags |= MLX5_FLOW_ITEM_RANDOM;
2905 : 0 : break;
2906 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
2907 : 0 : ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i);
2908 : 0 : item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE;
2909 : 0 : break;
2910 : 0 : default:
2911 : 0 : DR_LOG(ERR, "Unsupported item type %d", items->type);
2912 : 0 : rte_errno = ENOTSUP;
2913 : 0 : return rte_errno;
2914 : : }
2915 : :
2916 : 0 : cd.last_item = items->type;
2917 : :
2918 [ # # ]: 0 : if (ret) {
2919 : 0 : DR_LOG(ERR, "Failed processing item type: %d", items->type);
2920 : 0 : return ret;
2921 : : }
2922 : : }
2923 : :
2924 : 0 : mt->item_flags = item_flags;
2925 : :
2926 : : /* Fill in headers layout and allocate fc & fcr array on mt */
2927 : 0 : ret = mlx5dr_definer_mt_set_fc(mt, fc, hl);
2928 [ # # ]: 0 : if (ret) {
2929 : 0 : DR_LOG(ERR, "Failed to set field copy to match template");
2930 : 0 : return ret;
2931 : : }
2932 : :
2933 : : return 0;
2934 : : }
2935 : :
2936 : : static int
2937 [ # # ]: 0 : mlx5dr_definer_find_byte_in_tag(struct mlx5dr_definer *definer,
2938 : : uint32_t hl_byte_off,
2939 : : uint32_t *tag_byte_off)
2940 : : {
2941 : : uint8_t byte_offset;
2942 : : int i, dw_to_scan;
2943 : :
2944 : : /* Avoid accessing unused DW selectors */
2945 : : dw_to_scan = mlx5dr_definer_is_jumbo(definer) ?
2946 [ # # ]: 0 : DW_SELECTORS : DW_SELECTORS_MATCH;
2947 : :
2948 : : /* Add offset since each DW covers multiple BYTEs */
2949 : 0 : byte_offset = hl_byte_off % DW_SIZE;
2950 [ # # ]: 0 : for (i = 0; i < dw_to_scan; i++) {
2951 [ # # ]: 0 : if (definer->dw_selector[i] == hl_byte_off / DW_SIZE) {
2952 : 0 : *tag_byte_off = byte_offset + DW_SIZE * (DW_SELECTORS - i - 1);
2953 : 0 : return 0;
2954 : : }
2955 : : }
2956 : :
2957 : : /* Add offset to skip DWs in definer */
2958 : : byte_offset = DW_SIZE * DW_SELECTORS;
2959 : : /* Iterate in reverse since the code uses bytes from 7 -> 0 */
2960 [ # # ]: 0 : for (i = BYTE_SELECTORS; i-- > 0 ;) {
2961 [ # # ]: 0 : if (definer->byte_selector[i] == hl_byte_off) {
2962 : 0 : *tag_byte_off = byte_offset + (BYTE_SELECTORS - i - 1);
2963 : 0 : return 0;
2964 : : }
2965 : : }
2966 : :
2967 : : /* The hl byte offset must be part of the definer */
2968 : 0 : DR_LOG(INFO, "Failed to map to definer, HL byte [%d] not found", byte_offset);
2969 : 0 : rte_errno = EINVAL;
2970 : 0 : return rte_errno;
2971 : : }
2972 : :
2973 : : static int
2974 : 0 : mlx5dr_definer_fc_bind(struct mlx5dr_definer *definer,
2975 : : struct mlx5dr_definer_fc *fc,
2976 : : uint32_t fc_sz)
2977 : : {
2978 : 0 : uint32_t tag_offset = 0;
2979 : : int ret, byte_diff;
2980 : : uint32_t i;
2981 : :
2982 [ # # ]: 0 : for (i = 0; i < fc_sz; i++) {
2983 : : /* Map header layout byte offset to byte offset in tag */
2984 : 0 : ret = mlx5dr_definer_find_byte_in_tag(definer, fc->byte_off, &tag_offset);
2985 [ # # ]: 0 : if (ret)
2986 : 0 : return ret;
2987 : :
2988 : : /* Move setter based on the location in the definer */
2989 : 0 : byte_diff = fc->byte_off % DW_SIZE - tag_offset % DW_SIZE;
2990 : 0 : fc->bit_off = fc->bit_off + byte_diff * BITS_IN_BYTE;
2991 : :
2992 : : /* Update offset in headers layout to offset in tag */
2993 : 0 : fc->byte_off = tag_offset;
2994 : 0 : fc++;
2995 : : }
2996 : :
2997 : : return 0;
2998 : : }
2999 : :
3000 : : static bool
3001 : 0 : mlx5dr_definer_best_hl_fit_recu(struct mlx5dr_definer_sel_ctrl *ctrl,
3002 : : uint32_t cur_dw,
3003 : : uint32_t *data)
3004 : : {
3005 : : uint8_t bytes_set;
3006 : : int byte_idx;
3007 : : bool ret;
3008 : : int i;
3009 : :
3010 : : /* Reached end, nothing left to do */
3011 [ # # ]: 0 : if (cur_dw == MLX5_ST_SZ_DW(definer_hl))
3012 : : return true;
3013 : :
3014 : : /* No data set, can skip to next DW */
3015 [ # # ]: 0 : while (!*data) {
3016 : 0 : cur_dw++;
3017 : 0 : data++;
3018 : :
3019 : : /* Reached end, nothing left to do */
3020 [ # # ]: 0 : if (cur_dw == MLX5_ST_SZ_DW(definer_hl))
3021 : : return true;
3022 : : }
3023 : :
3024 : : /* Used all DW selectors and Byte selectors, no possible solution */
3025 [ # # ]: 0 : if (ctrl->allowed_full_dw == ctrl->used_full_dw &&
3026 [ # # ]: 0 : ctrl->allowed_lim_dw == ctrl->used_lim_dw &&
3027 [ # # ]: 0 : ctrl->allowed_bytes == ctrl->used_bytes)
3028 : : return false;
3029 : :
3030 : : /* Try to use limited DW selectors */
3031 [ # # # # ]: 0 : if (ctrl->allowed_lim_dw > ctrl->used_lim_dw && cur_dw < 64) {
3032 : 0 : ctrl->lim_dw_selector[ctrl->used_lim_dw++] = cur_dw;
3033 : :
3034 : 0 : ret = mlx5dr_definer_best_hl_fit_recu(ctrl, cur_dw + 1, data + 1);
3035 [ # # ]: 0 : if (ret)
3036 : : return ret;
3037 : :
3038 : 0 : ctrl->lim_dw_selector[--ctrl->used_lim_dw] = 0;
3039 : : }
3040 : :
3041 : : /* Try to use DW selectors */
3042 [ # # ]: 0 : if (ctrl->allowed_full_dw > ctrl->used_full_dw) {
3043 : 0 : ctrl->full_dw_selector[ctrl->used_full_dw++] = cur_dw;
3044 : :
3045 : 0 : ret = mlx5dr_definer_best_hl_fit_recu(ctrl, cur_dw + 1, data + 1);
3046 [ # # ]: 0 : if (ret)
3047 : : return ret;
3048 : :
3049 : 0 : ctrl->full_dw_selector[--ctrl->used_full_dw] = 0;
3050 : : }
3051 : :
3052 : : /* No byte selector for offset bigger than 255 */
3053 [ # # ]: 0 : if (cur_dw * DW_SIZE > 255)
3054 : : return false;
3055 : :
3056 : 0 : bytes_set = !!(0x000000ff & *data) +
3057 : 0 : !!(0x0000ff00 & *data) +
3058 : 0 : !!(0x00ff0000 & *data) +
3059 : 0 : !!(0xff000000 & *data);
3060 : :
3061 : : /* Check if there are enough byte selectors left */
3062 [ # # ]: 0 : if (bytes_set + ctrl->used_bytes > ctrl->allowed_bytes)
3063 : : return false;
3064 : :
3065 : : /* Try to use Byte selectors */
3066 [ # # ]: 0 : for (i = 0; i < DW_SIZE; i++)
3067 [ # # # # ]: 0 : if ((0xff000000 >> (i * BITS_IN_BYTE)) & rte_be_to_cpu_32(*data)) {
3068 : : /* Use byte selectors high to low */
3069 : 0 : byte_idx = ctrl->allowed_bytes - ctrl->used_bytes - 1;
3070 : 0 : ctrl->byte_selector[byte_idx] = cur_dw * DW_SIZE + i;
3071 : 0 : ctrl->used_bytes++;
3072 : : }
3073 : :
3074 : 0 : ret = mlx5dr_definer_best_hl_fit_recu(ctrl, cur_dw + 1, data + 1);
3075 [ # # ]: 0 : if (ret)
3076 : : return ret;
3077 : :
3078 [ # # ]: 0 : for (i = 0; i < DW_SIZE; i++)
3079 [ # # # # ]: 0 : if ((0xff << (i * BITS_IN_BYTE)) & rte_be_to_cpu_32(*data)) {
3080 : 0 : ctrl->used_bytes--;
3081 : 0 : byte_idx = ctrl->allowed_bytes - ctrl->used_bytes - 1;
3082 : 0 : ctrl->byte_selector[byte_idx] = 0;
3083 : : }
3084 : :
3085 : : return false;
3086 : : }
3087 : :
3088 : : static void
3089 : 0 : mlx5dr_definer_copy_sel_ctrl(struct mlx5dr_definer_sel_ctrl *ctrl,
3090 : : struct mlx5dr_definer *definer)
3091 : : {
3092 : 0 : memcpy(definer->byte_selector, ctrl->byte_selector, ctrl->allowed_bytes);
3093 : 0 : memcpy(definer->dw_selector, ctrl->full_dw_selector, ctrl->allowed_full_dw);
3094 : 0 : memcpy(definer->dw_selector + ctrl->allowed_full_dw,
3095 : 0 : ctrl->lim_dw_selector, ctrl->allowed_lim_dw);
3096 : 0 : }
3097 : :
3098 : : static int
3099 : 0 : mlx5dr_definer_find_best_range_fit(struct mlx5dr_definer *definer,
3100 : : struct mlx5dr_matcher *matcher)
3101 : : {
3102 : 0 : uint8_t tag_byte_offset[MLX5DR_DEFINER_FNAME_MAX] = {0};
3103 : 0 : uint8_t field_select[MLX5DR_DEFINER_FNAME_MAX] = {0};
3104 : 0 : struct mlx5dr_definer_sel_ctrl ctrl = {0};
3105 : : uint32_t byte_offset, algn_byte_off;
3106 : : struct mlx5dr_definer_fc *fcr;
3107 : : bool require_dw;
3108 : : int idx, i, j;
3109 : :
3110 : : /* Try to create a range definer */
3111 : 0 : ctrl.allowed_full_dw = DW_SELECTORS_RANGE;
3112 : 0 : ctrl.allowed_bytes = BYTE_SELECTORS_RANGE;
3113 : :
3114 : : /* Multiple fields cannot share the same DW for range match.
3115 : : * The HW doesn't recognize each field but compares the full dw.
3116 : : * For example definer DW consists of FieldA_FieldB
3117 : : * FieldA: Mask 0xFFFF range 0x1 to 0x2
3118 : : * FieldB: Mask 0xFFFF range 0x3 to 0x4
3119 : : * STE DW range will be 0x00010003 - 0x00020004
3120 : : * This will cause invalid match for FieldB if FieldA=1 and FieldB=8
3121 : : * Since 0x10003 < 0x10008 < 0x20004
3122 : : */
3123 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++) {
3124 [ # # ]: 0 : for (j = 0; j < matcher->mt[i].fcr_sz; j++) {
3125 : 0 : fcr = &matcher->mt[i].fcr[j];
3126 : :
3127 : : /* Found - Reuse previous mt binding */
3128 [ # # ]: 0 : if (field_select[fcr->fname]) {
3129 : 0 : fcr->byte_off = tag_byte_offset[fcr->fname];
3130 : 0 : continue;
3131 : : }
3132 : :
3133 : : /* Not found */
3134 : 0 : require_dw = fcr->byte_off >= (64 * DW_SIZE);
3135 [ # # # # ]: 0 : if (require_dw || ctrl.used_bytes == ctrl.allowed_bytes) {
3136 : : /* Try to cover using DW selector */
3137 [ # # ]: 0 : if (ctrl.used_full_dw == ctrl.allowed_full_dw)
3138 : 0 : goto not_supported;
3139 : :
3140 : 0 : ctrl.full_dw_selector[ctrl.used_full_dw++] =
3141 : 0 : fcr->byte_off / DW_SIZE;
3142 : :
3143 : : /* Bind DW */
3144 : 0 : idx = ctrl.used_full_dw - 1;
3145 : 0 : byte_offset = fcr->byte_off % DW_SIZE;
3146 : 0 : byte_offset += DW_SIZE * (DW_SELECTORS - idx - 1);
3147 : : } else {
3148 : : /* Try to cover using Bytes selectors */
3149 : : if (ctrl.used_bytes == ctrl.allowed_bytes)
3150 : : goto not_supported;
3151 : :
3152 : 0 : algn_byte_off = DW_SIZE * (fcr->byte_off / DW_SIZE);
3153 : 0 : ctrl.byte_selector[ctrl.used_bytes++] = algn_byte_off + 3;
3154 : 0 : ctrl.byte_selector[ctrl.used_bytes++] = algn_byte_off + 2;
3155 : 0 : ctrl.byte_selector[ctrl.used_bytes++] = algn_byte_off + 1;
3156 : 0 : ctrl.byte_selector[ctrl.used_bytes++] = algn_byte_off;
3157 : :
3158 : : /* Bind BYTE */
3159 : : byte_offset = DW_SIZE * DW_SELECTORS;
3160 : 0 : byte_offset += BYTE_SELECTORS - ctrl.used_bytes;
3161 : 0 : byte_offset += fcr->byte_off % DW_SIZE;
3162 : : }
3163 : :
3164 : 0 : fcr->byte_off = byte_offset;
3165 : 0 : tag_byte_offset[fcr->fname] = byte_offset;
3166 : 0 : field_select[fcr->fname] = 1;
3167 : : }
3168 : : }
3169 : :
3170 : 0 : mlx5dr_definer_copy_sel_ctrl(&ctrl, definer);
3171 : 0 : definer->type = MLX5DR_DEFINER_TYPE_RANGE;
3172 : :
3173 : 0 : return 0;
3174 : :
3175 : : not_supported:
3176 : 0 : DR_LOG(ERR, "Unable to find supporting range definer combination");
3177 : 0 : rte_errno = ENOTSUP;
3178 : 0 : return rte_errno;
3179 : : }
3180 : :
3181 : : static int
3182 : 0 : mlx5dr_definer_find_best_match_fit(struct mlx5dr_context *ctx,
3183 : : struct mlx5dr_definer *definer,
3184 : : uint8_t *hl)
3185 : : {
3186 : 0 : struct mlx5dr_definer_sel_ctrl ctrl = {0};
3187 : : bool found;
3188 : :
3189 : : /* Try to create a match definer */
3190 : 0 : ctrl.allowed_full_dw = DW_SELECTORS_MATCH;
3191 : : ctrl.allowed_lim_dw = 0;
3192 : 0 : ctrl.allowed_bytes = BYTE_SELECTORS;
3193 : :
3194 : 0 : found = mlx5dr_definer_best_hl_fit_recu(&ctrl, 0, (uint32_t *)hl);
3195 [ # # ]: 0 : if (found) {
3196 : 0 : mlx5dr_definer_copy_sel_ctrl(&ctrl, definer);
3197 : 0 : definer->type = MLX5DR_DEFINER_TYPE_MATCH;
3198 : 0 : return 0;
3199 : : }
3200 : :
3201 : : /* Try to create a full/limited jumbo definer */
3202 [ # # ]: 0 : ctrl.allowed_full_dw = ctx->caps->full_dw_jumbo_support ? DW_SELECTORS :
3203 : : DW_SELECTORS_MATCH;
3204 [ # # ]: 0 : ctrl.allowed_lim_dw = ctx->caps->full_dw_jumbo_support ? 0 :
3205 : : DW_SELECTORS_LIMITED;
3206 : : ctrl.allowed_bytes = BYTE_SELECTORS;
3207 : :
3208 : 0 : found = mlx5dr_definer_best_hl_fit_recu(&ctrl, 0, (uint32_t *)hl);
3209 [ # # ]: 0 : if (found) {
3210 : 0 : mlx5dr_definer_copy_sel_ctrl(&ctrl, definer);
3211 : 0 : definer->type = MLX5DR_DEFINER_TYPE_JUMBO;
3212 : 0 : return 0;
3213 : : }
3214 : :
3215 : 0 : DR_LOG(ERR, "Unable to find supporting match/jumbo definer combination");
3216 : 0 : rte_errno = ENOTSUP;
3217 : 0 : return rte_errno;
3218 : : }
3219 : :
3220 : : static void
3221 : 0 : mlx5dr_definer_create_tag_mask(struct rte_flow_item *items,
3222 : : struct mlx5dr_definer_fc *fc,
3223 : : uint32_t fc_sz,
3224 : : uint8_t *tag)
3225 : : {
3226 : : uint32_t i;
3227 : :
3228 [ # # ]: 0 : for (i = 0; i < fc_sz; i++) {
3229 [ # # ]: 0 : if (fc->tag_mask_set)
3230 : 0 : fc->tag_mask_set(fc, items[fc->item_idx].mask, tag);
3231 : : else
3232 : 0 : fc->tag_set(fc, items[fc->item_idx].mask, tag);
3233 : 0 : fc++;
3234 : : }
3235 : 0 : }
3236 : :
3237 : 0 : void mlx5dr_definer_create_tag(const struct rte_flow_item *items,
3238 : : struct mlx5dr_definer_fc *fc,
3239 : : uint32_t fc_sz,
3240 : : uint8_t *tag)
3241 : : {
3242 : : uint32_t i;
3243 : :
3244 [ # # ]: 0 : for (i = 0; i < fc_sz; i++) {
3245 : 0 : fc->tag_set(fc, items[fc->item_idx].spec, tag);
3246 : 0 : fc++;
3247 : : }
3248 : 0 : }
3249 : :
3250 : : static uint32_t mlx5dr_definer_get_range_byte_off(uint32_t match_byte_off)
3251 : : {
3252 : 0 : uint8_t curr_dw_idx = match_byte_off / DW_SIZE;
3253 : : uint8_t new_dw_idx;
3254 : :
3255 : : /* Range DW can have the following values 7,8,9,10
3256 : : * -DW7 is mapped to DW9
3257 : : * -DW8 is mapped to DW7
3258 : : * -DW9 is mapped to DW5
3259 : : * -DW10 is mapped to DW3
3260 : : * To reduce calculation the following formula is used:
3261 : : */
3262 : 0 : new_dw_idx = curr_dw_idx * (-2) + 23;
3263 : :
3264 : 0 : return new_dw_idx * DW_SIZE + match_byte_off % DW_SIZE;
3265 : : }
3266 : :
3267 : 0 : void mlx5dr_definer_create_tag_range(const struct rte_flow_item *items,
3268 : : struct mlx5dr_definer_fc *fc,
3269 : : uint32_t fc_sz,
3270 : : uint8_t *tag)
3271 : : {
3272 : : struct mlx5dr_definer_fc tmp_fc;
3273 : : uint32_t i;
3274 : :
3275 [ # # ]: 0 : for (i = 0; i < fc_sz; i++) {
3276 : 0 : tmp_fc = *fc;
3277 : : /* Set MAX value */
3278 : 0 : tmp_fc.byte_off = mlx5dr_definer_get_range_byte_off(fc->byte_off);
3279 : 0 : tmp_fc.tag_set(&tmp_fc, items[fc->item_idx].last, tag);
3280 : : /* Set MIN value */
3281 : 0 : tmp_fc.byte_off += DW_SIZE;
3282 : 0 : tmp_fc.tag_set(&tmp_fc, items[fc->item_idx].spec, tag);
3283 : 0 : fc++;
3284 : : }
3285 : 0 : }
3286 : :
3287 : 0 : int mlx5dr_definer_get_id(struct mlx5dr_definer *definer)
3288 : : {
3289 : 0 : return definer->obj->id;
3290 : : }
3291 : :
3292 : : static int
3293 : 0 : mlx5dr_definer_compare(struct mlx5dr_definer *definer_a,
3294 : : struct mlx5dr_definer *definer_b)
3295 : : {
3296 : : int i;
3297 : :
3298 : : /* Future: Optimize by comparing selectors with valid mask only */
3299 [ # # ]: 0 : for (i = 0; i < BYTE_SELECTORS; i++)
3300 [ # # ]: 0 : if (definer_a->byte_selector[i] != definer_b->byte_selector[i])
3301 : : return 1;
3302 : :
3303 [ # # ]: 0 : for (i = 0; i < DW_SELECTORS; i++)
3304 [ # # ]: 0 : if (definer_a->dw_selector[i] != definer_b->dw_selector[i])
3305 : : return 1;
3306 : :
3307 [ # # ]: 0 : for (i = 0; i < MLX5DR_JUMBO_TAG_SZ; i++)
3308 [ # # ]: 0 : if (definer_a->mask.jumbo[i] != definer_b->mask.jumbo[i])
3309 : : return 1;
3310 : :
3311 : : return 0;
3312 : : }
3313 : :
3314 : : static int
3315 : 0 : mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher,
3316 : : struct mlx5dr_definer *match_definer,
3317 : : struct mlx5dr_definer *range_definer)
3318 : : {
3319 : 0 : struct mlx5dr_context *ctx = matcher->tbl->ctx;
3320 : 0 : struct mlx5dr_match_template *mt = matcher->mt;
3321 : : uint8_t *match_hl;
3322 : : int i, ret;
3323 : :
3324 : : /* Union header-layout (hl) is used for creating a single definer
3325 : : * field layout used with different bitmasks for hash and match.
3326 : : */
3327 : : match_hl = simple_calloc(1, MLX5_ST_SZ_BYTES(definer_hl));
3328 [ # # ]: 0 : if (!match_hl) {
3329 : 0 : DR_LOG(ERR, "Failed to allocate memory for header layout");
3330 : 0 : rte_errno = ENOMEM;
3331 : 0 : return rte_errno;
3332 : : }
3333 : :
3334 : : /* Convert all mt items to header layout (hl)
3335 : : * and allocate the match and range field copy array (fc & fcr).
3336 : : */
3337 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++) {
3338 : 0 : ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl);
3339 [ # # ]: 0 : if (ret) {
3340 : 0 : DR_LOG(ERR, "Failed to convert items to header layout");
3341 : 0 : goto free_fc;
3342 : : }
3343 : : }
3344 : :
3345 : : /* Find the match definer layout for header layout match union */
3346 : 0 : ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl);
3347 [ # # ]: 0 : if (ret) {
3348 : 0 : DR_LOG(ERR, "Failed to create match definer from header layout");
3349 : 0 : goto free_fc;
3350 : : }
3351 : :
3352 : : /* Find the range definer layout for match templates fcrs */
3353 : 0 : ret = mlx5dr_definer_find_best_range_fit(range_definer, matcher);
3354 [ # # ]: 0 : if (ret) {
3355 : 0 : DR_LOG(ERR, "Failed to create range definer from header layout");
3356 : 0 : goto free_fc;
3357 : : }
3358 : :
3359 : : simple_free(match_hl);
3360 : 0 : return 0;
3361 : :
3362 : : free_fc:
3363 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++)
3364 [ # # ]: 0 : if (mt[i].fc)
3365 : : simple_free(mt[i].fc);
3366 : :
3367 : : simple_free(match_hl);
3368 : 0 : return rte_errno;
3369 : : }
3370 : :
3371 : 0 : int mlx5dr_definer_init_cache(struct mlx5dr_definer_cache **cache)
3372 : : {
3373 : : struct mlx5dr_definer_cache *new_cache;
3374 : :
3375 : : new_cache = simple_calloc(1, sizeof(*new_cache));
3376 [ # # ]: 0 : if (!new_cache) {
3377 : 0 : rte_errno = ENOMEM;
3378 : 0 : return rte_errno;
3379 : : }
3380 : 0 : LIST_INIT(&new_cache->head);
3381 : 0 : *cache = new_cache;
3382 : :
3383 : 0 : return 0;
3384 : : }
3385 : :
3386 : 0 : void mlx5dr_definer_uninit_cache(struct mlx5dr_definer_cache *cache)
3387 : : {
3388 : : simple_free(cache);
3389 : 0 : }
3390 : :
3391 : : static struct mlx5dr_devx_obj *
3392 : 0 : mlx5dr_definer_get_obj(struct mlx5dr_context *ctx,
3393 : : struct mlx5dr_definer *definer)
3394 : : {
3395 : 0 : struct mlx5dr_definer_cache *cache = ctx->definer_cache;
3396 : 0 : struct mlx5dr_cmd_definer_create_attr def_attr = {0};
3397 : : struct mlx5dr_definer_cache_item *cached_definer;
3398 : : struct mlx5dr_devx_obj *obj;
3399 : :
3400 : : /* Search definer cache for requested definer */
3401 [ # # ]: 0 : LIST_FOREACH(cached_definer, &cache->head, next) {
3402 [ # # ]: 0 : if (mlx5dr_definer_compare(&cached_definer->definer, definer))
3403 : : continue;
3404 : :
3405 : : /* Reuse definer and set LRU (move to be first in the list) */
3406 [ # # ]: 0 : LIST_REMOVE(cached_definer, next);
3407 [ # # ]: 0 : LIST_INSERT_HEAD(&cache->head, cached_definer, next);
3408 : 0 : cached_definer->refcount++;
3409 : 0 : return cached_definer->definer.obj;
3410 : : }
3411 : :
3412 : : /* Allocate and create definer based on the bitmask tag */
3413 : 0 : def_attr.match_mask = definer->mask.jumbo;
3414 : 0 : def_attr.dw_selector = definer->dw_selector;
3415 : 0 : def_attr.byte_selector = definer->byte_selector;
3416 : :
3417 : 0 : obj = mlx5dr_cmd_definer_create(ctx->ibv_ctx, &def_attr);
3418 [ # # ]: 0 : if (!obj)
3419 : : return NULL;
3420 : :
3421 : : cached_definer = simple_calloc(1, sizeof(*cached_definer));
3422 [ # # ]: 0 : if (!cached_definer) {
3423 : 0 : rte_errno = ENOMEM;
3424 : 0 : goto free_definer_obj;
3425 : : }
3426 : :
3427 [ # # ]: 0 : memcpy(&cached_definer->definer, definer, sizeof(*definer));
3428 : 0 : cached_definer->definer.obj = obj;
3429 : 0 : cached_definer->refcount = 1;
3430 [ # # ]: 0 : LIST_INSERT_HEAD(&cache->head, cached_definer, next);
3431 : :
3432 : 0 : return obj;
3433 : :
3434 : : free_definer_obj:
3435 : 0 : mlx5dr_cmd_destroy_obj(obj);
3436 : 0 : return NULL;
3437 : : }
3438 : :
3439 : : static void
3440 : 0 : mlx5dr_definer_put_obj(struct mlx5dr_context *ctx,
3441 : : struct mlx5dr_devx_obj *obj)
3442 : : {
3443 : : struct mlx5dr_definer_cache_item *cached_definer;
3444 : :
3445 [ # # ]: 0 : LIST_FOREACH(cached_definer, &ctx->definer_cache->head, next) {
3446 [ # # ]: 0 : if (cached_definer->definer.obj != obj)
3447 : : continue;
3448 : :
3449 : : /* Object found */
3450 [ # # ]: 0 : if (--cached_definer->refcount)
3451 : : return;
3452 : :
3453 [ # # ]: 0 : LIST_REMOVE(cached_definer, next);
3454 : 0 : mlx5dr_cmd_destroy_obj(cached_definer->definer.obj);
3455 : : simple_free(cached_definer);
3456 : : return;
3457 : : }
3458 : :
3459 : : /* Programming error, object must be part of cache */
3460 : 0 : assert(false);
3461 : : }
3462 : :
3463 : : static struct mlx5dr_definer *
3464 : 0 : mlx5dr_definer_alloc(struct mlx5dr_context *ctx,
3465 : : struct mlx5dr_definer_fc *fc,
3466 : : int fc_sz,
3467 : : struct rte_flow_item *items,
3468 : : struct mlx5dr_definer *layout,
3469 : : bool bind_fc)
3470 : : {
3471 : : struct mlx5dr_definer *definer;
3472 : : int ret;
3473 : :
3474 : : definer = simple_calloc(1, sizeof(*definer));
3475 [ # # ]: 0 : if (!definer) {
3476 : 0 : DR_LOG(ERR, "Failed to allocate memory for definer");
3477 : 0 : rte_errno = ENOMEM;
3478 : 0 : return NULL;
3479 : : }
3480 : :
3481 : : memcpy(definer, layout, sizeof(*definer));
3482 : :
3483 : : /* Align field copy array based on given layout */
3484 [ # # ]: 0 : if (bind_fc) {
3485 : 0 : ret = mlx5dr_definer_fc_bind(definer, fc, fc_sz);
3486 [ # # ]: 0 : if (ret) {
3487 : 0 : DR_LOG(ERR, "Failed to bind field copy to definer");
3488 : 0 : goto free_definer;
3489 : : }
3490 : : }
3491 : :
3492 : : /* Create the tag mask used for definer creation */
3493 : 0 : mlx5dr_definer_create_tag_mask(items, fc, fc_sz, definer->mask.jumbo);
3494 : :
3495 : 0 : definer->obj = mlx5dr_definer_get_obj(ctx, definer);
3496 [ # # ]: 0 : if (!definer->obj)
3497 : 0 : goto free_definer;
3498 : :
3499 : : return definer;
3500 : :
3501 : 0 : free_definer:
3502 : : simple_free(definer);
3503 : 0 : return NULL;
3504 : : }
3505 : :
3506 : : static void
3507 : : mlx5dr_definer_free(struct mlx5dr_context *ctx,
3508 : : struct mlx5dr_definer *definer)
3509 : : {
3510 : 0 : mlx5dr_definer_put_obj(ctx, definer->obj);
3511 : : simple_free(definer);
3512 : 0 : }
3513 : :
3514 : : static int
3515 : 0 : mlx5dr_definer_matcher_match_init(struct mlx5dr_context *ctx,
3516 : : struct mlx5dr_matcher *matcher,
3517 : : struct mlx5dr_definer *match_layout)
3518 : : {
3519 : 0 : struct mlx5dr_match_template *mt = matcher->mt;
3520 : : int i;
3521 : :
3522 : : /* Create mendatory match definer */
3523 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++) {
3524 : 0 : mt[i].definer = mlx5dr_definer_alloc(ctx,
3525 : : mt[i].fc,
3526 : 0 : mt[i].fc_sz,
3527 : 0 : mt[i].items,
3528 : : match_layout,
3529 : : true);
3530 [ # # ]: 0 : if (!mt[i].definer) {
3531 : 0 : DR_LOG(ERR, "Failed to create match definer");
3532 : 0 : goto free_definers;
3533 : : }
3534 : : }
3535 : : return 0;
3536 : :
3537 : : free_definers:
3538 [ # # ]: 0 : while (i--)
3539 : 0 : mlx5dr_definer_free(ctx, mt[i].definer);
3540 : :
3541 : 0 : return rte_errno;
3542 : : }
3543 : :
3544 : : static void
3545 : 0 : mlx5dr_definer_matcher_match_uninit(struct mlx5dr_matcher *matcher)
3546 : : {
3547 : 0 : struct mlx5dr_context *ctx = matcher->tbl->ctx;
3548 : : int i;
3549 : :
3550 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++)
3551 : 0 : mlx5dr_definer_free(ctx, matcher->mt[i].definer);
3552 : 0 : }
3553 : :
3554 : : static int
3555 : 0 : mlx5dr_definer_matcher_range_init(struct mlx5dr_context *ctx,
3556 : : struct mlx5dr_matcher *matcher,
3557 : : struct mlx5dr_definer *range_layout)
3558 : : {
3559 : 0 : struct mlx5dr_match_template *mt = matcher->mt;
3560 : : int i;
3561 : :
3562 : : /* Create optional range definers */
3563 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++) {
3564 [ # # ]: 0 : if (!mt[i].fcr_sz)
3565 : 0 : continue;
3566 : :
3567 : : /* All must use range if requested */
3568 [ # # # # ]: 0 : if (i && !mt[i - 1].range_definer) {
3569 : 0 : DR_LOG(ERR, "Using range and non range templates is not allowed");
3570 : 0 : goto free_definers;
3571 : : }
3572 : :
3573 : 0 : matcher->flags |= MLX5DR_MATCHER_FLAGS_RANGE_DEFINER;
3574 : : /* Create definer without fcr binding, already binded */
3575 : 0 : mt[i].range_definer = mlx5dr_definer_alloc(ctx,
3576 : : mt[i].fcr,
3577 : : mt[i].fcr_sz,
3578 : : mt[i].items,
3579 : : range_layout,
3580 : : false);
3581 [ # # ]: 0 : if (!mt[i].range_definer) {
3582 : 0 : DR_LOG(ERR, "Failed to create match definer");
3583 : 0 : goto free_definers;
3584 : : }
3585 : : }
3586 : : return 0;
3587 : :
3588 : : free_definers:
3589 [ # # ]: 0 : while (i--)
3590 [ # # ]: 0 : if (mt[i].range_definer)
3591 : : mlx5dr_definer_free(ctx, mt[i].range_definer);
3592 : :
3593 : 0 : return rte_errno;
3594 : : }
3595 : :
3596 : : static void
3597 : 0 : mlx5dr_definer_matcher_range_uninit(struct mlx5dr_matcher *matcher)
3598 : : {
3599 : 0 : struct mlx5dr_context *ctx = matcher->tbl->ctx;
3600 : : int i;
3601 : :
3602 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++)
3603 [ # # ]: 0 : if (matcher->mt[i].range_definer)
3604 : : mlx5dr_definer_free(ctx, matcher->mt[i].range_definer);
3605 : 0 : }
3606 : :
3607 : : static int
3608 : 0 : mlx5dr_definer_matcher_hash_init(struct mlx5dr_context *ctx,
3609 : : struct mlx5dr_matcher *matcher)
3610 : : {
3611 : 0 : struct mlx5dr_cmd_definer_create_attr def_attr = {0};
3612 : 0 : struct mlx5dr_match_template *mt = matcher->mt;
3613 : 0 : struct ibv_context *ibv_ctx = ctx->ibv_ctx;
3614 : : uint8_t *bit_mask;
3615 : : int i, j;
3616 : :
3617 [ # # ]: 0 : for (i = 1; i < matcher->num_of_mt; i++)
3618 [ # # ]: 0 : if (mlx5dr_definer_compare(mt[i].definer, mt[i - 1].definer))
3619 : 0 : matcher->flags |= MLX5DR_MATCHER_FLAGS_HASH_DEFINER;
3620 : :
3621 [ # # ]: 0 : if (!(matcher->flags & MLX5DR_MATCHER_FLAGS_HASH_DEFINER))
3622 : : return 0;
3623 : :
3624 : : /* Insert by index requires all MT using the same definer */
3625 [ # # ]: 0 : if (matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) {
3626 : 0 : DR_LOG(ERR, "Insert by index not supported with MT combination");
3627 : 0 : rte_errno = EOPNOTSUPP;
3628 : 0 : return rte_errno;
3629 : : }
3630 : :
3631 : 0 : matcher->hash_definer = simple_calloc(1, sizeof(*matcher->hash_definer));
3632 [ # # ]: 0 : if (!matcher->hash_definer) {
3633 : 0 : DR_LOG(ERR, "Failed to allocate memory for hash definer");
3634 : 0 : rte_errno = ENOMEM;
3635 : 0 : return rte_errno;
3636 : : }
3637 : :
3638 : : /* Calculate intersection between all match templates bitmasks.
3639 : : * We will use mt[0] as reference and intersect it with mt[1..n].
3640 : : * From this we will get:
3641 : : * hash_definer.selectors = mt[0].selecotrs
3642 : : * hash_definer.mask = mt[0].mask & mt[0].mask & ... & mt[n].mask
3643 : : */
3644 : :
3645 : : /* Use first definer which should also contain intersection fields */
3646 : 0 : memcpy(matcher->hash_definer, mt->definer, sizeof(struct mlx5dr_definer));
3647 : :
3648 : : /* Calculate intersection between first to all match templates bitmasks */
3649 [ # # ]: 0 : for (i = 1; i < matcher->num_of_mt; i++) {
3650 : 0 : bit_mask = (uint8_t *)&mt[i].definer->mask;
3651 [ # # ]: 0 : for (j = 0; j < MLX5DR_JUMBO_TAG_SZ; j++)
3652 : 0 : ((uint8_t *)&matcher->hash_definer->mask)[j] &= bit_mask[j];
3653 : : }
3654 : :
3655 : 0 : def_attr.match_mask = matcher->hash_definer->mask.jumbo;
3656 : 0 : def_attr.dw_selector = matcher->hash_definer->dw_selector;
3657 : 0 : def_attr.byte_selector = matcher->hash_definer->byte_selector;
3658 : 0 : matcher->hash_definer->obj = mlx5dr_cmd_definer_create(ibv_ctx, &def_attr);
3659 [ # # ]: 0 : if (!matcher->hash_definer->obj) {
3660 : 0 : DR_LOG(ERR, "Failed to create hash definer");
3661 : 0 : goto free_hash_definer;
3662 : : }
3663 : :
3664 : : return 0;
3665 : :
3666 : : free_hash_definer:
3667 : 0 : simple_free(matcher->hash_definer);
3668 : 0 : return rte_errno;
3669 : : }
3670 : :
3671 : : static void
3672 : 0 : mlx5dr_definer_matcher_hash_uninit(struct mlx5dr_matcher *matcher)
3673 : : {
3674 [ # # ]: 0 : if (!matcher->hash_definer)
3675 : : return;
3676 : :
3677 : 0 : mlx5dr_cmd_destroy_obj(matcher->hash_definer->obj);
3678 : 0 : simple_free(matcher->hash_definer);
3679 : : }
3680 : :
3681 : 0 : int mlx5dr_definer_matcher_init(struct mlx5dr_context *ctx,
3682 : : struct mlx5dr_matcher *matcher)
3683 : : {
3684 : 0 : struct mlx5dr_definer match_layout = {0};
3685 : 0 : struct mlx5dr_definer range_layout = {0};
3686 : : int ret, i;
3687 : :
3688 [ # # ]: 0 : if (matcher->flags & MLX5DR_MATCHER_FLAGS_COLLISION)
3689 : : return 0;
3690 : :
3691 : 0 : ret = mlx5dr_definer_calc_layout(matcher, &match_layout, &range_layout);
3692 [ # # ]: 0 : if (ret) {
3693 : 0 : DR_LOG(ERR, "Failed to calculate matcher definer layout");
3694 : 0 : return ret;
3695 : : }
3696 : :
3697 : : /* Calculate definers needed for exact match */
3698 : 0 : ret = mlx5dr_definer_matcher_match_init(ctx, matcher, &match_layout);
3699 [ # # ]: 0 : if (ret) {
3700 : 0 : DR_LOG(ERR, "Failed to init match definers");
3701 : 0 : goto free_fc;
3702 : : }
3703 : :
3704 : : /* Calculate definers needed for range */
3705 : 0 : ret = mlx5dr_definer_matcher_range_init(ctx, matcher, &range_layout);
3706 [ # # ]: 0 : if (ret) {
3707 : 0 : DR_LOG(ERR, "Failed to init range definers");
3708 : 0 : goto uninit_match_definer;
3709 : : }
3710 : :
3711 : : /* Calculate partial hash definer */
3712 : 0 : ret = mlx5dr_definer_matcher_hash_init(ctx, matcher);
3713 [ # # ]: 0 : if (ret) {
3714 : 0 : DR_LOG(ERR, "Failed to init hash definer");
3715 : 0 : goto uninit_range_definer;
3716 : : }
3717 : :
3718 : : return 0;
3719 : :
3720 : : uninit_range_definer:
3721 : 0 : mlx5dr_definer_matcher_range_uninit(matcher);
3722 : 0 : uninit_match_definer:
3723 : 0 : mlx5dr_definer_matcher_match_uninit(matcher);
3724 : 0 : free_fc:
3725 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++)
3726 : 0 : simple_free(matcher->mt[i].fc);
3727 : :
3728 : : return ret;
3729 : : }
3730 : :
3731 : 0 : void mlx5dr_definer_matcher_uninit(struct mlx5dr_matcher *matcher)
3732 : : {
3733 : : int i;
3734 : :
3735 [ # # ]: 0 : if (matcher->flags & MLX5DR_MATCHER_FLAGS_COLLISION)
3736 : : return;
3737 : :
3738 : 0 : mlx5dr_definer_matcher_hash_uninit(matcher);
3739 : 0 : mlx5dr_definer_matcher_range_uninit(matcher);
3740 : 0 : mlx5dr_definer_matcher_match_uninit(matcher);
3741 : :
3742 [ # # ]: 0 : for (i = 0; i < matcher->num_of_mt; i++)
3743 : 0 : simple_free(matcher->mt[i].fc);
3744 : : }
|