1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */
3
4 #include <linux/types.h>
5 #include <linux/crc32.h>
6 #include "dr_ste.h"
7
8 #define SVLAN_ETHERTYPE 0x88a8
9 #define DR_STE_ENABLE_FLOW_TAG BIT(31)
10
11 enum dr_ste_v0_entry_type {
12 DR_STE_TYPE_TX = 1,
13 DR_STE_TYPE_RX = 2,
14 DR_STE_TYPE_MODIFY_PKT = 6,
15 };
16
17 enum dr_ste_v0_action_tunl {
18 DR_STE_TUNL_ACTION_NONE = 0,
19 DR_STE_TUNL_ACTION_ENABLE = 1,
20 DR_STE_TUNL_ACTION_DECAP = 2,
21 DR_STE_TUNL_ACTION_L3_DECAP = 3,
22 DR_STE_TUNL_ACTION_POP_VLAN = 4,
23 };
24
25 enum dr_ste_v0_action_type {
26 DR_STE_ACTION_TYPE_PUSH_VLAN = 1,
27 DR_STE_ACTION_TYPE_ENCAP_L3 = 3,
28 DR_STE_ACTION_TYPE_ENCAP = 4,
29 };
30
31 enum dr_ste_v0_action_mdfy_op {
32 DR_STE_ACTION_MDFY_OP_COPY = 0x1,
33 DR_STE_ACTION_MDFY_OP_SET = 0x2,
34 DR_STE_ACTION_MDFY_OP_ADD = 0x3,
35 };
36
37 #define DR_STE_CALC_LU_TYPE(lookup_type, rx, inner) \
38 ((inner) ? DR_STE_V0_LU_TYPE_##lookup_type##_I : \
39 (rx) ? DR_STE_V0_LU_TYPE_##lookup_type##_D : \
40 DR_STE_V0_LU_TYPE_##lookup_type##_O)
41
42 enum {
43 DR_STE_V0_LU_TYPE_NOP = 0x00,
44 DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP = 0x05,
45 DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I = 0x0a,
46 DR_STE_V0_LU_TYPE_ETHL2_DST_O = 0x06,
47 DR_STE_V0_LU_TYPE_ETHL2_DST_I = 0x07,
48 DR_STE_V0_LU_TYPE_ETHL2_DST_D = 0x1b,
49 DR_STE_V0_LU_TYPE_ETHL2_SRC_O = 0x08,
50 DR_STE_V0_LU_TYPE_ETHL2_SRC_I = 0x09,
51 DR_STE_V0_LU_TYPE_ETHL2_SRC_D = 0x1c,
52 DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_O = 0x36,
53 DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_I = 0x37,
54 DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_D = 0x38,
55 DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_O = 0x0d,
56 DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_I = 0x0e,
57 DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_D = 0x1e,
58 DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_O = 0x0f,
59 DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_I = 0x10,
60 DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_D = 0x1f,
61 DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_O = 0x11,
62 DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_I = 0x12,
63 DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_D = 0x20,
64 DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_O = 0x29,
65 DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_I = 0x2a,
66 DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_D = 0x2b,
67 DR_STE_V0_LU_TYPE_ETHL4_O = 0x13,
68 DR_STE_V0_LU_TYPE_ETHL4_I = 0x14,
69 DR_STE_V0_LU_TYPE_ETHL4_D = 0x21,
70 DR_STE_V0_LU_TYPE_ETHL4_MISC_O = 0x2c,
71 DR_STE_V0_LU_TYPE_ETHL4_MISC_I = 0x2d,
72 DR_STE_V0_LU_TYPE_ETHL4_MISC_D = 0x2e,
73 DR_STE_V0_LU_TYPE_MPLS_FIRST_O = 0x15,
74 DR_STE_V0_LU_TYPE_MPLS_FIRST_I = 0x24,
75 DR_STE_V0_LU_TYPE_MPLS_FIRST_D = 0x25,
76 DR_STE_V0_LU_TYPE_GRE = 0x16,
77 DR_STE_V0_LU_TYPE_FLEX_PARSER_0 = 0x22,
78 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 = 0x23,
79 DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER = 0x19,
80 DR_STE_V0_LU_TYPE_GENERAL_PURPOSE = 0x18,
81 DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0 = 0x2f,
82 DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1 = 0x30,
83 DR_STE_V0_LU_TYPE_DONT_CARE = MLX5DR_STE_LU_TYPE_DONT_CARE,
84 };
85
86 enum {
87 DR_STE_V0_ACTION_MDFY_FLD_L2_0 = 0,
88 DR_STE_V0_ACTION_MDFY_FLD_L2_1 = 1,
89 DR_STE_V0_ACTION_MDFY_FLD_L2_2 = 2,
90 DR_STE_V0_ACTION_MDFY_FLD_L3_0 = 3,
91 DR_STE_V0_ACTION_MDFY_FLD_L3_1 = 4,
92 DR_STE_V0_ACTION_MDFY_FLD_L3_2 = 5,
93 DR_STE_V0_ACTION_MDFY_FLD_L3_3 = 6,
94 DR_STE_V0_ACTION_MDFY_FLD_L3_4 = 7,
95 DR_STE_V0_ACTION_MDFY_FLD_L4_0 = 8,
96 DR_STE_V0_ACTION_MDFY_FLD_L4_1 = 9,
97 DR_STE_V0_ACTION_MDFY_FLD_MPLS = 10,
98 DR_STE_V0_ACTION_MDFY_FLD_L2_TNL_0 = 11,
99 DR_STE_V0_ACTION_MDFY_FLD_REG_0 = 12,
100 DR_STE_V0_ACTION_MDFY_FLD_REG_1 = 13,
101 DR_STE_V0_ACTION_MDFY_FLD_REG_2 = 14,
102 DR_STE_V0_ACTION_MDFY_FLD_REG_3 = 15,
103 DR_STE_V0_ACTION_MDFY_FLD_L4_2 = 16,
104 DR_STE_V0_ACTION_MDFY_FLD_FLEX_0 = 17,
105 DR_STE_V0_ACTION_MDFY_FLD_FLEX_1 = 18,
106 DR_STE_V0_ACTION_MDFY_FLD_FLEX_2 = 19,
107 DR_STE_V0_ACTION_MDFY_FLD_FLEX_3 = 20,
108 DR_STE_V0_ACTION_MDFY_FLD_L2_TNL_1 = 21,
109 DR_STE_V0_ACTION_MDFY_FLD_METADATA = 22,
110 DR_STE_V0_ACTION_MDFY_FLD_RESERVED = 23,
111 };
112
113 static const struct mlx5dr_ste_action_modify_field dr_ste_v0_action_modify_field_arr[] = {
114 [MLX5_ACTION_IN_FIELD_OUT_SMAC_47_16] = {
115 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_1, .start = 16, .end = 47,
116 },
117 [MLX5_ACTION_IN_FIELD_OUT_SMAC_15_0] = {
118 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_1, .start = 0, .end = 15,
119 },
120 [MLX5_ACTION_IN_FIELD_OUT_ETHERTYPE] = {
121 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_2, .start = 32, .end = 47,
122 },
123 [MLX5_ACTION_IN_FIELD_OUT_DMAC_47_16] = {
124 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_0, .start = 16, .end = 47,
125 },
126 [MLX5_ACTION_IN_FIELD_OUT_DMAC_15_0] = {
127 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_0, .start = 0, .end = 15,
128 },
129 [MLX5_ACTION_IN_FIELD_OUT_IP_DSCP] = {
130 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_1, .start = 0, .end = 5,
131 },
132 [MLX5_ACTION_IN_FIELD_OUT_TCP_FLAGS] = {
133 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 48, .end = 56,
134 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP,
135 },
136 [MLX5_ACTION_IN_FIELD_OUT_TCP_SPORT] = {
137 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 0, .end = 15,
138 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP,
139 },
140 [MLX5_ACTION_IN_FIELD_OUT_TCP_DPORT] = {
141 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 16, .end = 31,
142 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP,
143 },
144 [MLX5_ACTION_IN_FIELD_OUT_IP_TTL] = {
145 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_1, .start = 8, .end = 15,
146 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4,
147 },
148 [MLX5_ACTION_IN_FIELD_OUT_IPV6_HOPLIMIT] = {
149 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_1, .start = 8, .end = 15,
150 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
151 },
152 [MLX5_ACTION_IN_FIELD_OUT_UDP_SPORT] = {
153 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 0, .end = 15,
154 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP,
155 },
156 [MLX5_ACTION_IN_FIELD_OUT_UDP_DPORT] = {
157 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 16, .end = 31,
158 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP,
159 },
160 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_127_96] = {
161 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_3, .start = 32, .end = 63,
162 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
163 },
164 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_95_64] = {
165 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_3, .start = 0, .end = 31,
166 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
167 },
168 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_63_32] = {
169 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_4, .start = 32, .end = 63,
170 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
171 },
172 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_31_0] = {
173 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_4, .start = 0, .end = 31,
174 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
175 },
176 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_127_96] = {
177 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 32, .end = 63,
178 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
179 },
180 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_95_64] = {
181 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 0, .end = 31,
182 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
183 },
184 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_63_32] = {
185 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_2, .start = 32, .end = 63,
186 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
187 },
188 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_31_0] = {
189 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_2, .start = 0, .end = 31,
190 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
191 },
192 [MLX5_ACTION_IN_FIELD_OUT_SIPV4] = {
193 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 0, .end = 31,
194 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4,
195 },
196 [MLX5_ACTION_IN_FIELD_OUT_DIPV4] = {
197 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 32, .end = 63,
198 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4,
199 },
200 [MLX5_ACTION_IN_FIELD_METADATA_REG_A] = {
201 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_METADATA, .start = 0, .end = 31,
202 },
203 [MLX5_ACTION_IN_FIELD_METADATA_REG_B] = {
204 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_METADATA, .start = 32, .end = 63,
205 },
206 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_0] = {
207 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_0, .start = 32, .end = 63,
208 },
209 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_1] = {
210 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_0, .start = 0, .end = 31,
211 },
212 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_2] = {
213 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_1, .start = 32, .end = 63,
214 },
215 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_3] = {
216 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_1, .start = 0, .end = 31,
217 },
218 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_4] = {
219 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_2, .start = 32, .end = 63,
220 },
221 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_5] = {
222 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_2, .start = 0, .end = 31,
223 },
224 [MLX5_ACTION_IN_FIELD_OUT_TCP_SEQ_NUM] = {
225 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_1, .start = 32, .end = 63,
226 },
227 [MLX5_ACTION_IN_FIELD_OUT_TCP_ACK_NUM] = {
228 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_1, .start = 0, .end = 31,
229 },
230 [MLX5_ACTION_IN_FIELD_OUT_FIRST_VID] = {
231 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_2, .start = 0, .end = 15,
232 },
233 };
234
dr_ste_v0_set_entry_type(u8 * hw_ste_p,u8 entry_type)235 static void dr_ste_v0_set_entry_type(u8 *hw_ste_p, u8 entry_type)
236 {
237 MLX5_SET(ste_general, hw_ste_p, entry_type, entry_type);
238 }
239
dr_ste_v0_get_entry_type(u8 * hw_ste_p)240 static u8 dr_ste_v0_get_entry_type(u8 *hw_ste_p)
241 {
242 return MLX5_GET(ste_general, hw_ste_p, entry_type);
243 }
244
dr_ste_v0_set_miss_addr(u8 * hw_ste_p,u64 miss_addr)245 static void dr_ste_v0_set_miss_addr(u8 *hw_ste_p, u64 miss_addr)
246 {
247 u64 index = miss_addr >> 6;
248
249 /* Miss address for TX and RX STEs located in the same offsets */
250 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32, index >> 26);
251 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6, index);
252 }
253
dr_ste_v0_get_miss_addr(u8 * hw_ste_p)254 static u64 dr_ste_v0_get_miss_addr(u8 *hw_ste_p)
255 {
256 u64 index =
257 ((u64)MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6) |
258 ((u64)MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32)) << 26);
259
260 return index << 6;
261 }
262
dr_ste_v0_set_byte_mask(u8 * hw_ste_p,u16 byte_mask)263 static void dr_ste_v0_set_byte_mask(u8 *hw_ste_p, u16 byte_mask)
264 {
265 MLX5_SET(ste_general, hw_ste_p, byte_mask, byte_mask);
266 }
267
dr_ste_v0_get_byte_mask(u8 * hw_ste_p)268 static u16 dr_ste_v0_get_byte_mask(u8 *hw_ste_p)
269 {
270 return MLX5_GET(ste_general, hw_ste_p, byte_mask);
271 }
272
dr_ste_v0_set_lu_type(u8 * hw_ste_p,u16 lu_type)273 static void dr_ste_v0_set_lu_type(u8 *hw_ste_p, u16 lu_type)
274 {
275 MLX5_SET(ste_general, hw_ste_p, entry_sub_type, lu_type);
276 }
277
dr_ste_v0_set_next_lu_type(u8 * hw_ste_p,u16 lu_type)278 static void dr_ste_v0_set_next_lu_type(u8 *hw_ste_p, u16 lu_type)
279 {
280 MLX5_SET(ste_general, hw_ste_p, next_lu_type, lu_type);
281 }
282
dr_ste_v0_get_next_lu_type(u8 * hw_ste_p)283 static u16 dr_ste_v0_get_next_lu_type(u8 *hw_ste_p)
284 {
285 return MLX5_GET(ste_general, hw_ste_p, next_lu_type);
286 }
287
dr_ste_v0_set_hit_gvmi(u8 * hw_ste_p,u16 gvmi)288 static void dr_ste_v0_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi)
289 {
290 MLX5_SET(ste_general, hw_ste_p, next_table_base_63_48, gvmi);
291 }
292
dr_ste_v0_set_hit_addr(u8 * hw_ste_p,u64 icm_addr,u32 ht_size)293 static void dr_ste_v0_set_hit_addr(u8 *hw_ste_p, u64 icm_addr, u32 ht_size)
294 {
295 u64 index = (icm_addr >> 5) | ht_size;
296
297 MLX5_SET(ste_general, hw_ste_p, next_table_base_39_32_size, index >> 27);
298 MLX5_SET(ste_general, hw_ste_p, next_table_base_31_5_size, index);
299 }
300
dr_ste_v0_init_full(u8 * hw_ste_p,u16 lu_type,enum dr_ste_v0_entry_type entry_type,u16 gvmi)301 static void dr_ste_v0_init_full(u8 *hw_ste_p, u16 lu_type,
302 enum dr_ste_v0_entry_type entry_type, u16 gvmi)
303 {
304 dr_ste_v0_set_entry_type(hw_ste_p, entry_type);
305 dr_ste_v0_set_lu_type(hw_ste_p, lu_type);
306 dr_ste_v0_set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE);
307
308 /* Set GVMI once, this is the same for RX/TX
309 * bits 63_48 of next table base / miss address encode the next GVMI
310 */
311 MLX5_SET(ste_rx_steering_mult, hw_ste_p, gvmi, gvmi);
312 MLX5_SET(ste_rx_steering_mult, hw_ste_p, next_table_base_63_48, gvmi);
313 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_63_48, gvmi);
314 }
315
dr_ste_v0_init(u8 * hw_ste_p,u16 lu_type,bool is_rx,u16 gvmi)316 static void dr_ste_v0_init(u8 *hw_ste_p, u16 lu_type,
317 bool is_rx, u16 gvmi)
318 {
319 enum dr_ste_v0_entry_type entry_type;
320
321 entry_type = is_rx ? DR_STE_TYPE_RX : DR_STE_TYPE_TX;
322 dr_ste_v0_init_full(hw_ste_p, lu_type, entry_type, gvmi);
323 }
324
dr_ste_v0_rx_set_flow_tag(u8 * hw_ste_p,u32 flow_tag)325 static void dr_ste_v0_rx_set_flow_tag(u8 *hw_ste_p, u32 flow_tag)
326 {
327 MLX5_SET(ste_rx_steering_mult, hw_ste_p, qp_list_pointer,
328 DR_STE_ENABLE_FLOW_TAG | flow_tag);
329 }
330
dr_ste_v0_set_counter_id(u8 * hw_ste_p,u32 ctr_id)331 static void dr_ste_v0_set_counter_id(u8 *hw_ste_p, u32 ctr_id)
332 {
333 /* This can be used for both rx_steering_mult and for sx_transmit */
334 MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_15_0, ctr_id);
335 MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_23_16, ctr_id >> 16);
336 }
337
dr_ste_v0_set_go_back_bit(u8 * hw_ste_p)338 static void dr_ste_v0_set_go_back_bit(u8 *hw_ste_p)
339 {
340 MLX5_SET(ste_sx_transmit, hw_ste_p, go_back, 1);
341 }
342
dr_ste_v0_set_tx_push_vlan(u8 * hw_ste_p,u32 vlan_hdr,bool go_back)343 static void dr_ste_v0_set_tx_push_vlan(u8 *hw_ste_p, u32 vlan_hdr,
344 bool go_back)
345 {
346 MLX5_SET(ste_sx_transmit, hw_ste_p, action_type,
347 DR_STE_ACTION_TYPE_PUSH_VLAN);
348 MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, vlan_hdr);
349 /* Due to HW limitation we need to set this bit, otherwise reformat +
350 * push vlan will not work.
351 */
352 if (go_back)
353 dr_ste_v0_set_go_back_bit(hw_ste_p);
354 }
355
dr_ste_v0_set_tx_encap(void * hw_ste_p,u32 reformat_id,int size,bool encap_l3)356 static void dr_ste_v0_set_tx_encap(void *hw_ste_p, u32 reformat_id,
357 int size, bool encap_l3)
358 {
359 MLX5_SET(ste_sx_transmit, hw_ste_p, action_type,
360 encap_l3 ? DR_STE_ACTION_TYPE_ENCAP_L3 : DR_STE_ACTION_TYPE_ENCAP);
361 /* The hardware expects here size in words (2 byte) */
362 MLX5_SET(ste_sx_transmit, hw_ste_p, action_description, size / 2);
363 MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, reformat_id);
364 }
365
dr_ste_v0_set_rx_decap(u8 * hw_ste_p)366 static void dr_ste_v0_set_rx_decap(u8 *hw_ste_p)
367 {
368 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action,
369 DR_STE_TUNL_ACTION_DECAP);
370 MLX5_SET(ste_rx_steering_mult, hw_ste_p, fail_on_error, 1);
371 }
372
dr_ste_v0_set_rx_pop_vlan(u8 * hw_ste_p)373 static void dr_ste_v0_set_rx_pop_vlan(u8 *hw_ste_p)
374 {
375 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action,
376 DR_STE_TUNL_ACTION_POP_VLAN);
377 }
378
dr_ste_v0_set_rx_decap_l3(u8 * hw_ste_p,bool vlan)379 static void dr_ste_v0_set_rx_decap_l3(u8 *hw_ste_p, bool vlan)
380 {
381 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action,
382 DR_STE_TUNL_ACTION_L3_DECAP);
383 MLX5_SET(ste_modify_packet, hw_ste_p, action_description, vlan ? 1 : 0);
384 MLX5_SET(ste_rx_steering_mult, hw_ste_p, fail_on_error, 1);
385 }
386
dr_ste_v0_set_rewrite_actions(u8 * hw_ste_p,u16 num_of_actions,u32 re_write_index)387 static void dr_ste_v0_set_rewrite_actions(u8 *hw_ste_p, u16 num_of_actions,
388 u32 re_write_index)
389 {
390 MLX5_SET(ste_modify_packet, hw_ste_p, number_of_re_write_actions,
391 num_of_actions);
392 MLX5_SET(ste_modify_packet, hw_ste_p, header_re_write_actions_pointer,
393 re_write_index);
394 }
395
dr_ste_v0_arr_init_next(u8 ** last_ste,u32 * added_stes,enum dr_ste_v0_entry_type entry_type,u16 gvmi)396 static void dr_ste_v0_arr_init_next(u8 **last_ste,
397 u32 *added_stes,
398 enum dr_ste_v0_entry_type entry_type,
399 u16 gvmi)
400 {
401 (*added_stes)++;
402 *last_ste += DR_STE_SIZE;
403 dr_ste_v0_init_full(*last_ste, MLX5DR_STE_LU_TYPE_DONT_CARE,
404 entry_type, gvmi);
405 }
406
407 static void
dr_ste_v0_set_actions_tx(struct mlx5dr_domain * dmn,u8 * action_type_set,u8 * last_ste,struct mlx5dr_ste_actions_attr * attr,u32 * added_stes)408 dr_ste_v0_set_actions_tx(struct mlx5dr_domain *dmn,
409 u8 *action_type_set,
410 u8 *last_ste,
411 struct mlx5dr_ste_actions_attr *attr,
412 u32 *added_stes)
413 {
414 bool encap = action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2] ||
415 action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3];
416
417 /* We want to make sure the modify header comes before L2
418 * encapsulation. The reason for that is that we support
419 * modify headers for outer headers only
420 */
421 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) {
422 dr_ste_v0_set_entry_type(last_ste, DR_STE_TYPE_MODIFY_PKT);
423 dr_ste_v0_set_rewrite_actions(last_ste,
424 attr->modify_actions,
425 attr->modify_index);
426 }
427
428 if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) {
429 int i;
430
431 for (i = 0; i < attr->vlans.count; i++) {
432 if (i || action_type_set[DR_ACTION_TYP_MODIFY_HDR])
433 dr_ste_v0_arr_init_next(&last_ste,
434 added_stes,
435 DR_STE_TYPE_TX,
436 attr->gvmi);
437
438 dr_ste_v0_set_tx_push_vlan(last_ste,
439 attr->vlans.headers[i],
440 encap);
441 }
442 }
443
444 if (encap) {
445 /* Modify header and encapsulation require a different STEs.
446 * Since modify header STE format doesn't support encapsulation
447 * tunneling_action.
448 */
449 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR] ||
450 action_type_set[DR_ACTION_TYP_PUSH_VLAN])
451 dr_ste_v0_arr_init_next(&last_ste,
452 added_stes,
453 DR_STE_TYPE_TX,
454 attr->gvmi);
455
456 dr_ste_v0_set_tx_encap(last_ste,
457 attr->reformat.id,
458 attr->reformat.size,
459 action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]);
460 /* Whenever prio_tag_required enabled, we can be sure that the
461 * previous table (ACL) already push vlan to our packet,
462 * And due to HW limitation we need to set this bit, otherwise
463 * push vlan + reformat will not work.
464 */
465 if (MLX5_CAP_GEN(dmn->mdev, prio_tag_required))
466 dr_ste_v0_set_go_back_bit(last_ste);
467 }
468
469 if (action_type_set[DR_ACTION_TYP_CTR])
470 dr_ste_v0_set_counter_id(last_ste, attr->ctr_id);
471
472 dr_ste_v0_set_hit_gvmi(last_ste, attr->hit_gvmi);
473 dr_ste_v0_set_hit_addr(last_ste, attr->final_icm_addr, 1);
474 }
475
476 static void
dr_ste_v0_set_actions_rx(struct mlx5dr_domain * dmn,u8 * action_type_set,u8 * last_ste,struct mlx5dr_ste_actions_attr * attr,u32 * added_stes)477 dr_ste_v0_set_actions_rx(struct mlx5dr_domain *dmn,
478 u8 *action_type_set,
479 u8 *last_ste,
480 struct mlx5dr_ste_actions_attr *attr,
481 u32 *added_stes)
482 {
483 if (action_type_set[DR_ACTION_TYP_CTR])
484 dr_ste_v0_set_counter_id(last_ste, attr->ctr_id);
485
486 if (action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) {
487 dr_ste_v0_set_entry_type(last_ste, DR_STE_TYPE_MODIFY_PKT);
488 dr_ste_v0_set_rx_decap_l3(last_ste, attr->decap_with_vlan);
489 dr_ste_v0_set_rewrite_actions(last_ste,
490 attr->decap_actions,
491 attr->decap_index);
492 }
493
494 if (action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2])
495 dr_ste_v0_set_rx_decap(last_ste);
496
497 if (action_type_set[DR_ACTION_TYP_POP_VLAN]) {
498 int i;
499
500 for (i = 0; i < attr->vlans.count; i++) {
501 if (i ||
502 action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2] ||
503 action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2])
504 dr_ste_v0_arr_init_next(&last_ste,
505 added_stes,
506 DR_STE_TYPE_RX,
507 attr->gvmi);
508
509 dr_ste_v0_set_rx_pop_vlan(last_ste);
510 }
511 }
512
513 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) {
514 if (dr_ste_v0_get_entry_type(last_ste) == DR_STE_TYPE_MODIFY_PKT)
515 dr_ste_v0_arr_init_next(&last_ste,
516 added_stes,
517 DR_STE_TYPE_MODIFY_PKT,
518 attr->gvmi);
519 else
520 dr_ste_v0_set_entry_type(last_ste, DR_STE_TYPE_MODIFY_PKT);
521
522 dr_ste_v0_set_rewrite_actions(last_ste,
523 attr->modify_actions,
524 attr->modify_index);
525 }
526
527 if (action_type_set[DR_ACTION_TYP_TAG]) {
528 if (dr_ste_v0_get_entry_type(last_ste) == DR_STE_TYPE_MODIFY_PKT)
529 dr_ste_v0_arr_init_next(&last_ste,
530 added_stes,
531 DR_STE_TYPE_RX,
532 attr->gvmi);
533
534 dr_ste_v0_rx_set_flow_tag(last_ste, attr->flow_tag);
535 }
536
537 dr_ste_v0_set_hit_gvmi(last_ste, attr->hit_gvmi);
538 dr_ste_v0_set_hit_addr(last_ste, attr->final_icm_addr, 1);
539 }
540
dr_ste_v0_set_action_set(u8 * hw_action,u8 hw_field,u8 shifter,u8 length,u32 data)541 static void dr_ste_v0_set_action_set(u8 *hw_action,
542 u8 hw_field,
543 u8 shifter,
544 u8 length,
545 u32 data)
546 {
547 length = (length == 32) ? 0 : length;
548 MLX5_SET(dr_action_hw_set, hw_action, opcode, DR_STE_ACTION_MDFY_OP_SET);
549 MLX5_SET(dr_action_hw_set, hw_action, destination_field_code, hw_field);
550 MLX5_SET(dr_action_hw_set, hw_action, destination_left_shifter, shifter);
551 MLX5_SET(dr_action_hw_set, hw_action, destination_length, length);
552 MLX5_SET(dr_action_hw_set, hw_action, inline_data, data);
553 }
554
dr_ste_v0_set_action_add(u8 * hw_action,u8 hw_field,u8 shifter,u8 length,u32 data)555 static void dr_ste_v0_set_action_add(u8 *hw_action,
556 u8 hw_field,
557 u8 shifter,
558 u8 length,
559 u32 data)
560 {
561 length = (length == 32) ? 0 : length;
562 MLX5_SET(dr_action_hw_set, hw_action, opcode, DR_STE_ACTION_MDFY_OP_ADD);
563 MLX5_SET(dr_action_hw_set, hw_action, destination_field_code, hw_field);
564 MLX5_SET(dr_action_hw_set, hw_action, destination_left_shifter, shifter);
565 MLX5_SET(dr_action_hw_set, hw_action, destination_length, length);
566 MLX5_SET(dr_action_hw_set, hw_action, inline_data, data);
567 }
568
dr_ste_v0_set_action_copy(u8 * hw_action,u8 dst_hw_field,u8 dst_shifter,u8 dst_len,u8 src_hw_field,u8 src_shifter)569 static void dr_ste_v0_set_action_copy(u8 *hw_action,
570 u8 dst_hw_field,
571 u8 dst_shifter,
572 u8 dst_len,
573 u8 src_hw_field,
574 u8 src_shifter)
575 {
576 MLX5_SET(dr_action_hw_copy, hw_action, opcode, DR_STE_ACTION_MDFY_OP_COPY);
577 MLX5_SET(dr_action_hw_copy, hw_action, destination_field_code, dst_hw_field);
578 MLX5_SET(dr_action_hw_copy, hw_action, destination_left_shifter, dst_shifter);
579 MLX5_SET(dr_action_hw_copy, hw_action, destination_length, dst_len);
580 MLX5_SET(dr_action_hw_copy, hw_action, source_field_code, src_hw_field);
581 MLX5_SET(dr_action_hw_copy, hw_action, source_left_shifter, src_shifter);
582 }
583
584 #define DR_STE_DECAP_L3_MIN_ACTION_NUM 5
585
586 static int
dr_ste_v0_set_action_decap_l3_list(void * data,u32 data_sz,u8 * hw_action,u32 hw_action_sz,u16 * used_hw_action_num)587 dr_ste_v0_set_action_decap_l3_list(void *data, u32 data_sz,
588 u8 *hw_action, u32 hw_action_sz,
589 u16 *used_hw_action_num)
590 {
591 struct mlx5_ifc_l2_hdr_bits *l2_hdr = data;
592 u32 hw_action_num;
593 int required_actions;
594 u32 hdr_fld_4b;
595 u16 hdr_fld_2b;
596 u16 vlan_type;
597 bool vlan;
598
599 vlan = (data_sz != HDR_LEN_L2);
600 hw_action_num = hw_action_sz / MLX5_ST_SZ_BYTES(dr_action_hw_set);
601 required_actions = DR_STE_DECAP_L3_MIN_ACTION_NUM + !!vlan;
602
603 if (hw_action_num < required_actions)
604 return -ENOMEM;
605
606 /* dmac_47_16 */
607 MLX5_SET(dr_action_hw_set, hw_action,
608 opcode, DR_STE_ACTION_MDFY_OP_SET);
609 MLX5_SET(dr_action_hw_set, hw_action,
610 destination_length, 0);
611 MLX5_SET(dr_action_hw_set, hw_action,
612 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_0);
613 MLX5_SET(dr_action_hw_set, hw_action,
614 destination_left_shifter, 16);
615 hdr_fld_4b = MLX5_GET(l2_hdr, l2_hdr, dmac_47_16);
616 MLX5_SET(dr_action_hw_set, hw_action,
617 inline_data, hdr_fld_4b);
618 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set);
619
620 /* smac_47_16 */
621 MLX5_SET(dr_action_hw_set, hw_action,
622 opcode, DR_STE_ACTION_MDFY_OP_SET);
623 MLX5_SET(dr_action_hw_set, hw_action,
624 destination_length, 0);
625 MLX5_SET(dr_action_hw_set, hw_action,
626 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_1);
627 MLX5_SET(dr_action_hw_set, hw_action, destination_left_shifter, 16);
628 hdr_fld_4b = (MLX5_GET(l2_hdr, l2_hdr, smac_31_0) >> 16 |
629 MLX5_GET(l2_hdr, l2_hdr, smac_47_32) << 16);
630 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_4b);
631 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set);
632
633 /* dmac_15_0 */
634 MLX5_SET(dr_action_hw_set, hw_action,
635 opcode, DR_STE_ACTION_MDFY_OP_SET);
636 MLX5_SET(dr_action_hw_set, hw_action,
637 destination_length, 16);
638 MLX5_SET(dr_action_hw_set, hw_action,
639 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_0);
640 MLX5_SET(dr_action_hw_set, hw_action,
641 destination_left_shifter, 0);
642 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, dmac_15_0);
643 MLX5_SET(dr_action_hw_set, hw_action,
644 inline_data, hdr_fld_2b);
645 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set);
646
647 /* ethertype + (optional) vlan */
648 MLX5_SET(dr_action_hw_set, hw_action,
649 opcode, DR_STE_ACTION_MDFY_OP_SET);
650 MLX5_SET(dr_action_hw_set, hw_action,
651 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_2);
652 MLX5_SET(dr_action_hw_set, hw_action,
653 destination_left_shifter, 32);
654 if (!vlan) {
655 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, ethertype);
656 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_2b);
657 MLX5_SET(dr_action_hw_set, hw_action, destination_length, 16);
658 } else {
659 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, ethertype);
660 vlan_type = hdr_fld_2b == SVLAN_ETHERTYPE ? DR_STE_SVLAN : DR_STE_CVLAN;
661 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, vlan);
662 hdr_fld_4b = (vlan_type << 16) | hdr_fld_2b;
663 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_4b);
664 MLX5_SET(dr_action_hw_set, hw_action, destination_length, 18);
665 }
666 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set);
667
668 /* smac_15_0 */
669 MLX5_SET(dr_action_hw_set, hw_action,
670 opcode, DR_STE_ACTION_MDFY_OP_SET);
671 MLX5_SET(dr_action_hw_set, hw_action,
672 destination_length, 16);
673 MLX5_SET(dr_action_hw_set, hw_action,
674 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_1);
675 MLX5_SET(dr_action_hw_set, hw_action,
676 destination_left_shifter, 0);
677 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, smac_31_0);
678 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_2b);
679 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set);
680
681 if (vlan) {
682 MLX5_SET(dr_action_hw_set, hw_action,
683 opcode, DR_STE_ACTION_MDFY_OP_SET);
684 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, vlan_type);
685 MLX5_SET(dr_action_hw_set, hw_action,
686 inline_data, hdr_fld_2b);
687 MLX5_SET(dr_action_hw_set, hw_action,
688 destination_length, 16);
689 MLX5_SET(dr_action_hw_set, hw_action,
690 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_2);
691 MLX5_SET(dr_action_hw_set, hw_action,
692 destination_left_shifter, 0);
693 }
694
695 *used_hw_action_num = required_actions;
696
697 return 0;
698 }
699
700 static void
dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param * value,bool inner,u8 * bit_mask)701 dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value,
702 bool inner, u8 *bit_mask)
703 {
704 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
705
706 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
707 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
708
709 if (mask->smac_47_16 || mask->smac_15_0) {
710 MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32,
711 mask->smac_47_16 >> 16);
712 MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0,
713 mask->smac_47_16 << 16 | mask->smac_15_0);
714 mask->smac_47_16 = 0;
715 mask->smac_15_0 = 0;
716 }
717
718 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid);
719 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi);
720 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio);
721 DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version);
722
723 if (mask->cvlan_tag) {
724 MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
725 mask->cvlan_tag = 0;
726 } else if (mask->svlan_tag) {
727 MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
728 mask->svlan_tag = 0;
729 }
730 }
731
732 static int
dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)733 dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value,
734 struct mlx5dr_ste_build *sb,
735 u8 *tag)
736 {
737 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
738
739 DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16);
740 DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0);
741
742 if (spec->smac_47_16 || spec->smac_15_0) {
743 MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32,
744 spec->smac_47_16 >> 16);
745 MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0,
746 spec->smac_47_16 << 16 | spec->smac_15_0);
747 spec->smac_47_16 = 0;
748 spec->smac_15_0 = 0;
749 }
750
751 if (spec->ip_version) {
752 if (spec->ip_version == IP_VERSION_IPV4) {
753 MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4);
754 spec->ip_version = 0;
755 } else if (spec->ip_version == IP_VERSION_IPV6) {
756 MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6);
757 spec->ip_version = 0;
758 } else {
759 return -EINVAL;
760 }
761 }
762
763 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid);
764 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi);
765 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio);
766
767 if (spec->cvlan_tag) {
768 MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN);
769 spec->cvlan_tag = 0;
770 } else if (spec->svlan_tag) {
771 MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN);
772 spec->svlan_tag = 0;
773 }
774 return 0;
775 }
776
777 static void
dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)778 dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb,
779 struct mlx5dr_match_param *mask)
780 {
781 dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask);
782
783 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner);
784 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
785 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag;
786 }
787
788 static int
dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)789 dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value,
790 struct mlx5dr_ste_build *sb,
791 u8 *tag)
792 {
793 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
794
795 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96);
796 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64);
797 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32);
798 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0);
799
800 return 0;
801 }
802
803 static void
dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)804 dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb,
805 struct mlx5dr_match_param *mask)
806 {
807 dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask);
808
809 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, sb->rx, sb->inner);
810 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
811 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_dst_tag;
812 }
813
814 static int
dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)815 dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value,
816 struct mlx5dr_ste_build *sb,
817 u8 *tag)
818 {
819 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
820
821 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96);
822 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64);
823 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32);
824 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0);
825
826 return 0;
827 }
828
829 static void
dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)830 dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb,
831 struct mlx5dr_match_param *mask)
832 {
833 dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask);
834
835 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner);
836 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
837 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag;
838 }
839
840 static int
dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)841 dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value,
842 struct mlx5dr_ste_build *sb,
843 u8 *tag)
844 {
845 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
846
847 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0);
848 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0);
849 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport);
850 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport);
851 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport);
852 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport);
853 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol);
854 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag);
855 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp);
856 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn);
857
858 if (spec->tcp_flags) {
859 DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec);
860 spec->tcp_flags = 0;
861 }
862
863 return 0;
864 }
865
866 static void
dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)867 dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb,
868 struct mlx5dr_match_param *mask)
869 {
870 dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask);
871
872 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner);
873 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
874 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag;
875 }
876
877 static void
dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param * value,bool inner,u8 * bit_mask)878 dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value,
879 bool inner, u8 *bit_mask)
880 {
881 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
882 struct mlx5dr_match_misc *misc_mask = &value->misc;
883
884 DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid);
885 DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi);
886 DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio);
887 DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag);
888 DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype);
889 DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version);
890
891 if (mask->svlan_tag || mask->cvlan_tag) {
892 MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1);
893 mask->cvlan_tag = 0;
894 mask->svlan_tag = 0;
895 }
896
897 if (inner) {
898 if (misc_mask->inner_second_cvlan_tag ||
899 misc_mask->inner_second_svlan_tag) {
900 MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
901 misc_mask->inner_second_cvlan_tag = 0;
902 misc_mask->inner_second_svlan_tag = 0;
903 }
904
905 DR_STE_SET_TAG(eth_l2_src, bit_mask,
906 second_vlan_id, misc_mask, inner_second_vid);
907 DR_STE_SET_TAG(eth_l2_src, bit_mask,
908 second_cfi, misc_mask, inner_second_cfi);
909 DR_STE_SET_TAG(eth_l2_src, bit_mask,
910 second_priority, misc_mask, inner_second_prio);
911 } else {
912 if (misc_mask->outer_second_cvlan_tag ||
913 misc_mask->outer_second_svlan_tag) {
914 MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
915 misc_mask->outer_second_cvlan_tag = 0;
916 misc_mask->outer_second_svlan_tag = 0;
917 }
918
919 DR_STE_SET_TAG(eth_l2_src, bit_mask,
920 second_vlan_id, misc_mask, outer_second_vid);
921 DR_STE_SET_TAG(eth_l2_src, bit_mask,
922 second_cfi, misc_mask, outer_second_cfi);
923 DR_STE_SET_TAG(eth_l2_src, bit_mask,
924 second_priority, misc_mask, outer_second_prio);
925 }
926 }
927
928 static int
dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param * value,bool inner,u8 * tag)929 dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value,
930 bool inner, u8 *tag)
931 {
932 struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer;
933 struct mlx5dr_match_misc *misc_spec = &value->misc;
934
935 DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid);
936 DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi);
937 DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio);
938 DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag);
939 DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype);
940
941 if (spec->ip_version) {
942 if (spec->ip_version == IP_VERSION_IPV4) {
943 MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4);
944 spec->ip_version = 0;
945 } else if (spec->ip_version == IP_VERSION_IPV6) {
946 MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6);
947 spec->ip_version = 0;
948 } else {
949 return -EINVAL;
950 }
951 }
952
953 if (spec->cvlan_tag) {
954 MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN);
955 spec->cvlan_tag = 0;
956 } else if (spec->svlan_tag) {
957 MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN);
958 spec->svlan_tag = 0;
959 }
960
961 if (inner) {
962 if (misc_spec->inner_second_cvlan_tag) {
963 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
964 misc_spec->inner_second_cvlan_tag = 0;
965 } else if (misc_spec->inner_second_svlan_tag) {
966 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
967 misc_spec->inner_second_svlan_tag = 0;
968 }
969
970 DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid);
971 DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi);
972 DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio);
973 } else {
974 if (misc_spec->outer_second_cvlan_tag) {
975 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
976 misc_spec->outer_second_cvlan_tag = 0;
977 } else if (misc_spec->outer_second_svlan_tag) {
978 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
979 misc_spec->outer_second_svlan_tag = 0;
980 }
981 DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid);
982 DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi);
983 DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio);
984 }
985
986 return 0;
987 }
988
989 static void
dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param * value,bool inner,u8 * bit_mask)990 dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value,
991 bool inner, u8 *bit_mask)
992 {
993 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
994
995 DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16);
996 DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0);
997
998 dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
999 }
1000
1001 static int
dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1002 dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value,
1003 struct mlx5dr_ste_build *sb,
1004 u8 *tag)
1005 {
1006 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1007
1008 DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16);
1009 DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0);
1010
1011 return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
1012 }
1013
1014 static void
dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1015 dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb,
1016 struct mlx5dr_match_param *mask)
1017 {
1018 dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask);
1019 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner);
1020 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1021 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag;
1022 }
1023
1024 static void
dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * bit_mask)1025 dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value,
1026 struct mlx5dr_ste_build *sb,
1027 u8 *bit_mask)
1028 {
1029 struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer;
1030
1031 DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
1032 DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
1033
1034 dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask);
1035 }
1036
1037 static int
dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1038 dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value,
1039 struct mlx5dr_ste_build *sb,
1040 u8 *tag)
1041 {
1042 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1043
1044 DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16);
1045 DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0);
1046
1047 return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
1048 }
1049
1050 static void
dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1051 dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb,
1052 struct mlx5dr_match_param *mask)
1053 {
1054 dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask);
1055
1056 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner);
1057 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1058 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag;
1059 }
1060
1061 static void
dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param * value,bool inner,u8 * bit_mask)1062 dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value,
1063 bool inner, u8 *bit_mask)
1064 {
1065 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1066 struct mlx5dr_match_misc *misc = &value->misc;
1067
1068 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16);
1069 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0);
1070 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid);
1071 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi);
1072 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio);
1073 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag);
1074 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype);
1075 DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version);
1076
1077 if (misc->vxlan_vni) {
1078 MLX5_SET(ste_eth_l2_tnl, bit_mask,
1079 l2_tunneling_network_id, (misc->vxlan_vni << 8));
1080 misc->vxlan_vni = 0;
1081 }
1082
1083 if (mask->svlan_tag || mask->cvlan_tag) {
1084 MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1);
1085 mask->cvlan_tag = 0;
1086 mask->svlan_tag = 0;
1087 }
1088 }
1089
1090 static int
dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1091 dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value,
1092 struct mlx5dr_ste_build *sb,
1093 u8 *tag)
1094 {
1095 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1096 struct mlx5dr_match_misc *misc = &value->misc;
1097
1098 DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16);
1099 DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0);
1100 DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid);
1101 DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi);
1102 DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag);
1103 DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio);
1104 DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype);
1105
1106 if (misc->vxlan_vni) {
1107 MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id,
1108 (misc->vxlan_vni << 8));
1109 misc->vxlan_vni = 0;
1110 }
1111
1112 if (spec->cvlan_tag) {
1113 MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN);
1114 spec->cvlan_tag = 0;
1115 } else if (spec->svlan_tag) {
1116 MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN);
1117 spec->svlan_tag = 0;
1118 }
1119
1120 if (spec->ip_version) {
1121 if (spec->ip_version == IP_VERSION_IPV4) {
1122 MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4);
1123 spec->ip_version = 0;
1124 } else if (spec->ip_version == IP_VERSION_IPV6) {
1125 MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6);
1126 spec->ip_version = 0;
1127 } else {
1128 return -EINVAL;
1129 }
1130 }
1131
1132 return 0;
1133 }
1134
1135 static void
dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1136 dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb,
1137 struct mlx5dr_match_param *mask)
1138 {
1139 dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask);
1140
1141 sb->lu_type = DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I;
1142 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1143 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag;
1144 }
1145
1146 static int
dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1147 dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value,
1148 struct mlx5dr_ste_build *sb,
1149 u8 *tag)
1150 {
1151 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1152
1153 DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit);
1154
1155 return 0;
1156 }
1157
1158 static void
dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1159 dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb,
1160 struct mlx5dr_match_param *mask)
1161 {
1162 dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask);
1163
1164 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner);
1165 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1166 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag;
1167 }
1168
1169 static int
dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1170 dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value,
1171 struct mlx5dr_ste_build *sb,
1172 u8 *tag)
1173 {
1174 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1175 struct mlx5dr_match_misc *misc = &value->misc;
1176
1177 DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport);
1178 DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport);
1179 DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport);
1180 DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport);
1181 DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol);
1182 DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag);
1183 DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp);
1184 DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn);
1185 DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit);
1186
1187 if (sb->inner)
1188 DR_STE_SET_TAG(eth_l4, tag, flow_label, misc, inner_ipv6_flow_label);
1189 else
1190 DR_STE_SET_TAG(eth_l4, tag, flow_label, misc, outer_ipv6_flow_label);
1191
1192 if (spec->tcp_flags) {
1193 DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec);
1194 spec->tcp_flags = 0;
1195 }
1196
1197 return 0;
1198 }
1199
1200 static void
dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1201 dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb,
1202 struct mlx5dr_match_param *mask)
1203 {
1204 dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask);
1205
1206 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner);
1207 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1208 sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag;
1209 }
1210
1211 static int
dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1212 dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value,
1213 struct mlx5dr_ste_build *sb,
1214 u8 *tag)
1215 {
1216 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1217
1218 if (sb->inner)
1219 DR_STE_SET_MPLS(mpls, misc2, inner, tag);
1220 else
1221 DR_STE_SET_MPLS(mpls, misc2, outer, tag);
1222
1223 return 0;
1224 }
1225
1226 static void
dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1227 dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb,
1228 struct mlx5dr_match_param *mask)
1229 {
1230 dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask);
1231
1232 sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner);
1233 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1234 sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag;
1235 }
1236
1237 static int
dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1238 dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value,
1239 struct mlx5dr_ste_build *sb,
1240 u8 *tag)
1241 {
1242 struct mlx5dr_match_misc *misc = &value->misc;
1243
1244 DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol);
1245
1246 DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present);
1247 DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h);
1248 DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l);
1249
1250 DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present);
1251
1252 DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present);
1253
1254 return 0;
1255 }
1256
1257 static void
dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1258 dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb,
1259 struct mlx5dr_match_param *mask)
1260 {
1261 dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask);
1262
1263 sb->lu_type = DR_STE_V0_LU_TYPE_GRE;
1264 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1265 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag;
1266 }
1267
1268 static int
dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1269 dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value,
1270 struct mlx5dr_ste_build *sb,
1271 u8 *tag)
1272 {
1273 struct mlx5dr_match_misc2 *misc_2 = &value->misc2;
1274 u32 mpls_hdr;
1275
1276 if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) {
1277 mpls_hdr = misc_2->outer_first_mpls_over_gre_label << HDR_MPLS_OFFSET_LABEL;
1278 misc_2->outer_first_mpls_over_gre_label = 0;
1279 mpls_hdr |= misc_2->outer_first_mpls_over_gre_exp << HDR_MPLS_OFFSET_EXP;
1280 misc_2->outer_first_mpls_over_gre_exp = 0;
1281 mpls_hdr |= misc_2->outer_first_mpls_over_gre_s_bos << HDR_MPLS_OFFSET_S_BOS;
1282 misc_2->outer_first_mpls_over_gre_s_bos = 0;
1283 mpls_hdr |= misc_2->outer_first_mpls_over_gre_ttl << HDR_MPLS_OFFSET_TTL;
1284 misc_2->outer_first_mpls_over_gre_ttl = 0;
1285 } else {
1286 mpls_hdr = misc_2->outer_first_mpls_over_udp_label << HDR_MPLS_OFFSET_LABEL;
1287 misc_2->outer_first_mpls_over_udp_label = 0;
1288 mpls_hdr |= misc_2->outer_first_mpls_over_udp_exp << HDR_MPLS_OFFSET_EXP;
1289 misc_2->outer_first_mpls_over_udp_exp = 0;
1290 mpls_hdr |= misc_2->outer_first_mpls_over_udp_s_bos << HDR_MPLS_OFFSET_S_BOS;
1291 misc_2->outer_first_mpls_over_udp_s_bos = 0;
1292 mpls_hdr |= misc_2->outer_first_mpls_over_udp_ttl << HDR_MPLS_OFFSET_TTL;
1293 misc_2->outer_first_mpls_over_udp_ttl = 0;
1294 }
1295
1296 MLX5_SET(ste_flex_parser_0, tag, flex_parser_3, mpls_hdr);
1297 return 0;
1298 }
1299
1300 static void
dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1301 dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb,
1302 struct mlx5dr_match_param *mask)
1303 {
1304 dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask);
1305
1306 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1307 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1308 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag;
1309 }
1310
1311 static int
dr_ste_v0_build_tnl_mpls_over_udp_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1312 dr_ste_v0_build_tnl_mpls_over_udp_tag(struct mlx5dr_match_param *value,
1313 struct mlx5dr_ste_build *sb,
1314 u8 *tag)
1315 {
1316 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1317 u8 *parser_ptr;
1318 u8 parser_id;
1319 u32 mpls_hdr;
1320
1321 mpls_hdr = misc2->outer_first_mpls_over_udp_label << HDR_MPLS_OFFSET_LABEL;
1322 misc2->outer_first_mpls_over_udp_label = 0;
1323 mpls_hdr |= misc2->outer_first_mpls_over_udp_exp << HDR_MPLS_OFFSET_EXP;
1324 misc2->outer_first_mpls_over_udp_exp = 0;
1325 mpls_hdr |= misc2->outer_first_mpls_over_udp_s_bos << HDR_MPLS_OFFSET_S_BOS;
1326 misc2->outer_first_mpls_over_udp_s_bos = 0;
1327 mpls_hdr |= misc2->outer_first_mpls_over_udp_ttl << HDR_MPLS_OFFSET_TTL;
1328 misc2->outer_first_mpls_over_udp_ttl = 0;
1329
1330 parser_id = sb->caps->flex_parser_id_mpls_over_udp;
1331 parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id);
1332 *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr);
1333
1334 return 0;
1335 }
1336
1337 static void
dr_ste_v0_build_tnl_mpls_over_udp_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1338 dr_ste_v0_build_tnl_mpls_over_udp_init(struct mlx5dr_ste_build *sb,
1339 struct mlx5dr_match_param *mask)
1340 {
1341 dr_ste_v0_build_tnl_mpls_over_udp_tag(mask, sb, sb->bit_mask);
1342 /* STEs with lookup type FLEX_PARSER_{0/1} includes
1343 * flex parsers_{0-3}/{4-7} respectively.
1344 */
1345 sb->lu_type = sb->caps->flex_parser_id_mpls_over_udp > DR_STE_MAX_FLEX_0_ID ?
1346 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 :
1347 DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1348
1349 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1350 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_over_udp_tag;
1351 }
1352
1353 static int
dr_ste_v0_build_tnl_mpls_over_gre_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1354 dr_ste_v0_build_tnl_mpls_over_gre_tag(struct mlx5dr_match_param *value,
1355 struct mlx5dr_ste_build *sb,
1356 u8 *tag)
1357 {
1358 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1359 u8 *parser_ptr;
1360 u8 parser_id;
1361 u32 mpls_hdr;
1362
1363 mpls_hdr = misc2->outer_first_mpls_over_gre_label << HDR_MPLS_OFFSET_LABEL;
1364 misc2->outer_first_mpls_over_gre_label = 0;
1365 mpls_hdr |= misc2->outer_first_mpls_over_gre_exp << HDR_MPLS_OFFSET_EXP;
1366 misc2->outer_first_mpls_over_gre_exp = 0;
1367 mpls_hdr |= misc2->outer_first_mpls_over_gre_s_bos << HDR_MPLS_OFFSET_S_BOS;
1368 misc2->outer_first_mpls_over_gre_s_bos = 0;
1369 mpls_hdr |= misc2->outer_first_mpls_over_gre_ttl << HDR_MPLS_OFFSET_TTL;
1370 misc2->outer_first_mpls_over_gre_ttl = 0;
1371
1372 parser_id = sb->caps->flex_parser_id_mpls_over_gre;
1373 parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id);
1374 *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr);
1375
1376 return 0;
1377 }
1378
1379 static void
dr_ste_v0_build_tnl_mpls_over_gre_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1380 dr_ste_v0_build_tnl_mpls_over_gre_init(struct mlx5dr_ste_build *sb,
1381 struct mlx5dr_match_param *mask)
1382 {
1383 dr_ste_v0_build_tnl_mpls_over_gre_tag(mask, sb, sb->bit_mask);
1384
1385 /* STEs with lookup type FLEX_PARSER_{0/1} includes
1386 * flex parsers_{0-3}/{4-7} respectively.
1387 */
1388 sb->lu_type = sb->caps->flex_parser_id_mpls_over_gre > DR_STE_MAX_FLEX_0_ID ?
1389 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 :
1390 DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1391
1392 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1393 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_over_gre_tag;
1394 }
1395
1396 #define ICMP_TYPE_OFFSET_FIRST_DW 24
1397 #define ICMP_CODE_OFFSET_FIRST_DW 16
1398
1399 static int
dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1400 dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value,
1401 struct mlx5dr_ste_build *sb,
1402 u8 *tag)
1403 {
1404 struct mlx5dr_match_misc3 *misc_3 = &value->misc3;
1405 u32 *icmp_header_data;
1406 int dw0_location;
1407 int dw1_location;
1408 u8 *parser_ptr;
1409 u8 *icmp_type;
1410 u8 *icmp_code;
1411 bool is_ipv4;
1412 u32 icmp_hdr;
1413
1414 is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3);
1415 if (is_ipv4) {
1416 icmp_header_data = &misc_3->icmpv4_header_data;
1417 icmp_type = &misc_3->icmpv4_type;
1418 icmp_code = &misc_3->icmpv4_code;
1419 dw0_location = sb->caps->flex_parser_id_icmp_dw0;
1420 dw1_location = sb->caps->flex_parser_id_icmp_dw1;
1421 } else {
1422 icmp_header_data = &misc_3->icmpv6_header_data;
1423 icmp_type = &misc_3->icmpv6_type;
1424 icmp_code = &misc_3->icmpv6_code;
1425 dw0_location = sb->caps->flex_parser_id_icmpv6_dw0;
1426 dw1_location = sb->caps->flex_parser_id_icmpv6_dw1;
1427 }
1428
1429 parser_ptr = dr_ste_calc_flex_parser_offset(tag, dw0_location);
1430 icmp_hdr = (*icmp_type << ICMP_TYPE_OFFSET_FIRST_DW) |
1431 (*icmp_code << ICMP_CODE_OFFSET_FIRST_DW);
1432 *(__be32 *)parser_ptr = cpu_to_be32(icmp_hdr);
1433 *icmp_code = 0;
1434 *icmp_type = 0;
1435
1436 parser_ptr = dr_ste_calc_flex_parser_offset(tag, dw1_location);
1437 *(__be32 *)parser_ptr = cpu_to_be32(*icmp_header_data);
1438 *icmp_header_data = 0;
1439
1440 return 0;
1441 }
1442
1443 static void
dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1444 dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb,
1445 struct mlx5dr_match_param *mask)
1446 {
1447 u8 parser_id;
1448 bool is_ipv4;
1449
1450 dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask);
1451
1452 /* STEs with lookup type FLEX_PARSER_{0/1} includes
1453 * flex parsers_{0-3}/{4-7} respectively.
1454 */
1455 is_ipv4 = DR_MASK_IS_ICMPV4_SET(&mask->misc3);
1456 parser_id = is_ipv4 ? sb->caps->flex_parser_id_icmp_dw0 :
1457 sb->caps->flex_parser_id_icmpv6_dw0;
1458 sb->lu_type = parser_id > DR_STE_MAX_FLEX_0_ID ?
1459 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 :
1460 DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1461 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1462 sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag;
1463 }
1464
1465 static int
dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1466 dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value,
1467 struct mlx5dr_ste_build *sb,
1468 u8 *tag)
1469 {
1470 struct mlx5dr_match_misc2 *misc_2 = &value->misc2;
1471
1472 DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field,
1473 misc_2, metadata_reg_a);
1474
1475 return 0;
1476 }
1477
1478 static void
dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1479 dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb,
1480 struct mlx5dr_match_param *mask)
1481 {
1482 dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask);
1483
1484 sb->lu_type = DR_STE_V0_LU_TYPE_GENERAL_PURPOSE;
1485 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1486 sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag;
1487 }
1488
1489 static int
dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1490 dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value,
1491 struct mlx5dr_ste_build *sb,
1492 u8 *tag)
1493 {
1494 struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1495
1496 if (sb->inner) {
1497 DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num);
1498 DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num);
1499 } else {
1500 DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num);
1501 DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num);
1502 }
1503
1504 return 0;
1505 }
1506
1507 static void
dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1508 dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb,
1509 struct mlx5dr_match_param *mask)
1510 {
1511 dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask);
1512
1513 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner);
1514 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1515 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag;
1516 }
1517
1518 static int
dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1519 dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value,
1520 struct mlx5dr_ste_build *sb,
1521 u8 *tag)
1522 {
1523 struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1524
1525 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
1526 outer_vxlan_gpe_flags, misc3,
1527 outer_vxlan_gpe_flags);
1528 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
1529 outer_vxlan_gpe_next_protocol, misc3,
1530 outer_vxlan_gpe_next_protocol);
1531 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
1532 outer_vxlan_gpe_vni, misc3,
1533 outer_vxlan_gpe_vni);
1534
1535 return 0;
1536 }
1537
1538 static void
dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1539 dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb,
1540 struct mlx5dr_match_param *mask)
1541 {
1542 dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask);
1543 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER;
1544 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1545 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag;
1546 }
1547
1548 static int
dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1549 dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value,
1550 struct mlx5dr_ste_build *sb,
1551 u8 *tag)
1552 {
1553 struct mlx5dr_match_misc *misc = &value->misc;
1554
1555 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1556 geneve_protocol_type, misc, geneve_protocol_type);
1557 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1558 geneve_oam, misc, geneve_oam);
1559 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1560 geneve_opt_len, misc, geneve_opt_len);
1561 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1562 geneve_vni, misc, geneve_vni);
1563
1564 return 0;
1565 }
1566
1567 static void
dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1568 dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb,
1569 struct mlx5dr_match_param *mask)
1570 {
1571 dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask);
1572 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER;
1573 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1574 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag;
1575 }
1576
1577 static int
dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1578 dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value,
1579 struct mlx5dr_ste_build *sb,
1580 u8 *tag)
1581 {
1582 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1583
1584 DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0);
1585 DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1);
1586 DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2);
1587 DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3);
1588
1589 return 0;
1590 }
1591
1592 static void
dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1593 dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb,
1594 struct mlx5dr_match_param *mask)
1595 {
1596 dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask);
1597
1598 sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0;
1599 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1600 sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag;
1601 }
1602
1603 static int
dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1604 dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value,
1605 struct mlx5dr_ste_build *sb,
1606 u8 *tag)
1607 {
1608 struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1609
1610 DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4);
1611 DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5);
1612 DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6);
1613 DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7);
1614
1615 return 0;
1616 }
1617
1618 static void
dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1619 dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb,
1620 struct mlx5dr_match_param *mask)
1621 {
1622 dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask);
1623
1624 sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1;
1625 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1626 sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag;
1627 }
1628
1629 static void
dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param * value,u8 * bit_mask)1630 dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value,
1631 u8 *bit_mask)
1632 {
1633 struct mlx5dr_match_misc *misc_mask = &value->misc;
1634
1635 DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port);
1636 DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn);
1637 misc_mask->source_eswitch_owner_vhca_id = 0;
1638 }
1639
1640 static int
dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1641 dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
1642 struct mlx5dr_ste_build *sb,
1643 u8 *tag)
1644 {
1645 struct mlx5dr_match_misc *misc = &value->misc;
1646 struct mlx5dr_cmd_vport_cap *vport_cap;
1647 struct mlx5dr_domain *dmn = sb->dmn;
1648 struct mlx5dr_cmd_caps *caps;
1649 u8 *bit_mask = sb->bit_mask;
1650 bool source_gvmi_set;
1651
1652 DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn);
1653
1654 if (sb->vhca_id_valid) {
1655 /* Find port GVMI based on the eswitch_owner_vhca_id */
1656 if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
1657 caps = &dmn->info.caps;
1658 else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
1659 dmn->peer_dmn->info.caps.gvmi))
1660 caps = &dmn->peer_dmn->info.caps;
1661 else
1662 return -EINVAL;
1663
1664 misc->source_eswitch_owner_vhca_id = 0;
1665 } else {
1666 caps = &dmn->info.caps;
1667 }
1668
1669 source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi);
1670 if (source_gvmi_set) {
1671 vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port);
1672 if (!vport_cap) {
1673 mlx5dr_err(dmn, "Vport 0x%x is invalid\n",
1674 misc->source_port);
1675 return -EINVAL;
1676 }
1677
1678 if (vport_cap->vport_gvmi)
1679 MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi);
1680
1681 misc->source_port = 0;
1682 }
1683
1684 return 0;
1685 }
1686
1687 static void
dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1688 dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb,
1689 struct mlx5dr_match_param *mask)
1690 {
1691 dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask);
1692
1693 sb->lu_type = DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP;
1694 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1695 sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag;
1696 }
1697
dr_ste_v0_set_flex_parser(u32 * misc4_field_id,u32 * misc4_field_value,bool * parser_is_used,u8 * tag)1698 static void dr_ste_v0_set_flex_parser(u32 *misc4_field_id,
1699 u32 *misc4_field_value,
1700 bool *parser_is_used,
1701 u8 *tag)
1702 {
1703 u32 id = *misc4_field_id;
1704 u8 *parser_ptr;
1705
1706 if (parser_is_used[id])
1707 return;
1708
1709 parser_is_used[id] = true;
1710 parser_ptr = dr_ste_calc_flex_parser_offset(tag, id);
1711
1712 *(__be32 *)parser_ptr = cpu_to_be32(*misc4_field_value);
1713 *misc4_field_id = 0;
1714 *misc4_field_value = 0;
1715 }
1716
dr_ste_v0_build_flex_parser_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1717 static int dr_ste_v0_build_flex_parser_tag(struct mlx5dr_match_param *value,
1718 struct mlx5dr_ste_build *sb,
1719 u8 *tag)
1720 {
1721 struct mlx5dr_match_misc4 *misc_4_mask = &value->misc4;
1722 bool parser_is_used[DR_NUM_OF_FLEX_PARSERS] = {};
1723
1724 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_0,
1725 &misc_4_mask->prog_sample_field_value_0,
1726 parser_is_used, tag);
1727
1728 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_1,
1729 &misc_4_mask->prog_sample_field_value_1,
1730 parser_is_used, tag);
1731
1732 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_2,
1733 &misc_4_mask->prog_sample_field_value_2,
1734 parser_is_used, tag);
1735
1736 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_3,
1737 &misc_4_mask->prog_sample_field_value_3,
1738 parser_is_used, tag);
1739
1740 return 0;
1741 }
1742
dr_ste_v0_build_flex_parser_0_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1743 static void dr_ste_v0_build_flex_parser_0_init(struct mlx5dr_ste_build *sb,
1744 struct mlx5dr_match_param *mask)
1745 {
1746 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1747 dr_ste_v0_build_flex_parser_tag(mask, sb, sb->bit_mask);
1748 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1749 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tag;
1750 }
1751
dr_ste_v0_build_flex_parser_1_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1752 static void dr_ste_v0_build_flex_parser_1_init(struct mlx5dr_ste_build *sb,
1753 struct mlx5dr_match_param *mask)
1754 {
1755 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1;
1756 dr_ste_v0_build_flex_parser_tag(mask, sb, sb->bit_mask);
1757 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1758 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tag;
1759 }
1760
1761 static int
dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1762 dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag(struct mlx5dr_match_param *value,
1763 struct mlx5dr_ste_build *sb,
1764 u8 *tag)
1765 {
1766 struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1767 u8 parser_id = sb->caps->flex_parser_id_geneve_tlv_option_0;
1768 u8 *parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id);
1769
1770 MLX5_SET(ste_flex_parser_0, parser_ptr, flex_parser_3,
1771 misc3->geneve_tlv_option_0_data);
1772 misc3->geneve_tlv_option_0_data = 0;
1773
1774 return 0;
1775 }
1776
1777 static void
dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1778 dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_init(struct mlx5dr_ste_build *sb,
1779 struct mlx5dr_match_param *mask)
1780 {
1781 dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag(mask, sb, sb->bit_mask);
1782
1783 /* STEs with lookup type FLEX_PARSER_{0/1} includes
1784 * flex parsers_{0-3}/{4-7} respectively.
1785 */
1786 sb->lu_type = sb->caps->flex_parser_id_geneve_tlv_option_0 > 3 ?
1787 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 :
1788 DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1789
1790 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1791 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag;
1792 }
1793
dr_ste_v0_build_flex_parser_tnl_gtpu_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1794 static int dr_ste_v0_build_flex_parser_tnl_gtpu_tag(struct mlx5dr_match_param *value,
1795 struct mlx5dr_ste_build *sb,
1796 u8 *tag)
1797 {
1798 struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1799
1800 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag,
1801 gtpu_msg_flags, misc3,
1802 gtpu_msg_flags);
1803 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag,
1804 gtpu_msg_type, misc3,
1805 gtpu_msg_type);
1806 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag,
1807 gtpu_teid, misc3,
1808 gtpu_teid);
1809
1810 return 0;
1811 }
1812
dr_ste_v0_build_flex_parser_tnl_gtpu_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1813 static void dr_ste_v0_build_flex_parser_tnl_gtpu_init(struct mlx5dr_ste_build *sb,
1814 struct mlx5dr_match_param *mask)
1815 {
1816 dr_ste_v0_build_flex_parser_tnl_gtpu_tag(mask, sb, sb->bit_mask);
1817
1818 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER;
1819 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1820 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_gtpu_tag;
1821 }
1822
1823 static int
dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1824 dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag(struct mlx5dr_match_param *value,
1825 struct mlx5dr_ste_build *sb,
1826 u8 *tag)
1827 {
1828 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_0))
1829 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3);
1830 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_teid))
1831 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3);
1832 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_2))
1833 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3);
1834 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0))
1835 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3);
1836 return 0;
1837 }
1838
1839 static void
dr_ste_v0_build_tnl_gtpu_flex_parser_0_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1840 dr_ste_v0_build_tnl_gtpu_flex_parser_0_init(struct mlx5dr_ste_build *sb,
1841 struct mlx5dr_match_param *mask)
1842 {
1843 dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag(mask, sb, sb->bit_mask);
1844
1845 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
1846 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1847 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag;
1848 }
1849
1850 static int
dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag(struct mlx5dr_match_param * value,struct mlx5dr_ste_build * sb,u8 * tag)1851 dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag(struct mlx5dr_match_param *value,
1852 struct mlx5dr_ste_build *sb,
1853 u8 *tag)
1854 {
1855 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_0))
1856 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3);
1857 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_teid))
1858 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3);
1859 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_2))
1860 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3);
1861 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0))
1862 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3);
1863 return 0;
1864 }
1865
1866 static void
dr_ste_v0_build_tnl_gtpu_flex_parser_1_init(struct mlx5dr_ste_build * sb,struct mlx5dr_match_param * mask)1867 dr_ste_v0_build_tnl_gtpu_flex_parser_1_init(struct mlx5dr_ste_build *sb,
1868 struct mlx5dr_match_param *mask)
1869 {
1870 dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag(mask, sb, sb->bit_mask);
1871
1872 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1;
1873 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1874 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag;
1875 }
1876
1877 struct mlx5dr_ste_ctx ste_ctx_v0 = {
1878 /* Builders */
1879 .build_eth_l2_src_dst_init = &dr_ste_v0_build_eth_l2_src_dst_init,
1880 .build_eth_l3_ipv6_src_init = &dr_ste_v0_build_eth_l3_ipv6_src_init,
1881 .build_eth_l3_ipv6_dst_init = &dr_ste_v0_build_eth_l3_ipv6_dst_init,
1882 .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init,
1883 .build_eth_l2_src_init = &dr_ste_v0_build_eth_l2_src_init,
1884 .build_eth_l2_dst_init = &dr_ste_v0_build_eth_l2_dst_init,
1885 .build_eth_l2_tnl_init = &dr_ste_v0_build_eth_l2_tnl_init,
1886 .build_eth_l3_ipv4_misc_init = &dr_ste_v0_build_eth_l3_ipv4_misc_init,
1887 .build_eth_ipv6_l3_l4_init = &dr_ste_v0_build_eth_ipv6_l3_l4_init,
1888 .build_mpls_init = &dr_ste_v0_build_mpls_init,
1889 .build_tnl_gre_init = &dr_ste_v0_build_tnl_gre_init,
1890 .build_tnl_mpls_init = &dr_ste_v0_build_tnl_mpls_init,
1891 .build_tnl_mpls_over_udp_init = &dr_ste_v0_build_tnl_mpls_over_udp_init,
1892 .build_tnl_mpls_over_gre_init = &dr_ste_v0_build_tnl_mpls_over_gre_init,
1893 .build_icmp_init = &dr_ste_v0_build_icmp_init,
1894 .build_general_purpose_init = &dr_ste_v0_build_general_purpose_init,
1895 .build_eth_l4_misc_init = &dr_ste_v0_build_eth_l4_misc_init,
1896 .build_tnl_vxlan_gpe_init = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init,
1897 .build_tnl_geneve_init = &dr_ste_v0_build_flex_parser_tnl_geneve_init,
1898 .build_tnl_geneve_tlv_opt_init = &dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_init,
1899 .build_register_0_init = &dr_ste_v0_build_register_0_init,
1900 .build_register_1_init = &dr_ste_v0_build_register_1_init,
1901 .build_src_gvmi_qpn_init = &dr_ste_v0_build_src_gvmi_qpn_init,
1902 .build_flex_parser_0_init = &dr_ste_v0_build_flex_parser_0_init,
1903 .build_flex_parser_1_init = &dr_ste_v0_build_flex_parser_1_init,
1904 .build_tnl_gtpu_init = &dr_ste_v0_build_flex_parser_tnl_gtpu_init,
1905 .build_tnl_gtpu_flex_parser_0_init = &dr_ste_v0_build_tnl_gtpu_flex_parser_0_init,
1906 .build_tnl_gtpu_flex_parser_1_init = &dr_ste_v0_build_tnl_gtpu_flex_parser_1_init,
1907
1908 /* Getters and Setters */
1909 .ste_init = &dr_ste_v0_init,
1910 .set_next_lu_type = &dr_ste_v0_set_next_lu_type,
1911 .get_next_lu_type = &dr_ste_v0_get_next_lu_type,
1912 .set_miss_addr = &dr_ste_v0_set_miss_addr,
1913 .get_miss_addr = &dr_ste_v0_get_miss_addr,
1914 .set_hit_addr = &dr_ste_v0_set_hit_addr,
1915 .set_byte_mask = &dr_ste_v0_set_byte_mask,
1916 .get_byte_mask = &dr_ste_v0_get_byte_mask,
1917
1918 /* Actions */
1919 .actions_caps = DR_STE_CTX_ACTION_CAP_NONE,
1920 .set_actions_rx = &dr_ste_v0_set_actions_rx,
1921 .set_actions_tx = &dr_ste_v0_set_actions_tx,
1922 .modify_field_arr_sz = ARRAY_SIZE(dr_ste_v0_action_modify_field_arr),
1923 .modify_field_arr = dr_ste_v0_action_modify_field_arr,
1924 .set_action_set = &dr_ste_v0_set_action_set,
1925 .set_action_add = &dr_ste_v0_set_action_add,
1926 .set_action_copy = &dr_ste_v0_set_action_copy,
1927 .set_action_decap_l3_list = &dr_ste_v0_set_action_decap_l3_list,
1928 };
1929