1
2
3
4#include <linux/types.h>
5#include <linux/crc32.h>
6#include "dr_types.h"
7
8#define DR_STE_CRC_POLY 0xEDB88320L
9#define STE_IPV4 0x1
10#define STE_IPV6 0x2
11#define STE_TCP 0x1
12#define STE_UDP 0x2
13#define STE_SPI 0x3
14#define IP_VERSION_IPV4 0x4
15#define IP_VERSION_IPV6 0x6
16#define STE_SVLAN 0x1
17#define STE_CVLAN 0x2
18
19#define DR_STE_ENABLE_FLOW_TAG BIT(31)
20
21
22#define DR_STE_SET_VAL(lookup_type, tag, t_fname, spec, s_fname, value) do { \
23 if ((spec)->s_fname) { \
24 MLX5_SET(ste_##lookup_type, tag, t_fname, value); \
25 (spec)->s_fname = 0; \
26 } \
27} while (0)
28
29
30#define DR_STE_SET_TAG(lookup_type, tag, t_fname, spec, s_fname) \
31 DR_STE_SET_VAL(lookup_type, tag, t_fname, spec, s_fname, spec->s_fname)
32
33
34#define DR_STE_SET_MASK(lookup_type, bit_mask, bm_fname, spec, s_fname) \
35 DR_STE_SET_VAL(lookup_type, bit_mask, bm_fname, spec, s_fname, -1)
36
37
38#define DR_STE_SET_MASK_V(lookup_type, bit_mask, bm_fname, spec, s_fname) \
39 DR_STE_SET_VAL(lookup_type, bit_mask, bm_fname, spec, s_fname, (spec)->s_fname)
40
41#define DR_STE_SET_TCP_FLAGS(lookup_type, tag, spec) do { \
42 MLX5_SET(ste_##lookup_type, tag, tcp_ns, !!((spec)->tcp_flags & (1 << 8))); \
43 MLX5_SET(ste_##lookup_type, tag, tcp_cwr, !!((spec)->tcp_flags & (1 << 7))); \
44 MLX5_SET(ste_##lookup_type, tag, tcp_ece, !!((spec)->tcp_flags & (1 << 6))); \
45 MLX5_SET(ste_##lookup_type, tag, tcp_urg, !!((spec)->tcp_flags & (1 << 5))); \
46 MLX5_SET(ste_##lookup_type, tag, tcp_ack, !!((spec)->tcp_flags & (1 << 4))); \
47 MLX5_SET(ste_##lookup_type, tag, tcp_psh, !!((spec)->tcp_flags & (1 << 3))); \
48 MLX5_SET(ste_##lookup_type, tag, tcp_rst, !!((spec)->tcp_flags & (1 << 2))); \
49 MLX5_SET(ste_##lookup_type, tag, tcp_syn, !!((spec)->tcp_flags & (1 << 1))); \
50 MLX5_SET(ste_##lookup_type, tag, tcp_fin, !!((spec)->tcp_flags & (1 << 0))); \
51} while (0)
52
53#define DR_STE_SET_MPLS_MASK(lookup_type, mask, in_out, bit_mask) do { \
54 DR_STE_SET_MASK_V(lookup_type, mask, mpls0_label, mask, \
55 in_out##_first_mpls_label);\
56 DR_STE_SET_MASK_V(lookup_type, mask, mpls0_s_bos, mask, \
57 in_out##_first_mpls_s_bos); \
58 DR_STE_SET_MASK_V(lookup_type, mask, mpls0_exp, mask, \
59 in_out##_first_mpls_exp); \
60 DR_STE_SET_MASK_V(lookup_type, mask, mpls0_ttl, mask, \
61 in_out##_first_mpls_ttl); \
62} while (0)
63
64#define DR_STE_SET_MPLS_TAG(lookup_type, mask, in_out, tag) do { \
65 DR_STE_SET_TAG(lookup_type, tag, mpls0_label, mask, \
66 in_out##_first_mpls_label);\
67 DR_STE_SET_TAG(lookup_type, tag, mpls0_s_bos, mask, \
68 in_out##_first_mpls_s_bos); \
69 DR_STE_SET_TAG(lookup_type, tag, mpls0_exp, mask, \
70 in_out##_first_mpls_exp); \
71 DR_STE_SET_TAG(lookup_type, tag, mpls0_ttl, mask, \
72 in_out##_first_mpls_ttl); \
73} while (0)
74
75#define DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(_misc) (\
76 (_misc)->outer_first_mpls_over_gre_label || \
77 (_misc)->outer_first_mpls_over_gre_exp || \
78 (_misc)->outer_first_mpls_over_gre_s_bos || \
79 (_misc)->outer_first_mpls_over_gre_ttl)
80#define DR_STE_IS_OUTER_MPLS_OVER_UDP_SET(_misc) (\
81 (_misc)->outer_first_mpls_over_udp_label || \
82 (_misc)->outer_first_mpls_over_udp_exp || \
83 (_misc)->outer_first_mpls_over_udp_s_bos || \
84 (_misc)->outer_first_mpls_over_udp_ttl)
85
86#define DR_STE_CALC_LU_TYPE(lookup_type, rx, inner) \
87 ((inner) ? MLX5DR_STE_LU_TYPE_##lookup_type##_I : \
88 (rx) ? MLX5DR_STE_LU_TYPE_##lookup_type##_D : \
89 MLX5DR_STE_LU_TYPE_##lookup_type##_O)
90
91enum dr_ste_tunl_action {
92 DR_STE_TUNL_ACTION_NONE = 0,
93 DR_STE_TUNL_ACTION_ENABLE = 1,
94 DR_STE_TUNL_ACTION_DECAP = 2,
95 DR_STE_TUNL_ACTION_L3_DECAP = 3,
96 DR_STE_TUNL_ACTION_POP_VLAN = 4,
97};
98
99enum dr_ste_action_type {
100 DR_STE_ACTION_TYPE_PUSH_VLAN = 1,
101 DR_STE_ACTION_TYPE_ENCAP_L3 = 3,
102 DR_STE_ACTION_TYPE_ENCAP = 4,
103};
104
105struct dr_hw_ste_format {
106 u8 ctrl[DR_STE_SIZE_CTRL];
107 u8 tag[DR_STE_SIZE_TAG];
108 u8 mask[DR_STE_SIZE_MASK];
109};
110
111static u32 dr_ste_crc32_calc(const void *input_data, size_t length)
112{
113 u32 crc = crc32(0, input_data, length);
114
115 return (__force u32)htonl(crc);
116}
117
118u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl)
119{
120 struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
121 u8 masked[DR_STE_SIZE_TAG] = {};
122 u32 crc32, index;
123 u16 bit;
124 int i;
125
126
127 if (htbl->chunk->num_of_entries == 1 || htbl->byte_mask == 0)
128 return 0;
129
130
131 bit = 1 << (DR_STE_SIZE_TAG - 1);
132 for (i = 0; i < DR_STE_SIZE_TAG; i++) {
133 if (htbl->byte_mask & bit)
134 masked[i] = hw_ste->tag[i];
135
136 bit = bit >> 1;
137 }
138
139 crc32 = dr_ste_crc32_calc(masked, DR_STE_SIZE_TAG);
140 index = crc32 & (htbl->chunk->num_of_entries - 1);
141
142 return index;
143}
144
145static u16 dr_ste_conv_bit_to_byte_mask(u8 *bit_mask)
146{
147 u16 byte_mask = 0;
148 int i;
149
150 for (i = 0; i < DR_STE_SIZE_MASK; i++) {
151 byte_mask = byte_mask << 1;
152 if (bit_mask[i] == 0xff)
153 byte_mask |= 1;
154 }
155 return byte_mask;
156}
157
158static u8 *mlx5dr_ste_get_tag(u8 *hw_ste_p)
159{
160 struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
161
162 return hw_ste->tag;
163}
164
165void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask)
166{
167 struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
168
169 memcpy(hw_ste->mask, bit_mask, DR_STE_SIZE_MASK);
170}
171
172void mlx5dr_ste_rx_set_flow_tag(u8 *hw_ste_p, u32 flow_tag)
173{
174 MLX5_SET(ste_rx_steering_mult, hw_ste_p, qp_list_pointer,
175 DR_STE_ENABLE_FLOW_TAG | flow_tag);
176}
177
178void mlx5dr_ste_set_counter_id(u8 *hw_ste_p, u32 ctr_id)
179{
180
181 MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_15_0, ctr_id);
182 MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_23_16, ctr_id >> 16);
183}
184
185void mlx5dr_ste_set_go_back_bit(u8 *hw_ste_p)
186{
187 MLX5_SET(ste_sx_transmit, hw_ste_p, go_back, 1);
188}
189
190void mlx5dr_ste_set_tx_push_vlan(u8 *hw_ste_p, u32 vlan_hdr,
191 bool go_back)
192{
193 MLX5_SET(ste_sx_transmit, hw_ste_p, action_type,
194 DR_STE_ACTION_TYPE_PUSH_VLAN);
195 MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, vlan_hdr);
196
197
198
199 if (go_back)
200 mlx5dr_ste_set_go_back_bit(hw_ste_p);
201}
202
203void mlx5dr_ste_set_tx_encap(void *hw_ste_p, u32 reformat_id, int size, bool encap_l3)
204{
205 MLX5_SET(ste_sx_transmit, hw_ste_p, action_type,
206 encap_l3 ? DR_STE_ACTION_TYPE_ENCAP_L3 : DR_STE_ACTION_TYPE_ENCAP);
207
208 MLX5_SET(ste_sx_transmit, hw_ste_p, action_description, size / 2);
209 MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, reformat_id);
210}
211
212void mlx5dr_ste_set_rx_decap(u8 *hw_ste_p)
213{
214 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action,
215 DR_STE_TUNL_ACTION_DECAP);
216}
217
218void mlx5dr_ste_set_rx_pop_vlan(u8 *hw_ste_p)
219{
220 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action,
221 DR_STE_TUNL_ACTION_POP_VLAN);
222}
223
224void mlx5dr_ste_set_rx_decap_l3(u8 *hw_ste_p, bool vlan)
225{
226 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action,
227 DR_STE_TUNL_ACTION_L3_DECAP);
228 MLX5_SET(ste_modify_packet, hw_ste_p, action_description, vlan ? 1 : 0);
229}
230
231void mlx5dr_ste_set_entry_type(u8 *hw_ste_p, u8 entry_type)
232{
233 MLX5_SET(ste_general, hw_ste_p, entry_type, entry_type);
234}
235
236u8 mlx5dr_ste_get_entry_type(u8 *hw_ste_p)
237{
238 return MLX5_GET(ste_general, hw_ste_p, entry_type);
239}
240
241void mlx5dr_ste_set_rewrite_actions(u8 *hw_ste_p, u16 num_of_actions,
242 u32 re_write_index)
243{
244 MLX5_SET(ste_modify_packet, hw_ste_p, number_of_re_write_actions,
245 num_of_actions);
246 MLX5_SET(ste_modify_packet, hw_ste_p, header_re_write_actions_pointer,
247 re_write_index);
248}
249
250void mlx5dr_ste_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi)
251{
252 MLX5_SET(ste_general, hw_ste_p, next_table_base_63_48, gvmi);
253}
254
255void mlx5dr_ste_init(u8 *hw_ste_p, u8 lu_type, u8 entry_type,
256 u16 gvmi)
257{
258 MLX5_SET(ste_general, hw_ste_p, entry_type, entry_type);
259 MLX5_SET(ste_general, hw_ste_p, entry_sub_type, lu_type);
260 MLX5_SET(ste_general, hw_ste_p, next_lu_type, MLX5DR_STE_LU_TYPE_DONT_CARE);
261
262
263
264
265 MLX5_SET(ste_rx_steering_mult, hw_ste_p, gvmi, gvmi);
266 MLX5_SET(ste_rx_steering_mult, hw_ste_p, next_table_base_63_48, gvmi);
267 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_63_48, gvmi);
268}
269
270static void dr_ste_set_always_hit(struct dr_hw_ste_format *hw_ste)
271{
272 memset(&hw_ste->tag, 0, sizeof(hw_ste->tag));
273 memset(&hw_ste->mask, 0, sizeof(hw_ste->mask));
274}
275
276static void dr_ste_set_always_miss(struct dr_hw_ste_format *hw_ste)
277{
278 hw_ste->tag[0] = 0xdc;
279 hw_ste->mask[0] = 0;
280}
281
282u64 mlx5dr_ste_get_miss_addr(u8 *hw_ste)
283{
284 u64 index =
285 (MLX5_GET(ste_rx_steering_mult, hw_ste, miss_address_31_6) |
286 MLX5_GET(ste_rx_steering_mult, hw_ste, miss_address_39_32) << 26);
287
288 return index << 6;
289}
290
291void mlx5dr_ste_set_hit_addr(u8 *hw_ste, u64 icm_addr, u32 ht_size)
292{
293 u64 index = (icm_addr >> 5) | ht_size;
294
295 MLX5_SET(ste_general, hw_ste, next_table_base_39_32_size, index >> 27);
296 MLX5_SET(ste_general, hw_ste, next_table_base_31_5_size, index);
297}
298
299u64 mlx5dr_ste_get_icm_addr(struct mlx5dr_ste *ste)
300{
301 u32 index = ste - ste->htbl->ste_arr;
302
303 return ste->htbl->chunk->icm_addr + DR_STE_SIZE * index;
304}
305
306u64 mlx5dr_ste_get_mr_addr(struct mlx5dr_ste *ste)
307{
308 u32 index = ste - ste->htbl->ste_arr;
309
310 return ste->htbl->chunk->mr_addr + DR_STE_SIZE * index;
311}
312
313struct list_head *mlx5dr_ste_get_miss_list(struct mlx5dr_ste *ste)
314{
315 u32 index = ste - ste->htbl->ste_arr;
316
317 return &ste->htbl->miss_list[index];
318}
319
320static void dr_ste_always_hit_htbl(struct mlx5dr_ste *ste,
321 struct mlx5dr_ste_htbl *next_htbl)
322{
323 struct mlx5dr_icm_chunk *chunk = next_htbl->chunk;
324 u8 *hw_ste = ste->hw_ste;
325
326 MLX5_SET(ste_general, hw_ste, byte_mask, next_htbl->byte_mask);
327 MLX5_SET(ste_general, hw_ste, next_lu_type, next_htbl->lu_type);
328 mlx5dr_ste_set_hit_addr(hw_ste, chunk->icm_addr, chunk->num_of_entries);
329
330 dr_ste_set_always_hit((struct dr_hw_ste_format *)ste->hw_ste);
331}
332
333bool mlx5dr_ste_is_last_in_rule(struct mlx5dr_matcher_rx_tx *nic_matcher,
334 u8 ste_location)
335{
336 return ste_location == nic_matcher->num_of_builders;
337}
338
339
340
341
342
343
344
345
346
347
348
349
350
351static void dr_ste_replace(struct mlx5dr_ste *dst, struct mlx5dr_ste *src)
352{
353 memcpy(dst->hw_ste, src->hw_ste, DR_STE_SIZE_REDUCED);
354 dst->next_htbl = src->next_htbl;
355 if (dst->next_htbl)
356 dst->next_htbl->pointing_ste = dst;
357
358 dst->refcount = src->refcount;
359
360 INIT_LIST_HEAD(&dst->rule_list);
361 list_splice_tail_init(&src->rule_list, &dst->rule_list);
362}
363
364
365static void
366dr_ste_remove_head_ste(struct mlx5dr_ste *ste,
367 struct mlx5dr_matcher_rx_tx *nic_matcher,
368 struct mlx5dr_ste_send_info *ste_info_head,
369 struct list_head *send_ste_list,
370 struct mlx5dr_ste_htbl *stats_tbl)
371{
372 u8 tmp_data_ste[DR_STE_SIZE] = {};
373 struct mlx5dr_ste tmp_ste = {};
374 u64 miss_addr;
375
376 tmp_ste.hw_ste = tmp_data_ste;
377
378
379
380
381 memcpy(tmp_ste.hw_ste, ste->hw_ste, DR_STE_SIZE_REDUCED);
382 miss_addr = nic_matcher->e_anchor->chunk->icm_addr;
383 mlx5dr_ste_always_miss_addr(&tmp_ste, miss_addr);
384 memcpy(ste->hw_ste, tmp_ste.hw_ste, DR_STE_SIZE_REDUCED);
385
386 list_del_init(&ste->miss_list_node);
387
388
389 mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE,
390 0, tmp_data_ste,
391 ste_info_head,
392 send_ste_list,
393 true );
394
395 stats_tbl->ctrl.num_of_valid_entries--;
396}
397
398
399
400
401static void
402dr_ste_replace_head_ste(struct mlx5dr_ste *ste, struct mlx5dr_ste *next_ste,
403 struct mlx5dr_ste_send_info *ste_info_head,
404 struct list_head *send_ste_list,
405 struct mlx5dr_ste_htbl *stats_tbl)
406
407{
408 struct mlx5dr_ste_htbl *next_miss_htbl;
409
410 next_miss_htbl = next_ste->htbl;
411
412
413 list_del_init(&next_ste->miss_list_node);
414
415
416 mlx5dr_rule_update_rule_member(next_ste, ste);
417
418
419 dr_ste_replace(ste, next_ste);
420
421
422
423
424 mlx5dr_htbl_put(next_miss_htbl);
425
426 mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE_REDUCED,
427 0, ste->hw_ste,
428 ste_info_head,
429 send_ste_list,
430 true );
431
432 stats_tbl->ctrl.num_of_collisions--;
433 stats_tbl->ctrl.num_of_valid_entries--;
434}
435
436
437
438
439static void dr_ste_remove_middle_ste(struct mlx5dr_ste *ste,
440 struct mlx5dr_ste_send_info *ste_info,
441 struct list_head *send_ste_list,
442 struct mlx5dr_ste_htbl *stats_tbl)
443{
444 struct mlx5dr_ste *prev_ste;
445 u64 miss_addr;
446
447 prev_ste = list_prev_entry(ste, miss_list_node);
448 if (WARN_ON(!prev_ste))
449 return;
450
451 miss_addr = mlx5dr_ste_get_miss_addr(ste->hw_ste);
452 mlx5dr_ste_set_miss_addr(prev_ste->hw_ste, miss_addr);
453
454 mlx5dr_send_fill_and_append_ste_send_info(prev_ste, DR_STE_SIZE_REDUCED, 0,
455 prev_ste->hw_ste, ste_info,
456 send_ste_list, true );
457
458 list_del_init(&ste->miss_list_node);
459
460 stats_tbl->ctrl.num_of_valid_entries--;
461 stats_tbl->ctrl.num_of_collisions--;
462}
463
464void mlx5dr_ste_free(struct mlx5dr_ste *ste,
465 struct mlx5dr_matcher *matcher,
466 struct mlx5dr_matcher_rx_tx *nic_matcher)
467{
468 struct mlx5dr_ste_send_info *cur_ste_info, *tmp_ste_info;
469 struct mlx5dr_domain *dmn = matcher->tbl->dmn;
470 struct mlx5dr_ste_send_info ste_info_head;
471 struct mlx5dr_ste *next_ste, *first_ste;
472 bool put_on_origin_table = true;
473 struct mlx5dr_ste_htbl *stats_tbl;
474 LIST_HEAD(send_ste_list);
475
476 first_ste = list_first_entry(mlx5dr_ste_get_miss_list(ste),
477 struct mlx5dr_ste, miss_list_node);
478 stats_tbl = first_ste->htbl;
479
480
481
482
483
484
485
486 if (first_ste == ste) {
487 struct mlx5dr_ste *last_ste;
488
489 last_ste = list_last_entry(mlx5dr_ste_get_miss_list(ste),
490 struct mlx5dr_ste, miss_list_node);
491 if (last_ste == first_ste)
492 next_ste = NULL;
493 else
494 next_ste = list_next_entry(ste, miss_list_node);
495
496 if (!next_ste) {
497
498 dr_ste_remove_head_ste(ste, nic_matcher,
499 &ste_info_head,
500 &send_ste_list,
501 stats_tbl);
502 } else {
503
504 dr_ste_replace_head_ste(ste, next_ste, &ste_info_head,
505 &send_ste_list, stats_tbl);
506 put_on_origin_table = false;
507 }
508 } else {
509 dr_ste_remove_middle_ste(ste, &ste_info_head, &send_ste_list, stats_tbl);
510 }
511
512
513 list_for_each_entry_safe(cur_ste_info, tmp_ste_info,
514 &send_ste_list, send_list) {
515 list_del(&cur_ste_info->send_list);
516 mlx5dr_send_postsend_ste(dmn, cur_ste_info->ste,
517 cur_ste_info->data, cur_ste_info->size,
518 cur_ste_info->offset);
519 }
520
521 if (put_on_origin_table)
522 mlx5dr_htbl_put(ste->htbl);
523}
524
525bool mlx5dr_ste_equal_tag(void *src, void *dst)
526{
527 struct dr_hw_ste_format *s_hw_ste = (struct dr_hw_ste_format *)src;
528 struct dr_hw_ste_format *d_hw_ste = (struct dr_hw_ste_format *)dst;
529
530 return !memcmp(s_hw_ste->tag, d_hw_ste->tag, DR_STE_SIZE_TAG);
531}
532
533void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste,
534 struct mlx5dr_ste_htbl *next_htbl)
535{
536 struct mlx5dr_icm_chunk *chunk = next_htbl->chunk;
537
538 mlx5dr_ste_set_hit_addr(hw_ste, chunk->icm_addr, chunk->num_of_entries);
539}
540
541void mlx5dr_ste_set_miss_addr(u8 *hw_ste_p, u64 miss_addr)
542{
543 u64 index = miss_addr >> 6;
544
545
546 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32, index >> 26);
547 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6, index);
548}
549
550void mlx5dr_ste_always_miss_addr(struct mlx5dr_ste *ste, u64 miss_addr)
551{
552 u8 *hw_ste = ste->hw_ste;
553
554 MLX5_SET(ste_rx_steering_mult, hw_ste, next_lu_type, MLX5DR_STE_LU_TYPE_DONT_CARE);
555 mlx5dr_ste_set_miss_addr(hw_ste, miss_addr);
556 dr_ste_set_always_miss((struct dr_hw_ste_format *)ste->hw_ste);
557}
558
559
560void mlx5dr_ste_set_formatted_ste(u16 gvmi,
561 struct mlx5dr_domain_rx_tx *nic_dmn,
562 struct mlx5dr_ste_htbl *htbl,
563 u8 *formatted_ste,
564 struct mlx5dr_htbl_connect_info *connect_info)
565{
566 struct mlx5dr_ste ste = {};
567
568 mlx5dr_ste_init(formatted_ste, htbl->lu_type, nic_dmn->ste_type, gvmi);
569 ste.hw_ste = formatted_ste;
570
571 if (connect_info->type == CONNECT_HIT)
572 dr_ste_always_hit_htbl(&ste, connect_info->hit_next_htbl);
573 else
574 mlx5dr_ste_always_miss_addr(&ste, connect_info->miss_icm_addr);
575}
576
577int mlx5dr_ste_htbl_init_and_postsend(struct mlx5dr_domain *dmn,
578 struct mlx5dr_domain_rx_tx *nic_dmn,
579 struct mlx5dr_ste_htbl *htbl,
580 struct mlx5dr_htbl_connect_info *connect_info,
581 bool update_hw_ste)
582{
583 u8 formatted_ste[DR_STE_SIZE] = {};
584
585 mlx5dr_ste_set_formatted_ste(dmn->info.caps.gvmi,
586 nic_dmn,
587 htbl,
588 formatted_ste,
589 connect_info);
590
591 return mlx5dr_send_postsend_formatted_htbl(dmn, htbl, formatted_ste, update_hw_ste);
592}
593
594int mlx5dr_ste_create_next_htbl(struct mlx5dr_matcher *matcher,
595 struct mlx5dr_matcher_rx_tx *nic_matcher,
596 struct mlx5dr_ste *ste,
597 u8 *cur_hw_ste,
598 enum mlx5dr_icm_chunk_size log_table_size)
599{
600 struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)cur_hw_ste;
601 struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
602 struct mlx5dr_domain *dmn = matcher->tbl->dmn;
603 struct mlx5dr_htbl_connect_info info;
604 struct mlx5dr_ste_htbl *next_htbl;
605
606 if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste->ste_chain_location)) {
607 u8 next_lu_type;
608 u16 byte_mask;
609
610 next_lu_type = MLX5_GET(ste_general, hw_ste, next_lu_type);
611 byte_mask = MLX5_GET(ste_general, hw_ste, byte_mask);
612
613 next_htbl = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool,
614 log_table_size,
615 next_lu_type,
616 byte_mask);
617 if (!next_htbl) {
618 mlx5dr_dbg(dmn, "Failed allocating table\n");
619 return -ENOMEM;
620 }
621
622
623 info.type = CONNECT_MISS;
624 info.miss_icm_addr = nic_matcher->e_anchor->chunk->icm_addr;
625 if (mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn, next_htbl,
626 &info, false)) {
627 mlx5dr_info(dmn, "Failed writing table to HW\n");
628 goto free_table;
629 }
630
631 mlx5dr_ste_set_hit_addr_by_next_htbl(cur_hw_ste, next_htbl);
632 ste->next_htbl = next_htbl;
633 next_htbl->pointing_ste = ste;
634 }
635
636 return 0;
637
638free_table:
639 mlx5dr_ste_htbl_free(next_htbl);
640 return -ENOENT;
641}
642
643static void dr_ste_set_ctrl(struct mlx5dr_ste_htbl *htbl)
644{
645 struct mlx5dr_ste_htbl_ctrl *ctrl = &htbl->ctrl;
646 int num_of_entries;
647
648 htbl->ctrl.may_grow = true;
649
650 if (htbl->chunk_size == DR_CHUNK_SIZE_MAX - 1 || !htbl->byte_mask)
651 htbl->ctrl.may_grow = false;
652
653
654 num_of_entries = mlx5dr_icm_pool_chunk_size_to_entries(htbl->chunk_size);
655 ctrl->increase_threshold = (num_of_entries + 1) / 2;
656}
657
658struct mlx5dr_ste_htbl *mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,
659 enum mlx5dr_icm_chunk_size chunk_size,
660 u8 lu_type, u16 byte_mask)
661{
662 struct mlx5dr_icm_chunk *chunk;
663 struct mlx5dr_ste_htbl *htbl;
664 int i;
665
666 htbl = kzalloc(sizeof(*htbl), GFP_KERNEL);
667 if (!htbl)
668 return NULL;
669
670 chunk = mlx5dr_icm_alloc_chunk(pool, chunk_size);
671 if (!chunk)
672 goto out_free_htbl;
673
674 htbl->chunk = chunk;
675 htbl->lu_type = lu_type;
676 htbl->byte_mask = byte_mask;
677 htbl->ste_arr = chunk->ste_arr;
678 htbl->hw_ste_arr = chunk->hw_ste_arr;
679 htbl->miss_list = chunk->miss_list;
680 htbl->refcount = 0;
681
682 for (i = 0; i < chunk->num_of_entries; i++) {
683 struct mlx5dr_ste *ste = &htbl->ste_arr[i];
684
685 ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED;
686 ste->htbl = htbl;
687 ste->refcount = 0;
688 INIT_LIST_HEAD(&ste->miss_list_node);
689 INIT_LIST_HEAD(&htbl->miss_list[i]);
690 INIT_LIST_HEAD(&ste->rule_list);
691 }
692
693 htbl->chunk_size = chunk_size;
694 dr_ste_set_ctrl(htbl);
695 return htbl;
696
697out_free_htbl:
698 kfree(htbl);
699 return NULL;
700}
701
702int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl)
703{
704 if (htbl->refcount)
705 return -EBUSY;
706
707 mlx5dr_icm_free_chunk(htbl->chunk);
708 kfree(htbl);
709 return 0;
710}
711
712int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
713 u8 match_criteria,
714 struct mlx5dr_match_param *mask,
715 struct mlx5dr_match_param *value)
716{
717 if (!value && (match_criteria & DR_MATCHER_CRITERIA_MISC)) {
718 if (mask->misc.source_port && mask->misc.source_port != 0xffff) {
719 mlx5dr_err(dmn,
720 "Partial mask source_port is not supported\n");
721 return -EINVAL;
722 }
723 if (mask->misc.source_eswitch_owner_vhca_id &&
724 mask->misc.source_eswitch_owner_vhca_id != 0xffff) {
725 mlx5dr_err(dmn,
726 "Partial mask source_eswitch_owner_vhca_id is not supported\n");
727 return -EINVAL;
728 }
729 }
730
731 return 0;
732}
733
734int mlx5dr_ste_build_ste_arr(struct mlx5dr_matcher *matcher,
735 struct mlx5dr_matcher_rx_tx *nic_matcher,
736 struct mlx5dr_match_param *value,
737 u8 *ste_arr)
738{
739 struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
740 struct mlx5dr_domain *dmn = matcher->tbl->dmn;
741 struct mlx5dr_ste_build *sb;
742 int ret, i;
743
744 ret = mlx5dr_ste_build_pre_check(dmn, matcher->match_criteria,
745 &matcher->mask, value);
746 if (ret)
747 return ret;
748
749 sb = nic_matcher->ste_builder;
750 for (i = 0; i < nic_matcher->num_of_builders; i++) {
751 mlx5dr_ste_init(ste_arr,
752 sb->lu_type,
753 nic_dmn->ste_type,
754 dmn->info.caps.gvmi);
755
756 mlx5dr_ste_set_bit_mask(ste_arr, sb->bit_mask);
757
758 ret = sb->ste_build_tag_func(value, sb, mlx5dr_ste_get_tag(ste_arr));
759 if (ret)
760 return ret;
761
762
763 if (i < (nic_matcher->num_of_builders - 1)) {
764
765
766
767 sb++;
768 MLX5_SET(ste_general, ste_arr, next_lu_type, sb->lu_type);
769 MLX5_SET(ste_general, ste_arr, byte_mask, sb->byte_mask);
770 }
771 ste_arr += DR_STE_SIZE;
772 }
773 return 0;
774}
775
776static void dr_ste_build_eth_l2_src_des_bit_mask(struct mlx5dr_match_param *value,
777 bool inner, u8 *bit_mask)
778{
779 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
780
781 DR_STE_SET_MASK_V(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
782 DR_STE_SET_MASK_V(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
783
784 if (mask->smac_47_16 || mask->smac_15_0) {
785 MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32,
786 mask->smac_47_16 >> 16);
787 MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0,
788 mask->smac_47_16 << 16 | mask->smac_15_0);
789 mask->smac_47_16 = 0;
790 mask->smac_15_0 = 0;
791 }
792
793 DR_STE_SET_MASK_V(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid);
794 DR_STE_SET_MASK_V(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi);
795 DR_STE_SET_MASK_V(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio);
796 DR_STE_SET_MASK(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version);
797
798 if (mask->cvlan_tag) {
799 MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
800 mask->cvlan_tag = 0;
801 } else if (mask->svlan_tag) {
802 MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
803 mask->svlan_tag = 0;
804 }
805}
806
807static void dr_ste_copy_mask_misc(char *mask, struct mlx5dr_match_misc *spec)
808{
809 spec->gre_c_present = MLX5_GET(fte_match_set_misc, mask, gre_c_present);
810 spec->gre_k_present = MLX5_GET(fte_match_set_misc, mask, gre_k_present);
811 spec->gre_s_present = MLX5_GET(fte_match_set_misc, mask, gre_s_present);
812 spec->source_vhca_port = MLX5_GET(fte_match_set_misc, mask, source_vhca_port);
813 spec->source_sqn = MLX5_GET(fte_match_set_misc, mask, source_sqn);
814
815 spec->source_port = MLX5_GET(fte_match_set_misc, mask, source_port);
816 spec->source_eswitch_owner_vhca_id = MLX5_GET(fte_match_set_misc, mask,
817 source_eswitch_owner_vhca_id);
818
819 spec->outer_second_prio = MLX5_GET(fte_match_set_misc, mask, outer_second_prio);
820 spec->outer_second_cfi = MLX5_GET(fte_match_set_misc, mask, outer_second_cfi);
821 spec->outer_second_vid = MLX5_GET(fte_match_set_misc, mask, outer_second_vid);
822 spec->inner_second_prio = MLX5_GET(fte_match_set_misc, mask, inner_second_prio);
823 spec->inner_second_cfi = MLX5_GET(fte_match_set_misc, mask, inner_second_cfi);
824 spec->inner_second_vid = MLX5_GET(fte_match_set_misc, mask, inner_second_vid);
825
826 spec->outer_second_cvlan_tag =
827 MLX5_GET(fte_match_set_misc, mask, outer_second_cvlan_tag);
828 spec->inner_second_cvlan_tag =
829 MLX5_GET(fte_match_set_misc, mask, inner_second_cvlan_tag);
830 spec->outer_second_svlan_tag =
831 MLX5_GET(fte_match_set_misc, mask, outer_second_svlan_tag);
832 spec->inner_second_svlan_tag =
833 MLX5_GET(fte_match_set_misc, mask, inner_second_svlan_tag);
834
835 spec->gre_protocol = MLX5_GET(fte_match_set_misc, mask, gre_protocol);
836
837 spec->gre_key_h = MLX5_GET(fte_match_set_misc, mask, gre_key.nvgre.hi);
838 spec->gre_key_l = MLX5_GET(fte_match_set_misc, mask, gre_key.nvgre.lo);
839
840 spec->vxlan_vni = MLX5_GET(fte_match_set_misc, mask, vxlan_vni);
841
842 spec->geneve_vni = MLX5_GET(fte_match_set_misc, mask, geneve_vni);
843 spec->geneve_oam = MLX5_GET(fte_match_set_misc, mask, geneve_oam);
844
845 spec->outer_ipv6_flow_label =
846 MLX5_GET(fte_match_set_misc, mask, outer_ipv6_flow_label);
847
848 spec->inner_ipv6_flow_label =
849 MLX5_GET(fte_match_set_misc, mask, inner_ipv6_flow_label);
850
851 spec->geneve_opt_len = MLX5_GET(fte_match_set_misc, mask, geneve_opt_len);
852 spec->geneve_protocol_type =
853 MLX5_GET(fte_match_set_misc, mask, geneve_protocol_type);
854
855 spec->bth_dst_qp = MLX5_GET(fte_match_set_misc, mask, bth_dst_qp);
856}
857
858static void dr_ste_copy_mask_spec(char *mask, struct mlx5dr_match_spec *spec)
859{
860 __be32 raw_ip[4];
861
862 spec->smac_47_16 = MLX5_GET(fte_match_set_lyr_2_4, mask, smac_47_16);
863
864 spec->smac_15_0 = MLX5_GET(fte_match_set_lyr_2_4, mask, smac_15_0);
865 spec->ethertype = MLX5_GET(fte_match_set_lyr_2_4, mask, ethertype);
866
867 spec->dmac_47_16 = MLX5_GET(fte_match_set_lyr_2_4, mask, dmac_47_16);
868
869 spec->dmac_15_0 = MLX5_GET(fte_match_set_lyr_2_4, mask, dmac_15_0);
870 spec->first_prio = MLX5_GET(fte_match_set_lyr_2_4, mask, first_prio);
871 spec->first_cfi = MLX5_GET(fte_match_set_lyr_2_4, mask, first_cfi);
872 spec->first_vid = MLX5_GET(fte_match_set_lyr_2_4, mask, first_vid);
873
874 spec->ip_protocol = MLX5_GET(fte_match_set_lyr_2_4, mask, ip_protocol);
875 spec->ip_dscp = MLX5_GET(fte_match_set_lyr_2_4, mask, ip_dscp);
876 spec->ip_ecn = MLX5_GET(fte_match_set_lyr_2_4, mask, ip_ecn);
877 spec->cvlan_tag = MLX5_GET(fte_match_set_lyr_2_4, mask, cvlan_tag);
878 spec->svlan_tag = MLX5_GET(fte_match_set_lyr_2_4, mask, svlan_tag);
879 spec->frag = MLX5_GET(fte_match_set_lyr_2_4, mask, frag);
880 spec->ip_version = MLX5_GET(fte_match_set_lyr_2_4, mask, ip_version);
881 spec->tcp_flags = MLX5_GET(fte_match_set_lyr_2_4, mask, tcp_flags);
882 spec->tcp_sport = MLX5_GET(fte_match_set_lyr_2_4, mask, tcp_sport);
883 spec->tcp_dport = MLX5_GET(fte_match_set_lyr_2_4, mask, tcp_dport);
884
885 spec->ttl_hoplimit = MLX5_GET(fte_match_set_lyr_2_4, mask, ttl_hoplimit);
886
887 spec->udp_sport = MLX5_GET(fte_match_set_lyr_2_4, mask, udp_sport);
888 spec->udp_dport = MLX5_GET(fte_match_set_lyr_2_4, mask, udp_dport);
889
890 memcpy(raw_ip, MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
891 src_ipv4_src_ipv6.ipv6_layout.ipv6),
892 sizeof(raw_ip));
893
894 spec->src_ip_127_96 = be32_to_cpu(raw_ip[0]);
895 spec->src_ip_95_64 = be32_to_cpu(raw_ip[1]);
896 spec->src_ip_63_32 = be32_to_cpu(raw_ip[2]);
897 spec->src_ip_31_0 = be32_to_cpu(raw_ip[3]);
898
899 memcpy(raw_ip, MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
900 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
901 sizeof(raw_ip));
902
903 spec->dst_ip_127_96 = be32_to_cpu(raw_ip[0]);
904 spec->dst_ip_95_64 = be32_to_cpu(raw_ip[1]);
905 spec->dst_ip_63_32 = be32_to_cpu(raw_ip[2]);
906 spec->dst_ip_31_0 = be32_to_cpu(raw_ip[3]);
907}
908
909static void dr_ste_copy_mask_misc2(char *mask, struct mlx5dr_match_misc2 *spec)
910{
911 spec->outer_first_mpls_label =
912 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls.mpls_label);
913 spec->outer_first_mpls_exp =
914 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls.mpls_exp);
915 spec->outer_first_mpls_s_bos =
916 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls.mpls_s_bos);
917 spec->outer_first_mpls_ttl =
918 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls.mpls_ttl);
919 spec->inner_first_mpls_label =
920 MLX5_GET(fte_match_set_misc2, mask, inner_first_mpls.mpls_label);
921 spec->inner_first_mpls_exp =
922 MLX5_GET(fte_match_set_misc2, mask, inner_first_mpls.mpls_exp);
923 spec->inner_first_mpls_s_bos =
924 MLX5_GET(fte_match_set_misc2, mask, inner_first_mpls.mpls_s_bos);
925 spec->inner_first_mpls_ttl =
926 MLX5_GET(fte_match_set_misc2, mask, inner_first_mpls.mpls_ttl);
927 spec->outer_first_mpls_over_gre_label =
928 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_label);
929 spec->outer_first_mpls_over_gre_exp =
930 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_exp);
931 spec->outer_first_mpls_over_gre_s_bos =
932 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_s_bos);
933 spec->outer_first_mpls_over_gre_ttl =
934 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_ttl);
935 spec->outer_first_mpls_over_udp_label =
936 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_label);
937 spec->outer_first_mpls_over_udp_exp =
938 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_exp);
939 spec->outer_first_mpls_over_udp_s_bos =
940 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_s_bos);
941 spec->outer_first_mpls_over_udp_ttl =
942 MLX5_GET(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_ttl);
943 spec->metadata_reg_c_7 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_7);
944 spec->metadata_reg_c_6 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_6);
945 spec->metadata_reg_c_5 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_5);
946 spec->metadata_reg_c_4 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_4);
947 spec->metadata_reg_c_3 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_3);
948 spec->metadata_reg_c_2 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_2);
949 spec->metadata_reg_c_1 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_1);
950 spec->metadata_reg_c_0 = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_c_0);
951 spec->metadata_reg_a = MLX5_GET(fte_match_set_misc2, mask, metadata_reg_a);
952}
953
954static void dr_ste_copy_mask_misc3(char *mask, struct mlx5dr_match_misc3 *spec)
955{
956 spec->inner_tcp_seq_num = MLX5_GET(fte_match_set_misc3, mask, inner_tcp_seq_num);
957 spec->outer_tcp_seq_num = MLX5_GET(fte_match_set_misc3, mask, outer_tcp_seq_num);
958 spec->inner_tcp_ack_num = MLX5_GET(fte_match_set_misc3, mask, inner_tcp_ack_num);
959 spec->outer_tcp_ack_num = MLX5_GET(fte_match_set_misc3, mask, outer_tcp_ack_num);
960 spec->outer_vxlan_gpe_vni =
961 MLX5_GET(fte_match_set_misc3, mask, outer_vxlan_gpe_vni);
962 spec->outer_vxlan_gpe_next_protocol =
963 MLX5_GET(fte_match_set_misc3, mask, outer_vxlan_gpe_next_protocol);
964 spec->outer_vxlan_gpe_flags =
965 MLX5_GET(fte_match_set_misc3, mask, outer_vxlan_gpe_flags);
966 spec->icmpv4_header_data = MLX5_GET(fte_match_set_misc3, mask, icmp_header_data);
967 spec->icmpv6_header_data =
968 MLX5_GET(fte_match_set_misc3, mask, icmpv6_header_data);
969 spec->icmpv4_type = MLX5_GET(fte_match_set_misc3, mask, icmp_type);
970 spec->icmpv4_code = MLX5_GET(fte_match_set_misc3, mask, icmp_code);
971 spec->icmpv6_type = MLX5_GET(fte_match_set_misc3, mask, icmpv6_type);
972 spec->icmpv6_code = MLX5_GET(fte_match_set_misc3, mask, icmpv6_code);
973}
974
975void mlx5dr_ste_copy_param(u8 match_criteria,
976 struct mlx5dr_match_param *set_param,
977 struct mlx5dr_match_parameters *mask)
978{
979 u8 tail_param[MLX5_ST_SZ_BYTES(fte_match_set_lyr_2_4)] = {};
980 u8 *data = (u8 *)mask->match_buf;
981 size_t param_location;
982 void *buff;
983
984 if (match_criteria & DR_MATCHER_CRITERIA_OUTER) {
985 if (mask->match_sz < sizeof(struct mlx5dr_match_spec)) {
986 memcpy(tail_param, data, mask->match_sz);
987 buff = tail_param;
988 } else {
989 buff = mask->match_buf;
990 }
991 dr_ste_copy_mask_spec(buff, &set_param->outer);
992 }
993 param_location = sizeof(struct mlx5dr_match_spec);
994
995 if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
996 if (mask->match_sz < param_location +
997 sizeof(struct mlx5dr_match_misc)) {
998 memcpy(tail_param, data + param_location,
999 mask->match_sz - param_location);
1000 buff = tail_param;
1001 } else {
1002 buff = data + param_location;
1003 }
1004 dr_ste_copy_mask_misc(buff, &set_param->misc);
1005 }
1006 param_location += sizeof(struct mlx5dr_match_misc);
1007
1008 if (match_criteria & DR_MATCHER_CRITERIA_INNER) {
1009 if (mask->match_sz < param_location +
1010 sizeof(struct mlx5dr_match_spec)) {
1011 memcpy(tail_param, data + param_location,
1012 mask->match_sz - param_location);
1013 buff = tail_param;
1014 } else {
1015 buff = data + param_location;
1016 }
1017 dr_ste_copy_mask_spec(buff, &set_param->inner);
1018 }
1019 param_location += sizeof(struct mlx5dr_match_spec);
1020
1021 if (match_criteria & DR_MATCHER_CRITERIA_MISC2) {
1022 if (mask->match_sz < param_location +
1023 sizeof(struct mlx5dr_match_misc2)) {
1024 memcpy(tail_param, data + param_location,
1025 mask->match_sz - param_location);
1026 buff = tail_param;
1027 } else {
1028 buff = data + param_location;
1029 }
1030 dr_ste_copy_mask_misc2(buff, &set_param->misc2);
1031 }
1032
1033 param_location += sizeof(struct mlx5dr_match_misc2);
1034
1035 if (match_criteria & DR_MATCHER_CRITERIA_MISC3) {
1036 if (mask->match_sz < param_location +
1037 sizeof(struct mlx5dr_match_misc3)) {
1038 memcpy(tail_param, data + param_location,
1039 mask->match_sz - param_location);
1040 buff = tail_param;
1041 } else {
1042 buff = data + param_location;
1043 }
1044 dr_ste_copy_mask_misc3(buff, &set_param->misc3);
1045 }
1046}
1047
1048static int dr_ste_build_eth_l2_src_des_tag(struct mlx5dr_match_param *value,
1049 struct mlx5dr_ste_build *sb,
1050 u8 *tag)
1051{
1052 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1053
1054 DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16);
1055 DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0);
1056
1057 if (spec->smac_47_16 || spec->smac_15_0) {
1058 MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32,
1059 spec->smac_47_16 >> 16);
1060 MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0,
1061 spec->smac_47_16 << 16 | spec->smac_15_0);
1062 spec->smac_47_16 = 0;
1063 spec->smac_15_0 = 0;
1064 }
1065
1066 if (spec->ip_version) {
1067 if (spec->ip_version == IP_VERSION_IPV4) {
1068 MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4);
1069 spec->ip_version = 0;
1070 } else if (spec->ip_version == IP_VERSION_IPV6) {
1071 MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6);
1072 spec->ip_version = 0;
1073 } else {
1074 pr_info("Unsupported ip_version value\n");
1075 return -EINVAL;
1076 }
1077 }
1078
1079 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid);
1080 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi);
1081 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio);
1082
1083 if (spec->cvlan_tag) {
1084 MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN);
1085 spec->cvlan_tag = 0;
1086 } else if (spec->svlan_tag) {
1087 MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN);
1088 spec->svlan_tag = 0;
1089 }
1090 return 0;
1091}
1092
1093void mlx5dr_ste_build_eth_l2_src_des(struct mlx5dr_ste_build *sb,
1094 struct mlx5dr_match_param *mask,
1095 bool inner, bool rx)
1096{
1097 dr_ste_build_eth_l2_src_des_bit_mask(mask, inner, sb->bit_mask);
1098
1099 sb->rx = rx;
1100 sb->inner = inner;
1101 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, rx, inner);
1102 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1103 sb->ste_build_tag_func = &dr_ste_build_eth_l2_src_des_tag;
1104}
1105
1106static void dr_ste_build_eth_l3_ipv6_dst_bit_mask(struct mlx5dr_match_param *value,
1107 bool inner, u8 *bit_mask)
1108{
1109 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1110
1111 DR_STE_SET_MASK_V(eth_l3_ipv6_dst, bit_mask, dst_ip_127_96, mask, dst_ip_127_96);
1112 DR_STE_SET_MASK_V(eth_l3_ipv6_dst, bit_mask, dst_ip_95_64, mask, dst_ip_95_64);
1113 DR_STE_SET_MASK_V(eth_l3_ipv6_dst, bit_mask, dst_ip_63_32, mask, dst_ip_63_32);
1114 DR_STE_SET_MASK_V(eth_l3_ipv6_dst, bit_mask, dst_ip_31_0, mask, dst_ip_31_0);
1115}
1116
1117static int dr_ste_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value,
1118 struct mlx5dr_ste_build *sb,
1119 u8 *tag)
1120{
1121 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1122
1123 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96);
1124 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64);
1125 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32);
1126 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0);
1127
1128 return 0;
1129}
1130
1131void mlx5dr_ste_build_eth_l3_ipv6_dst(struct mlx5dr_ste_build *sb,
1132 struct mlx5dr_match_param *mask,
1133 bool inner, bool rx)
1134{
1135 dr_ste_build_eth_l3_ipv6_dst_bit_mask(mask, inner, sb->bit_mask);
1136
1137 sb->rx = rx;
1138 sb->inner = inner;
1139 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, rx, inner);
1140 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1141 sb->ste_build_tag_func = &dr_ste_build_eth_l3_ipv6_dst_tag;
1142}
1143
1144static void dr_ste_build_eth_l3_ipv6_src_bit_mask(struct mlx5dr_match_param *value,
1145 bool inner, u8 *bit_mask)
1146{
1147 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1148
1149 DR_STE_SET_MASK_V(eth_l3_ipv6_src, bit_mask, src_ip_127_96, mask, src_ip_127_96);
1150 DR_STE_SET_MASK_V(eth_l3_ipv6_src, bit_mask, src_ip_95_64, mask, src_ip_95_64);
1151 DR_STE_SET_MASK_V(eth_l3_ipv6_src, bit_mask, src_ip_63_32, mask, src_ip_63_32);
1152 DR_STE_SET_MASK_V(eth_l3_ipv6_src, bit_mask, src_ip_31_0, mask, src_ip_31_0);
1153}
1154
1155static int dr_ste_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value,
1156 struct mlx5dr_ste_build *sb,
1157 u8 *tag)
1158{
1159 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1160
1161 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96);
1162 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64);
1163 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32);
1164 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0);
1165
1166 return 0;
1167}
1168
1169void mlx5dr_ste_build_eth_l3_ipv6_src(struct mlx5dr_ste_build *sb,
1170 struct mlx5dr_match_param *mask,
1171 bool inner, bool rx)
1172{
1173 dr_ste_build_eth_l3_ipv6_src_bit_mask(mask, inner, sb->bit_mask);
1174
1175 sb->rx = rx;
1176 sb->inner = inner;
1177 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, rx, inner);
1178 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1179 sb->ste_build_tag_func = &dr_ste_build_eth_l3_ipv6_src_tag;
1180}
1181
1182static void dr_ste_build_eth_l3_ipv4_5_tuple_bit_mask(struct mlx5dr_match_param *value,
1183 bool inner,
1184 u8 *bit_mask)
1185{
1186 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1187
1188 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1189 destination_address, mask, dst_ip_31_0);
1190 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1191 source_address, mask, src_ip_31_0);
1192 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1193 destination_port, mask, tcp_dport);
1194 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1195 destination_port, mask, udp_dport);
1196 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1197 source_port, mask, tcp_sport);
1198 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1199 source_port, mask, udp_sport);
1200 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1201 protocol, mask, ip_protocol);
1202 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1203 fragmented, mask, frag);
1204 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1205 dscp, mask, ip_dscp);
1206 DR_STE_SET_MASK_V(eth_l3_ipv4_5_tuple, bit_mask,
1207 ecn, mask, ip_ecn);
1208
1209 if (mask->tcp_flags) {
1210 DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, bit_mask, mask);
1211 mask->tcp_flags = 0;
1212 }
1213}
1214
1215static int dr_ste_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value,
1216 struct mlx5dr_ste_build *sb,
1217 u8 *tag)
1218{
1219 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1220
1221 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0);
1222 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0);
1223 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport);
1224 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport);
1225 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport);
1226 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport);
1227 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol);
1228 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag);
1229 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp);
1230 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn);
1231
1232 if (spec->tcp_flags) {
1233 DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec);
1234 spec->tcp_flags = 0;
1235 }
1236
1237 return 0;
1238}
1239
1240void mlx5dr_ste_build_eth_l3_ipv4_5_tuple(struct mlx5dr_ste_build *sb,
1241 struct mlx5dr_match_param *mask,
1242 bool inner, bool rx)
1243{
1244 dr_ste_build_eth_l3_ipv4_5_tuple_bit_mask(mask, inner, sb->bit_mask);
1245
1246 sb->rx = rx;
1247 sb->inner = inner;
1248 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, rx, inner);
1249 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1250 sb->ste_build_tag_func = &dr_ste_build_eth_l3_ipv4_5_tuple_tag;
1251}
1252
1253static void
1254dr_ste_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value,
1255 bool inner, u8 *bit_mask)
1256{
1257 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1258 struct mlx5dr_match_misc *misc_mask = &value->misc;
1259
1260 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid);
1261 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, first_cfi, mask, first_cfi);
1262 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, first_priority, mask, first_prio);
1263 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, ip_fragmented, mask, frag);
1264 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype);
1265 DR_STE_SET_MASK(eth_l2_src, bit_mask, l3_type, mask, ip_version);
1266
1267 if (mask->svlan_tag || mask->cvlan_tag) {
1268 MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1);
1269 mask->cvlan_tag = 0;
1270 mask->svlan_tag = 0;
1271 }
1272
1273 if (inner) {
1274 if (misc_mask->inner_second_cvlan_tag ||
1275 misc_mask->inner_second_svlan_tag) {
1276 MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
1277 misc_mask->inner_second_cvlan_tag = 0;
1278 misc_mask->inner_second_svlan_tag = 0;
1279 }
1280
1281 DR_STE_SET_MASK_V(eth_l2_src, bit_mask,
1282 second_vlan_id, misc_mask, inner_second_vid);
1283 DR_STE_SET_MASK_V(eth_l2_src, bit_mask,
1284 second_cfi, misc_mask, inner_second_cfi);
1285 DR_STE_SET_MASK_V(eth_l2_src, bit_mask,
1286 second_priority, misc_mask, inner_second_prio);
1287 } else {
1288 if (misc_mask->outer_second_cvlan_tag ||
1289 misc_mask->outer_second_svlan_tag) {
1290 MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
1291 misc_mask->outer_second_cvlan_tag = 0;
1292 misc_mask->outer_second_svlan_tag = 0;
1293 }
1294
1295 DR_STE_SET_MASK_V(eth_l2_src, bit_mask,
1296 second_vlan_id, misc_mask, outer_second_vid);
1297 DR_STE_SET_MASK_V(eth_l2_src, bit_mask,
1298 second_cfi, misc_mask, outer_second_cfi);
1299 DR_STE_SET_MASK_V(eth_l2_src, bit_mask,
1300 second_priority, misc_mask, outer_second_prio);
1301 }
1302}
1303
1304static int dr_ste_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value,
1305 bool inner, u8 *tag)
1306{
1307 struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer;
1308 struct mlx5dr_match_misc *misc_spec = &value->misc;
1309
1310 DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid);
1311 DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi);
1312 DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio);
1313 DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag);
1314 DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype);
1315
1316 if (spec->ip_version) {
1317 if (spec->ip_version == IP_VERSION_IPV4) {
1318 MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4);
1319 spec->ip_version = 0;
1320 } else if (spec->ip_version == IP_VERSION_IPV6) {
1321 MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6);
1322 spec->ip_version = 0;
1323 } else {
1324 pr_info("Unsupported ip_version value\n");
1325 return -EINVAL;
1326 }
1327 }
1328
1329 if (spec->cvlan_tag) {
1330 MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN);
1331 spec->cvlan_tag = 0;
1332 } else if (spec->svlan_tag) {
1333 MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN);
1334 spec->svlan_tag = 0;
1335 }
1336
1337 if (inner) {
1338 if (misc_spec->inner_second_cvlan_tag) {
1339 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
1340 misc_spec->inner_second_cvlan_tag = 0;
1341 } else if (misc_spec->inner_second_svlan_tag) {
1342 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
1343 misc_spec->inner_second_svlan_tag = 0;
1344 }
1345
1346 DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid);
1347 DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi);
1348 DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio);
1349 } else {
1350 if (misc_spec->outer_second_cvlan_tag) {
1351 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
1352 misc_spec->outer_second_cvlan_tag = 0;
1353 } else if (misc_spec->outer_second_svlan_tag) {
1354 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
1355 misc_spec->outer_second_svlan_tag = 0;
1356 }
1357 DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid);
1358 DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi);
1359 DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio);
1360 }
1361
1362 return 0;
1363}
1364
1365static void dr_ste_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value,
1366 bool inner, u8 *bit_mask)
1367{
1368 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1369
1370 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16);
1371 DR_STE_SET_MASK_V(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0);
1372
1373 dr_ste_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
1374}
1375
1376static int dr_ste_build_eth_l2_src_tag(struct mlx5dr_match_param *value,
1377 struct mlx5dr_ste_build *sb,
1378 u8 *tag)
1379{
1380 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1381
1382 DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16);
1383 DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0);
1384
1385 return dr_ste_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
1386}
1387
1388void mlx5dr_ste_build_eth_l2_src(struct mlx5dr_ste_build *sb,
1389 struct mlx5dr_match_param *mask,
1390 bool inner, bool rx)
1391{
1392 dr_ste_build_eth_l2_src_bit_mask(mask, inner, sb->bit_mask);
1393 sb->rx = rx;
1394 sb->inner = inner;
1395 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, rx, inner);
1396 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1397 sb->ste_build_tag_func = &dr_ste_build_eth_l2_src_tag;
1398}
1399
1400static void dr_ste_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value,
1401 bool inner, u8 *bit_mask)
1402{
1403 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1404
1405 DR_STE_SET_MASK_V(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
1406 DR_STE_SET_MASK_V(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
1407
1408 dr_ste_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
1409}
1410
1411static int dr_ste_build_eth_l2_dst_tag(struct mlx5dr_match_param *value,
1412 struct mlx5dr_ste_build *sb,
1413 u8 *tag)
1414{
1415 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1416
1417 DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16);
1418 DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0);
1419
1420 return dr_ste_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
1421}
1422
1423void mlx5dr_ste_build_eth_l2_dst(struct mlx5dr_ste_build *sb,
1424 struct mlx5dr_match_param *mask,
1425 bool inner, bool rx)
1426{
1427 dr_ste_build_eth_l2_dst_bit_mask(mask, inner, sb->bit_mask);
1428
1429 sb->rx = rx;
1430 sb->inner = inner;
1431 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, rx, inner);
1432 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1433 sb->ste_build_tag_func = &dr_ste_build_eth_l2_dst_tag;
1434}
1435
1436static void dr_ste_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value,
1437 bool inner, u8 *bit_mask)
1438{
1439 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1440 struct mlx5dr_match_misc *misc = &value->misc;
1441
1442 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16);
1443 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0);
1444 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid);
1445 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi);
1446 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, first_priority, mask, first_prio);
1447 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag);
1448 DR_STE_SET_MASK_V(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype);
1449 DR_STE_SET_MASK(eth_l2_tnl, bit_mask, l3_type, mask, ip_version);
1450
1451 if (misc->vxlan_vni) {
1452 MLX5_SET(ste_eth_l2_tnl, bit_mask,
1453 l2_tunneling_network_id, (misc->vxlan_vni << 8));
1454 misc->vxlan_vni = 0;
1455 }
1456
1457 if (mask->svlan_tag || mask->cvlan_tag) {
1458 MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1);
1459 mask->cvlan_tag = 0;
1460 mask->svlan_tag = 0;
1461 }
1462}
1463
1464static int dr_ste_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value,
1465 struct mlx5dr_ste_build *sb,
1466 u8 *tag)
1467{
1468 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1469 struct mlx5dr_match_misc *misc = &value->misc;
1470
1471 DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16);
1472 DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0);
1473 DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid);
1474 DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi);
1475 DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag);
1476 DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio);
1477 DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype);
1478
1479 if (misc->vxlan_vni) {
1480 MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id,
1481 (misc->vxlan_vni << 8));
1482 misc->vxlan_vni = 0;
1483 }
1484
1485 if (spec->cvlan_tag) {
1486 MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN);
1487 spec->cvlan_tag = 0;
1488 } else if (spec->svlan_tag) {
1489 MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN);
1490 spec->svlan_tag = 0;
1491 }
1492
1493 if (spec->ip_version) {
1494 if (spec->ip_version == IP_VERSION_IPV4) {
1495 MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4);
1496 spec->ip_version = 0;
1497 } else if (spec->ip_version == IP_VERSION_IPV6) {
1498 MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6);
1499 spec->ip_version = 0;
1500 } else {
1501 return -EINVAL;
1502 }
1503 }
1504
1505 return 0;
1506}
1507
1508void mlx5dr_ste_build_eth_l2_tnl(struct mlx5dr_ste_build *sb,
1509 struct mlx5dr_match_param *mask, bool inner, bool rx)
1510{
1511 dr_ste_build_eth_l2_tnl_bit_mask(mask, inner, sb->bit_mask);
1512
1513 sb->rx = rx;
1514 sb->inner = inner;
1515 sb->lu_type = MLX5DR_STE_LU_TYPE_ETHL2_TUNNELING_I;
1516 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1517 sb->ste_build_tag_func = &dr_ste_build_eth_l2_tnl_tag;
1518}
1519
1520static void dr_ste_build_eth_l3_ipv4_misc_bit_mask(struct mlx5dr_match_param *value,
1521 bool inner, u8 *bit_mask)
1522{
1523 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1524
1525 DR_STE_SET_MASK_V(eth_l3_ipv4_misc, bit_mask, time_to_live, mask, ttl_hoplimit);
1526}
1527
1528static int dr_ste_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value,
1529 struct mlx5dr_ste_build *sb,
1530 u8 *tag)
1531{
1532 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1533
1534 DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit);
1535
1536 return 0;
1537}
1538
1539void mlx5dr_ste_build_eth_l3_ipv4_misc(struct mlx5dr_ste_build *sb,
1540 struct mlx5dr_match_param *mask,
1541 bool inner, bool rx)
1542{
1543 dr_ste_build_eth_l3_ipv4_misc_bit_mask(mask, inner, sb->bit_mask);
1544
1545 sb->rx = rx;
1546 sb->inner = inner;
1547 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, rx, inner);
1548 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1549 sb->ste_build_tag_func = &dr_ste_build_eth_l3_ipv4_misc_tag;
1550}
1551
1552static void dr_ste_build_ipv6_l3_l4_bit_mask(struct mlx5dr_match_param *value,
1553 bool inner, u8 *bit_mask)
1554{
1555 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1556
1557 DR_STE_SET_MASK_V(eth_l4, bit_mask, dst_port, mask, tcp_dport);
1558 DR_STE_SET_MASK_V(eth_l4, bit_mask, src_port, mask, tcp_sport);
1559 DR_STE_SET_MASK_V(eth_l4, bit_mask, dst_port, mask, udp_dport);
1560 DR_STE_SET_MASK_V(eth_l4, bit_mask, src_port, mask, udp_sport);
1561 DR_STE_SET_MASK_V(eth_l4, bit_mask, protocol, mask, ip_protocol);
1562 DR_STE_SET_MASK_V(eth_l4, bit_mask, fragmented, mask, frag);
1563 DR_STE_SET_MASK_V(eth_l4, bit_mask, dscp, mask, ip_dscp);
1564 DR_STE_SET_MASK_V(eth_l4, bit_mask, ecn, mask, ip_ecn);
1565 DR_STE_SET_MASK_V(eth_l4, bit_mask, ipv6_hop_limit, mask, ttl_hoplimit);
1566
1567 if (mask->tcp_flags) {
1568 DR_STE_SET_TCP_FLAGS(eth_l4, bit_mask, mask);
1569 mask->tcp_flags = 0;
1570 }
1571}
1572
1573static int dr_ste_build_ipv6_l3_l4_tag(struct mlx5dr_match_param *value,
1574 struct mlx5dr_ste_build *sb,
1575 u8 *tag)
1576{
1577 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1578
1579 DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport);
1580 DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport);
1581 DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport);
1582 DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport);
1583 DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol);
1584 DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag);
1585 DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp);
1586 DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn);
1587 DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit);
1588
1589 if (spec->tcp_flags) {
1590 DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec);
1591 spec->tcp_flags = 0;
1592 }
1593
1594 return 0;
1595}
1596
1597void mlx5dr_ste_build_ipv6_l3_l4(struct mlx5dr_ste_build *sb,
1598 struct mlx5dr_match_param *mask,
1599 bool inner, bool rx)
1600{
1601 dr_ste_build_ipv6_l3_l4_bit_mask(mask, inner, sb->bit_mask);
1602
1603 sb->rx = rx;
1604 sb->inner = inner;
1605 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, rx, inner);
1606 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1607 sb->ste_build_tag_func = &dr_ste_build_ipv6_l3_l4_tag;
1608}
1609
1610static int dr_ste_build_empty_always_hit_tag(struct mlx5dr_match_param *value,
1611 struct mlx5dr_ste_build *sb,
1612 u8 *tag)
1613{
1614 return 0;
1615}
1616
1617void mlx5dr_ste_build_empty_always_hit(struct mlx5dr_ste_build *sb, bool rx)
1618{
1619 sb->rx = rx;
1620 sb->lu_type = MLX5DR_STE_LU_TYPE_DONT_CARE;
1621 sb->byte_mask = 0;
1622 sb->ste_build_tag_func = &dr_ste_build_empty_always_hit_tag;
1623}
1624
1625static void dr_ste_build_mpls_bit_mask(struct mlx5dr_match_param *value,
1626 bool inner, u8 *bit_mask)
1627{
1628 struct mlx5dr_match_misc2 *misc2_mask = &value->misc2;
1629
1630 if (inner)
1631 DR_STE_SET_MPLS_MASK(mpls, misc2_mask, inner, bit_mask);
1632 else
1633 DR_STE_SET_MPLS_MASK(mpls, misc2_mask, outer, bit_mask);
1634}
1635
1636static int dr_ste_build_mpls_tag(struct mlx5dr_match_param *value,
1637 struct mlx5dr_ste_build *sb,
1638 u8 *tag)
1639{
1640 struct mlx5dr_match_misc2 *misc2_mask = &value->misc2;
1641
1642 if (sb->inner)
1643 DR_STE_SET_MPLS_TAG(mpls, misc2_mask, inner, tag);
1644 else
1645 DR_STE_SET_MPLS_TAG(mpls, misc2_mask, outer, tag);
1646
1647 return 0;
1648}
1649
1650void mlx5dr_ste_build_mpls(struct mlx5dr_ste_build *sb,
1651 struct mlx5dr_match_param *mask,
1652 bool inner, bool rx)
1653{
1654 dr_ste_build_mpls_bit_mask(mask, inner, sb->bit_mask);
1655
1656 sb->rx = rx;
1657 sb->inner = inner;
1658 sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, rx, inner);
1659 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1660 sb->ste_build_tag_func = &dr_ste_build_mpls_tag;
1661}
1662
1663static void dr_ste_build_gre_bit_mask(struct mlx5dr_match_param *value,
1664 bool inner, u8 *bit_mask)
1665{
1666 struct mlx5dr_match_misc *misc_mask = &value->misc;
1667
1668 DR_STE_SET_MASK_V(gre, bit_mask, gre_protocol, misc_mask, gre_protocol);
1669 DR_STE_SET_MASK_V(gre, bit_mask, gre_k_present, misc_mask, gre_k_present);
1670 DR_STE_SET_MASK_V(gre, bit_mask, gre_key_h, misc_mask, gre_key_h);
1671 DR_STE_SET_MASK_V(gre, bit_mask, gre_key_l, misc_mask, gre_key_l);
1672
1673 DR_STE_SET_MASK_V(gre, bit_mask, gre_c_present, misc_mask, gre_c_present);
1674 DR_STE_SET_MASK_V(gre, bit_mask, gre_s_present, misc_mask, gre_s_present);
1675}
1676
1677static int dr_ste_build_gre_tag(struct mlx5dr_match_param *value,
1678 struct mlx5dr_ste_build *sb,
1679 u8 *tag)
1680{
1681 struct mlx5dr_match_misc *misc = &value->misc;
1682
1683 DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol);
1684
1685 DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present);
1686 DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h);
1687 DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l);
1688
1689 DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present);
1690
1691 DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present);
1692
1693 return 0;
1694}
1695
1696void mlx5dr_ste_build_gre(struct mlx5dr_ste_build *sb,
1697 struct mlx5dr_match_param *mask, bool inner, bool rx)
1698{
1699 dr_ste_build_gre_bit_mask(mask, inner, sb->bit_mask);
1700
1701 sb->rx = rx;
1702 sb->inner = inner;
1703 sb->lu_type = MLX5DR_STE_LU_TYPE_GRE;
1704 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1705 sb->ste_build_tag_func = &dr_ste_build_gre_tag;
1706}
1707
1708static void dr_ste_build_flex_parser_0_bit_mask(struct mlx5dr_match_param *value,
1709 bool inner, u8 *bit_mask)
1710{
1711 struct mlx5dr_match_misc2 *misc_2_mask = &value->misc2;
1712
1713 if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2_mask)) {
1714 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_label,
1715 misc_2_mask, outer_first_mpls_over_gre_label);
1716
1717 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_exp,
1718 misc_2_mask, outer_first_mpls_over_gre_exp);
1719
1720 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_s_bos,
1721 misc_2_mask, outer_first_mpls_over_gre_s_bos);
1722
1723 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_ttl,
1724 misc_2_mask, outer_first_mpls_over_gre_ttl);
1725 } else {
1726 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_label,
1727 misc_2_mask, outer_first_mpls_over_udp_label);
1728
1729 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_exp,
1730 misc_2_mask, outer_first_mpls_over_udp_exp);
1731
1732 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_s_bos,
1733 misc_2_mask, outer_first_mpls_over_udp_s_bos);
1734
1735 DR_STE_SET_MASK_V(flex_parser_0, bit_mask, parser_3_ttl,
1736 misc_2_mask, outer_first_mpls_over_udp_ttl);
1737 }
1738}
1739
1740static int dr_ste_build_flex_parser_0_tag(struct mlx5dr_match_param *value,
1741 struct mlx5dr_ste_build *sb,
1742 u8 *tag)
1743{
1744 struct mlx5dr_match_misc2 *misc_2_mask = &value->misc2;
1745
1746 if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2_mask)) {
1747 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label,
1748 misc_2_mask, outer_first_mpls_over_gre_label);
1749
1750 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp,
1751 misc_2_mask, outer_first_mpls_over_gre_exp);
1752
1753 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos,
1754 misc_2_mask, outer_first_mpls_over_gre_s_bos);
1755
1756 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl,
1757 misc_2_mask, outer_first_mpls_over_gre_ttl);
1758 } else {
1759 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label,
1760 misc_2_mask, outer_first_mpls_over_udp_label);
1761
1762 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp,
1763 misc_2_mask, outer_first_mpls_over_udp_exp);
1764
1765 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos,
1766 misc_2_mask, outer_first_mpls_over_udp_s_bos);
1767
1768 DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl,
1769 misc_2_mask, outer_first_mpls_over_udp_ttl);
1770 }
1771 return 0;
1772}
1773
1774void mlx5dr_ste_build_flex_parser_0(struct mlx5dr_ste_build *sb,
1775 struct mlx5dr_match_param *mask,
1776 bool inner, bool rx)
1777{
1778 dr_ste_build_flex_parser_0_bit_mask(mask, inner, sb->bit_mask);
1779
1780 sb->rx = rx;
1781 sb->inner = inner;
1782 sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_0;
1783 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1784 sb->ste_build_tag_func = &dr_ste_build_flex_parser_0_tag;
1785}
1786
1787#define ICMP_TYPE_OFFSET_FIRST_DW 24
1788#define ICMP_CODE_OFFSET_FIRST_DW 16
1789#define ICMP_HEADER_DATA_OFFSET_SECOND_DW 0
1790
1791static int dr_ste_build_flex_parser_1_bit_mask(struct mlx5dr_match_param *mask,
1792 struct mlx5dr_cmd_caps *caps,
1793 u8 *bit_mask)
1794{
1795 struct mlx5dr_match_misc3 *misc_3_mask = &mask->misc3;
1796 bool is_ipv4_mask = DR_MASK_IS_FLEX_PARSER_ICMPV4_SET(misc_3_mask);
1797 u32 icmp_header_data_mask;
1798 u32 icmp_type_mask;
1799 u32 icmp_code_mask;
1800 int dw0_location;
1801 int dw1_location;
1802
1803 if (is_ipv4_mask) {
1804 icmp_header_data_mask = misc_3_mask->icmpv4_header_data;
1805 icmp_type_mask = misc_3_mask->icmpv4_type;
1806 icmp_code_mask = misc_3_mask->icmpv4_code;
1807 dw0_location = caps->flex_parser_id_icmp_dw0;
1808 dw1_location = caps->flex_parser_id_icmp_dw1;
1809 } else {
1810 icmp_header_data_mask = misc_3_mask->icmpv6_header_data;
1811 icmp_type_mask = misc_3_mask->icmpv6_type;
1812 icmp_code_mask = misc_3_mask->icmpv6_code;
1813 dw0_location = caps->flex_parser_id_icmpv6_dw0;
1814 dw1_location = caps->flex_parser_id_icmpv6_dw1;
1815 }
1816
1817 switch (dw0_location) {
1818 case 4:
1819 if (icmp_type_mask) {
1820 MLX5_SET(ste_flex_parser_1, bit_mask, flex_parser_4,
1821 (icmp_type_mask << ICMP_TYPE_OFFSET_FIRST_DW));
1822 if (is_ipv4_mask)
1823 misc_3_mask->icmpv4_type = 0;
1824 else
1825 misc_3_mask->icmpv6_type = 0;
1826 }
1827 if (icmp_code_mask) {
1828 u32 cur_val = MLX5_GET(ste_flex_parser_1, bit_mask,
1829 flex_parser_4);
1830 MLX5_SET(ste_flex_parser_1, bit_mask, flex_parser_4,
1831 cur_val | (icmp_code_mask << ICMP_CODE_OFFSET_FIRST_DW));
1832 if (is_ipv4_mask)
1833 misc_3_mask->icmpv4_code = 0;
1834 else
1835 misc_3_mask->icmpv6_code = 0;
1836 }
1837 break;
1838 default:
1839 return -EINVAL;
1840 }
1841
1842 switch (dw1_location) {
1843 case 5:
1844 if (icmp_header_data_mask) {
1845 MLX5_SET(ste_flex_parser_1, bit_mask, flex_parser_5,
1846 (icmp_header_data_mask << ICMP_HEADER_DATA_OFFSET_SECOND_DW));
1847 if (is_ipv4_mask)
1848 misc_3_mask->icmpv4_header_data = 0;
1849 else
1850 misc_3_mask->icmpv6_header_data = 0;
1851 }
1852 break;
1853 default:
1854 return -EINVAL;
1855 }
1856
1857 return 0;
1858}
1859
1860static int dr_ste_build_flex_parser_1_tag(struct mlx5dr_match_param *value,
1861 struct mlx5dr_ste_build *sb,
1862 u8 *tag)
1863{
1864 struct mlx5dr_match_misc3 *misc_3 = &value->misc3;
1865 u32 icmp_header_data;
1866 int dw0_location;
1867 int dw1_location;
1868 u32 icmp_type;
1869 u32 icmp_code;
1870 bool is_ipv4;
1871
1872 is_ipv4 = DR_MASK_IS_FLEX_PARSER_ICMPV4_SET(misc_3);
1873 if (is_ipv4) {
1874 icmp_header_data = misc_3->icmpv4_header_data;
1875 icmp_type = misc_3->icmpv4_type;
1876 icmp_code = misc_3->icmpv4_code;
1877 dw0_location = sb->caps->flex_parser_id_icmp_dw0;
1878 dw1_location = sb->caps->flex_parser_id_icmp_dw1;
1879 } else {
1880 icmp_header_data = misc_3->icmpv6_header_data;
1881 icmp_type = misc_3->icmpv6_type;
1882 icmp_code = misc_3->icmpv6_code;
1883 dw0_location = sb->caps->flex_parser_id_icmpv6_dw0;
1884 dw1_location = sb->caps->flex_parser_id_icmpv6_dw1;
1885 }
1886
1887 switch (dw0_location) {
1888 case 4:
1889 if (icmp_type) {
1890 MLX5_SET(ste_flex_parser_1, tag, flex_parser_4,
1891 (icmp_type << ICMP_TYPE_OFFSET_FIRST_DW));
1892 if (is_ipv4)
1893 misc_3->icmpv4_type = 0;
1894 else
1895 misc_3->icmpv6_type = 0;
1896 }
1897
1898 if (icmp_code) {
1899 u32 cur_val = MLX5_GET(ste_flex_parser_1, tag,
1900 flex_parser_4);
1901 MLX5_SET(ste_flex_parser_1, tag, flex_parser_4,
1902 cur_val | (icmp_code << ICMP_CODE_OFFSET_FIRST_DW));
1903 if (is_ipv4)
1904 misc_3->icmpv4_code = 0;
1905 else
1906 misc_3->icmpv6_code = 0;
1907 }
1908 break;
1909 default:
1910 return -EINVAL;
1911 }
1912
1913 switch (dw1_location) {
1914 case 5:
1915 if (icmp_header_data) {
1916 MLX5_SET(ste_flex_parser_1, tag, flex_parser_5,
1917 (icmp_header_data << ICMP_HEADER_DATA_OFFSET_SECOND_DW));
1918 if (is_ipv4)
1919 misc_3->icmpv4_header_data = 0;
1920 else
1921 misc_3->icmpv6_header_data = 0;
1922 }
1923 break;
1924 default:
1925 return -EINVAL;
1926 }
1927
1928 return 0;
1929}
1930
1931int mlx5dr_ste_build_flex_parser_1(struct mlx5dr_ste_build *sb,
1932 struct mlx5dr_match_param *mask,
1933 struct mlx5dr_cmd_caps *caps,
1934 bool inner, bool rx)
1935{
1936 int ret;
1937
1938 ret = dr_ste_build_flex_parser_1_bit_mask(mask, caps, sb->bit_mask);
1939 if (ret)
1940 return ret;
1941
1942 sb->rx = rx;
1943 sb->inner = inner;
1944 sb->caps = caps;
1945 sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_1;
1946 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1947 sb->ste_build_tag_func = &dr_ste_build_flex_parser_1_tag;
1948
1949 return 0;
1950}
1951
1952static void dr_ste_build_general_purpose_bit_mask(struct mlx5dr_match_param *value,
1953 bool inner, u8 *bit_mask)
1954{
1955 struct mlx5dr_match_misc2 *misc_2_mask = &value->misc2;
1956
1957 DR_STE_SET_MASK_V(general_purpose, bit_mask,
1958 general_purpose_lookup_field, misc_2_mask,
1959 metadata_reg_a);
1960}
1961
1962static int dr_ste_build_general_purpose_tag(struct mlx5dr_match_param *value,
1963 struct mlx5dr_ste_build *sb,
1964 u8 *tag)
1965{
1966 struct mlx5dr_match_misc2 *misc_2_mask = &value->misc2;
1967
1968 DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field,
1969 misc_2_mask, metadata_reg_a);
1970
1971 return 0;
1972}
1973
1974void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_build *sb,
1975 struct mlx5dr_match_param *mask,
1976 bool inner, bool rx)
1977{
1978 dr_ste_build_general_purpose_bit_mask(mask, inner, sb->bit_mask);
1979
1980 sb->rx = rx;
1981 sb->inner = inner;
1982 sb->lu_type = MLX5DR_STE_LU_TYPE_GENERAL_PURPOSE;
1983 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1984 sb->ste_build_tag_func = &dr_ste_build_general_purpose_tag;
1985}
1986
1987static void dr_ste_build_eth_l4_misc_bit_mask(struct mlx5dr_match_param *value,
1988 bool inner, u8 *bit_mask)
1989{
1990 struct mlx5dr_match_misc3 *misc_3_mask = &value->misc3;
1991
1992 if (inner) {
1993 DR_STE_SET_MASK_V(eth_l4_misc, bit_mask, seq_num, misc_3_mask,
1994 inner_tcp_seq_num);
1995 DR_STE_SET_MASK_V(eth_l4_misc, bit_mask, ack_num, misc_3_mask,
1996 inner_tcp_ack_num);
1997 } else {
1998 DR_STE_SET_MASK_V(eth_l4_misc, bit_mask, seq_num, misc_3_mask,
1999 outer_tcp_seq_num);
2000 DR_STE_SET_MASK_V(eth_l4_misc, bit_mask, ack_num, misc_3_mask,
2001 outer_tcp_ack_num);
2002 }
2003}
2004
2005static int dr_ste_build_eth_l4_misc_tag(struct mlx5dr_match_param *value,
2006 struct mlx5dr_ste_build *sb,
2007 u8 *tag)
2008{
2009 struct mlx5dr_match_misc3 *misc3 = &value->misc3;
2010
2011 if (sb->inner) {
2012 DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num);
2013 DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num);
2014 } else {
2015 DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num);
2016 DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num);
2017 }
2018
2019 return 0;
2020}
2021
2022void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_build *sb,
2023 struct mlx5dr_match_param *mask,
2024 bool inner, bool rx)
2025{
2026 dr_ste_build_eth_l4_misc_bit_mask(mask, inner, sb->bit_mask);
2027
2028 sb->rx = rx;
2029 sb->inner = inner;
2030 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, rx, inner);
2031 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
2032 sb->ste_build_tag_func = &dr_ste_build_eth_l4_misc_tag;
2033}
2034
2035static void
2036dr_ste_build_flex_parser_tnl_vxlan_gpe_bit_mask(struct mlx5dr_match_param *value,
2037 bool inner, u8 *bit_mask)
2038{
2039 struct mlx5dr_match_misc3 *misc_3_mask = &value->misc3;
2040
2041 DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask,
2042 outer_vxlan_gpe_flags,
2043 misc_3_mask, outer_vxlan_gpe_flags);
2044 DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask,
2045 outer_vxlan_gpe_next_protocol,
2046 misc_3_mask, outer_vxlan_gpe_next_protocol);
2047 DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask,
2048 outer_vxlan_gpe_vni,
2049 misc_3_mask, outer_vxlan_gpe_vni);
2050}
2051
2052static int
2053dr_ste_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value,
2054 struct mlx5dr_ste_build *sb,
2055 u8 *tag)
2056{
2057 struct mlx5dr_match_misc3 *misc3 = &value->misc3;
2058
2059 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
2060 outer_vxlan_gpe_flags, misc3,
2061 outer_vxlan_gpe_flags);
2062 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
2063 outer_vxlan_gpe_next_protocol, misc3,
2064 outer_vxlan_gpe_next_protocol);
2065 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
2066 outer_vxlan_gpe_vni, misc3,
2067 outer_vxlan_gpe_vni);
2068
2069 return 0;
2070}
2071
2072void mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(struct mlx5dr_ste_build *sb,
2073 struct mlx5dr_match_param *mask,
2074 bool inner, bool rx)
2075{
2076 dr_ste_build_flex_parser_tnl_vxlan_gpe_bit_mask(mask, inner,
2077 sb->bit_mask);
2078
2079 sb->rx = rx;
2080 sb->inner = inner;
2081 sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER;
2082 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
2083 sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_vxlan_gpe_tag;
2084}
2085
2086static void
2087dr_ste_build_flex_parser_tnl_geneve_bit_mask(struct mlx5dr_match_param *value,
2088 u8 *bit_mask)
2089{
2090 struct mlx5dr_match_misc *misc_mask = &value->misc;
2091
2092 DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
2093 geneve_protocol_type,
2094 misc_mask, geneve_protocol_type);
2095 DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
2096 geneve_oam,
2097 misc_mask, geneve_oam);
2098 DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
2099 geneve_opt_len,
2100 misc_mask, geneve_opt_len);
2101 DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
2102 geneve_vni,
2103 misc_mask, geneve_vni);
2104}
2105
2106static int
2107dr_ste_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value,
2108 struct mlx5dr_ste_build *sb,
2109 u8 *tag)
2110{
2111 struct mlx5dr_match_misc *misc = &value->misc;
2112
2113 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
2114 geneve_protocol_type, misc, geneve_protocol_type);
2115 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
2116 geneve_oam, misc, geneve_oam);
2117 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
2118 geneve_opt_len, misc, geneve_opt_len);
2119 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
2120 geneve_vni, misc, geneve_vni);
2121
2122 return 0;
2123}
2124
2125void mlx5dr_ste_build_flex_parser_tnl_geneve(struct mlx5dr_ste_build *sb,
2126 struct mlx5dr_match_param *mask,
2127 bool inner, bool rx)
2128{
2129 dr_ste_build_flex_parser_tnl_geneve_bit_mask(mask, sb->bit_mask);
2130 sb->rx = rx;
2131 sb->inner = inner;
2132 sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER;
2133 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
2134 sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_geneve_tag;
2135}
2136
2137static void dr_ste_build_register_0_bit_mask(struct mlx5dr_match_param *value,
2138 u8 *bit_mask)
2139{
2140 struct mlx5dr_match_misc2 *misc_2_mask = &value->misc2;
2141
2142 DR_STE_SET_MASK_V(register_0, bit_mask, register_0_h,
2143 misc_2_mask, metadata_reg_c_0);
2144 DR_STE_SET_MASK_V(register_0, bit_mask, register_0_l,
2145 misc_2_mask, metadata_reg_c_1);
2146 DR_STE_SET_MASK_V(register_0, bit_mask, register_1_h,
2147 misc_2_mask, metadata_reg_c_2);
2148 DR_STE_SET_MASK_V(register_0, bit_mask, register_1_l,
2149 misc_2_mask, metadata_reg_c_3);
2150}
2151
2152static int dr_ste_build_register_0_tag(struct mlx5dr_match_param *value,
2153 struct mlx5dr_ste_build *sb,
2154 u8 *tag)
2155{
2156 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
2157
2158 DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0);
2159 DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1);
2160 DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2);
2161 DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3);
2162
2163 return 0;
2164}
2165
2166void mlx5dr_ste_build_register_0(struct mlx5dr_ste_build *sb,
2167 struct mlx5dr_match_param *mask,
2168 bool inner, bool rx)
2169{
2170 dr_ste_build_register_0_bit_mask(mask, sb->bit_mask);
2171
2172 sb->rx = rx;
2173 sb->inner = inner;
2174 sb->lu_type = MLX5DR_STE_LU_TYPE_STEERING_REGISTERS_0;
2175 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
2176 sb->ste_build_tag_func = &dr_ste_build_register_0_tag;
2177}
2178
2179static void dr_ste_build_register_1_bit_mask(struct mlx5dr_match_param *value,
2180 u8 *bit_mask)
2181{
2182 struct mlx5dr_match_misc2 *misc_2_mask = &value->misc2;
2183
2184 DR_STE_SET_MASK_V(register_1, bit_mask, register_2_h,
2185 misc_2_mask, metadata_reg_c_4);
2186 DR_STE_SET_MASK_V(register_1, bit_mask, register_2_l,
2187 misc_2_mask, metadata_reg_c_5);
2188 DR_STE_SET_MASK_V(register_1, bit_mask, register_3_h,
2189 misc_2_mask, metadata_reg_c_6);
2190 DR_STE_SET_MASK_V(register_1, bit_mask, register_3_l,
2191 misc_2_mask, metadata_reg_c_7);
2192}
2193
2194static int dr_ste_build_register_1_tag(struct mlx5dr_match_param *value,
2195 struct mlx5dr_ste_build *sb,
2196 u8 *tag)
2197{
2198 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
2199
2200 DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4);
2201 DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5);
2202 DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6);
2203 DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7);
2204
2205 return 0;
2206}
2207
2208void mlx5dr_ste_build_register_1(struct mlx5dr_ste_build *sb,
2209 struct mlx5dr_match_param *mask,
2210 bool inner, bool rx)
2211{
2212 dr_ste_build_register_1_bit_mask(mask, sb->bit_mask);
2213
2214 sb->rx = rx;
2215 sb->inner = inner;
2216 sb->lu_type = MLX5DR_STE_LU_TYPE_STEERING_REGISTERS_1;
2217 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
2218 sb->ste_build_tag_func = &dr_ste_build_register_1_tag;
2219}
2220
2221static void dr_ste_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value,
2222 u8 *bit_mask)
2223{
2224 struct mlx5dr_match_misc *misc_mask = &value->misc;
2225
2226 DR_STE_SET_MASK(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port);
2227 DR_STE_SET_MASK(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn);
2228 misc_mask->source_eswitch_owner_vhca_id = 0;
2229}
2230
2231static int dr_ste_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
2232 struct mlx5dr_ste_build *sb,
2233 u8 *tag)
2234{
2235 struct mlx5dr_match_misc *misc = &value->misc;
2236 struct mlx5dr_cmd_vport_cap *vport_cap;
2237 struct mlx5dr_domain *dmn = sb->dmn;
2238 struct mlx5dr_cmd_caps *caps;
2239 u8 *bit_mask = sb->bit_mask;
2240 bool source_gvmi_set;
2241
2242 DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn);
2243
2244 if (sb->vhca_id_valid) {
2245
2246 if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
2247 caps = &dmn->info.caps;
2248 else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
2249 dmn->peer_dmn->info.caps.gvmi))
2250 caps = &dmn->peer_dmn->info.caps;
2251 else
2252 return -EINVAL;
2253 } else {
2254 caps = &dmn->info.caps;
2255 }
2256
2257 vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port);
2258 if (!vport_cap)
2259 return -EINVAL;
2260
2261 source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi);
2262 if (vport_cap->vport_gvmi && source_gvmi_set)
2263 MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi);
2264
2265 misc->source_eswitch_owner_vhca_id = 0;
2266 misc->source_port = 0;
2267
2268 return 0;
2269}
2270
2271void mlx5dr_ste_build_src_gvmi_qpn(struct mlx5dr_ste_build *sb,
2272 struct mlx5dr_match_param *mask,
2273 struct mlx5dr_domain *dmn,
2274 bool inner, bool rx)
2275{
2276
2277 sb->vhca_id_valid = mask->misc.source_eswitch_owner_vhca_id;
2278
2279 dr_ste_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask);
2280
2281 sb->rx = rx;
2282 sb->dmn = dmn;
2283 sb->inner = inner;
2284 sb->lu_type = MLX5DR_STE_LU_TYPE_SRC_GVMI_AND_QP;
2285 sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
2286 sb->ste_build_tag_func = &dr_ste_build_src_gvmi_qpn_tag;
2287}
2288