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