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