xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_action.h (revision efb62499c623db13b7396231d0da8d1906d23d9b)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2022 NVIDIA Corporation & Affiliates
3  */
4 
5 #ifndef MLX5DR_ACTION_H_
6 #define MLX5DR_ACTION_H_
7 
8 /* Max number of STEs needed for a rule (including match) */
9 #define MLX5DR_ACTION_MAX_STE 20
10 
11 /* Max number of internal subactions of ipv6_ext */
12 #define MLX5DR_ACTION_IPV6_EXT_MAX_SA 4
13 
14 enum mlx5dr_action_stc_idx {
15 	MLX5DR_ACTION_STC_IDX_CTRL = 0,
16 	MLX5DR_ACTION_STC_IDX_HIT = 1,
17 	MLX5DR_ACTION_STC_IDX_DW5 = 2,
18 	MLX5DR_ACTION_STC_IDX_DW6 = 3,
19 	MLX5DR_ACTION_STC_IDX_DW7 = 4,
20 	MLX5DR_ACTION_STC_IDX_MAX = 5,
21 	/* STC Jumvo STE combo: CTR, Hit */
22 	MLX5DR_ACTION_STC_IDX_LAST_JUMBO_STE = 1,
23 	/* STC combo1: CTR, SINGLE, DOUBLE, Hit */
24 	MLX5DR_ACTION_STC_IDX_LAST_COMBO1 = 3,
25 	/* STC combo2: CTR, 3 x SINGLE, Hit */
26 	MLX5DR_ACTION_STC_IDX_LAST_COMBO2 = 4,
27 };
28 
29 enum mlx5dr_action_offset {
30 	MLX5DR_ACTION_OFFSET_DW0 = 0,
31 	MLX5DR_ACTION_OFFSET_DW5 = 5,
32 	MLX5DR_ACTION_OFFSET_DW6 = 6,
33 	MLX5DR_ACTION_OFFSET_DW7 = 7,
34 	MLX5DR_ACTION_OFFSET_HIT = 3,
35 	MLX5DR_ACTION_OFFSET_HIT_LSB = 4,
36 };
37 
38 enum {
39 	MLX5DR_ACTION_DOUBLE_SIZE = 8,
40 	MLX5DR_ACTION_INLINE_DATA_SIZE = 4,
41 	MLX5DR_ACTION_HDR_LEN_L2_MACS = 12,
42 	MLX5DR_ACTION_HDR_LEN_L2_VLAN = 4,
43 	MLX5DR_ACTION_HDR_LEN_L2_ETHER = 2,
44 	MLX5DR_ACTION_HDR_LEN_L2 = (MLX5DR_ACTION_HDR_LEN_L2_MACS +
45 				    MLX5DR_ACTION_HDR_LEN_L2_ETHER),
46 	MLX5DR_ACTION_HDR_LEN_L2_W_VLAN = (MLX5DR_ACTION_HDR_LEN_L2 +
47 					   MLX5DR_ACTION_HDR_LEN_L2_VLAN),
48 	MLX5DR_ACTION_REFORMAT_DATA_SIZE = 64,
49 	DECAP_L3_NUM_ACTIONS_W_NO_VLAN = 6,
50 	DECAP_L3_NUM_ACTIONS_W_VLAN = 7,
51 };
52 
53 enum mlx5dr_action_setter_flag {
54 	ASF_SINGLE1 = 1 << 0,
55 	ASF_SINGLE2 = 1 << 1,
56 	ASF_SINGLE3 = 1 << 2,
57 	ASF_DOUBLE = ASF_SINGLE2 | ASF_SINGLE3,
58 	ASF_INSERT = 1 << 3,
59 	ASF_REMOVE = 1 << 4,
60 	ASF_MODIFY = 1 << 5,
61 	ASF_CTR = 1 << 6,
62 	ASF_HIT = 1 << 7,
63 };
64 
65 enum mlx5dr_action_stc_reparse {
66 	MLX5DR_ACTION_STC_REPARSE_DEFAULT,
67 	MLX5DR_ACTION_STC_REPARSE_ON,
68 	MLX5DR_ACTION_STC_REPARSE_OFF,
69 };
70 
71  /* 2' comp to 20, to get -20 in add operation */
72 #define MLX5DR_ACTION_NAT64_DEC_20 0xffffffec
73 
74 enum {
75 	MLX5DR_ACTION_NAT64_MAX_MODIFY_ACTIONS = 20,
76 	MLX5DR_ACTION_NAT64_ADD_20 = 20,
77 	MLX5DR_ACTION_NAT64_HEADER_MINUS_ONE = 9,
78 	MLX5DR_ACTION_NAT64_IPV6_HEADER = 10,
79 	MLX5DR_ACTION_NAT64_IPV4_HEADER = 5,
80 	MLX5DR_ACTION_NAT64_IPV6_VER = 0x60000000,
81 	MLX5DR_ACTION_NAT64_IPV4_VER = 0x45000000,
82 	MLX5DR_ACTION_NAT64_TTL_DEFAULT_VAL = 64,
83 	MLX5DR_ACTION_NAT64_ECN_SIZE = 2,
84 };
85 
86 /* 3 stages for the nat64 action */
87 enum mlx5dr_action_nat64_stages {
88 	MLX5DR_ACTION_NAT64_STAGE_COPY = 0,
89 	MLX5DR_ACTION_NAT64_STAGE_REPLACE = 1,
90 	MLX5DR_ACTION_NAT64_STAGE_COPY_PROTOCOL = 2,
91 	MLX5DR_ACTION_NAT64_STAGE_COPYBACK = 3,
92 	/* Number of MH in NAT64 */
93 	MLX5DR_ACTION_NAT64_STAGES = 4,
94 };
95 
96 /* Registers for keeping data from stage to stage */
97 enum {
98 	MLX5DR_ACTION_NAT64_REG_CONTROL = 0,
99 	MLX5DR_ACTION_NAT64_REG_SRC_IP = 1,
100 	MLX5DR_ACTION_NAT64_REG_DST_IP = 2,
101 	MLX5DR_ACTION_NAT64_REG_MAX = 3,
102 };
103 
104 struct mlx5dr_action_default_stc {
105 	struct mlx5dr_pool_chunk nop_ctr;
106 	struct mlx5dr_pool_chunk nop_dw5;
107 	struct mlx5dr_pool_chunk nop_dw6;
108 	struct mlx5dr_pool_chunk nop_dw7;
109 	struct mlx5dr_pool_chunk default_hit;
110 	uint32_t refcount;
111 };
112 
113 struct mlx5dr_action_shared_stc {
114 	struct mlx5dr_pool_chunk remove_header;
115 	uint32_t refcount;
116 };
117 
118 struct mlx5dr_actions_apply_data {
119 	struct mlx5dr_send_engine *queue;
120 	struct mlx5dr_rule_action *rule_action;
121 	uint32_t *wqe_data;
122 	struct mlx5dr_wqe_gta_ctrl_seg *wqe_ctrl;
123 	uint32_t jump_to_action_stc;
124 	struct mlx5dr_context_common_res *common_res;
125 	enum mlx5dr_table_type tbl_type;
126 	uint32_t next_direct_idx;
127 	uint8_t require_dep;
128 };
129 
130 struct mlx5dr_actions_wqe_setter;
131 
132 typedef void (*mlx5dr_action_setter_fp)
133 	(struct mlx5dr_actions_apply_data *apply,
134 	 struct mlx5dr_actions_wqe_setter *setter);
135 
136 struct mlx5dr_actions_wqe_setter {
137 	mlx5dr_action_setter_fp set_single;
138 	mlx5dr_action_setter_fp set_double;
139 	mlx5dr_action_setter_fp set_hit;
140 	mlx5dr_action_setter_fp set_ctr;
141 	uint8_t idx_single;
142 	uint8_t idx_double;
143 	uint8_t idx_ctr;
144 	uint8_t idx_hit;
145 	uint8_t stage_idx;
146 	uint8_t flags;
147 	uint8_t extra_data;
148 };
149 
150 struct mlx5dr_action_template {
151 	struct mlx5dr_actions_wqe_setter setters[MLX5DR_ACTION_MAX_STE];
152 	enum mlx5dr_action_type *action_type_arr;
153 	uint8_t num_of_action_stes;
154 	uint8_t num_actions;
155 	uint8_t only_term;
156 	/* indicates rule might require dependent wqe */
157 	bool need_dep_write;
158 	uint32_t flags;
159 };
160 
161 struct mlx5dr_action {
162 	uint8_t type;
163 	uint8_t flags;
164 	struct mlx5dr_context *ctx;
165 	union {
166 		struct {
167 			struct mlx5dr_pool_chunk stc[MLX5DR_TABLE_TYPE_MAX];
168 			union {
169 				struct {
170 					struct mlx5dr_devx_obj *pat_obj;
171 					struct mlx5dr_devx_obj *arg_obj;
172 					__be64 single_action;
173 					uint8_t num_of_patterns;
174 					uint8_t single_action_type;
175 					uint8_t num_of_actions;
176 					uint8_t max_num_of_actions;
177 					uint8_t require_reparse;
178 				} modify_header;
179 				struct {
180 					struct mlx5dr_devx_obj *arg_obj;
181 					uint32_t header_size;
182 					uint16_t max_hdr_sz;
183 					uint8_t num_of_hdrs;
184 					uint8_t anchor;
185 					uint8_t offset;
186 					bool encap;
187 					uint8_t require_reparse;
188 					bool push_esp;
189 				} reformat;
190 				struct {
191 					struct mlx5dr_action
192 						*action[MLX5DR_ACTION_IPV6_EXT_MAX_SA];
193 				} ipv6_route_ext;
194 				struct {
195 					struct mlx5dr_devx_obj *devx_obj;
196 					uint8_t return_reg_id;
197 				} aso;
198 				struct {
199 					uint16_t vport_num;
200 					uint16_t esw_owner_vhca_id;
201 				} vport;
202 				struct {
203 					struct mlx5dr_devx_obj *devx_obj;
204 				} alias;
205 				struct {
206 					struct mlx5dv_steering_anchor *sa;
207 				} root_tbl;
208 				struct {
209 					struct mlx5dr_devx_obj *devx_obj;
210 				} devx_dest;
211 				struct {
212 					struct mlx5dr_cmd_forward_tbl *fw_island;
213 					size_t num_dest;
214 					struct mlx5dr_cmd_set_fte_dest *dest_list;
215 				} dest_array;
216 				struct {
217 					uint8_t type;
218 					uint8_t start_anchor;
219 					uint8_t end_anchor;
220 					uint8_t num_of_words;
221 					bool decap;
222 				} remove_header;
223 				struct {
224 					struct mlx5dr_action *stages[MLX5DR_ACTION_NAT64_STAGES];
225 				} nat64;
226 				struct {
227 					struct mlx5dr_matcher *matcher;
228 				} jump_to_matcher;
229 			};
230 		};
231 
232 		struct ibv_flow_action *flow_action;
233 		struct mlx5dv_devx_obj *devx_obj;
234 		struct ibv_qp *qp;
235 	};
236 };
237 
238 int mlx5dr_action_root_build_attr(struct mlx5dr_rule_action rule_actions[],
239 				  uint32_t num_actions,
240 				  struct mlx5dv_flow_action_attr *attr);
241 
242 int mlx5dr_action_get_default_stc(struct mlx5dr_context *ctx,
243 				  uint8_t tbl_type);
244 
245 void mlx5dr_action_put_default_stc(struct mlx5dr_context *ctx,
246 				   uint8_t tbl_type);
247 
248 void mlx5dr_action_prepare_decap_l3_data(uint8_t *src, uint8_t *dst,
249 					 uint16_t num_of_actions);
250 
251 int mlx5dr_action_template_process(struct mlx5dr_action_template *at);
252 
253 bool mlx5dr_action_check_combo(enum mlx5dr_action_type *user_actions,
254 			       enum mlx5dr_table_type table_type);
255 
256 int mlx5dr_action_alloc_single_stc(struct mlx5dr_context *ctx,
257 				   struct mlx5dr_cmd_stc_modify_attr *stc_attr,
258 				   uint32_t table_type,
259 				   struct mlx5dr_pool_chunk *stc);
260 
261 void mlx5dr_action_free_single_stc(struct mlx5dr_context *ctx,
262 				   uint32_t table_type,
263 				   struct mlx5dr_pool_chunk *stc);
264 struct mlx5dr_action *
265 mlx5dr_action_create_modify_header_reparse(struct mlx5dr_context *ctx,
266 					   uint8_t num_of_patterns,
267 					   struct mlx5dr_action_mh_pattern *patterns,
268 					   uint32_t log_bulk_size,
269 					   uint32_t flags, uint32_t reparse);
270 
271 
272 static inline void
273 mlx5dr_action_setter_default_single(struct mlx5dr_actions_apply_data *apply,
274 				    __rte_unused struct mlx5dr_actions_wqe_setter *setter)
275 {
276 	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
277 	apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] =
278 		htobe32(apply->common_res->default_stc->nop_dw5.offset);
279 }
280 
281 static inline void
282 mlx5dr_action_setter_default_double(struct mlx5dr_actions_apply_data *apply,
283 				    __rte_unused struct mlx5dr_actions_wqe_setter *setter)
284 {
285 	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
286 	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;
287 	apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] =
288 		htobe32(apply->common_res->default_stc->nop_dw6.offset);
289 	apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] =
290 		htobe32(apply->common_res->default_stc->nop_dw7.offset);
291 }
292 
293 static inline void
294 mlx5dr_action_setter_default_ctr(struct mlx5dr_actions_apply_data *apply,
295 				 __rte_unused struct mlx5dr_actions_wqe_setter *setter)
296 {
297 	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW0] = 0;
298 	apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_CTRL] =
299 		htobe32(apply->common_res->default_stc->nop_ctr.offset);
300 }
301 
302 static inline void
303 mlx5dr_action_apply_setter(struct mlx5dr_actions_apply_data *apply,
304 			   struct mlx5dr_actions_wqe_setter *setter,
305 			   bool is_jumbo)
306 {
307 	uint8_t num_of_actions;
308 
309 	/* Set control counter */
310 	if (setter->flags & ASF_CTR)
311 		setter->set_ctr(apply, setter);
312 	else
313 		mlx5dr_action_setter_default_ctr(apply, setter);
314 
315 	/* Set single and double on match */
316 	if (!is_jumbo) {
317 		if (setter->flags & ASF_SINGLE1)
318 			setter->set_single(apply, setter);
319 		else
320 			mlx5dr_action_setter_default_single(apply, setter);
321 
322 		if (setter->flags & ASF_DOUBLE)
323 			setter->set_double(apply, setter);
324 		else
325 			mlx5dr_action_setter_default_double(apply, setter);
326 
327 		num_of_actions = setter->flags & ASF_DOUBLE ?
328 			MLX5DR_ACTION_STC_IDX_LAST_COMBO1 :
329 			MLX5DR_ACTION_STC_IDX_LAST_COMBO2;
330 	} else {
331 		apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
332 		apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
333 		apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;
334 		apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] = 0;
335 		apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = 0;
336 		apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0;
337 		num_of_actions = MLX5DR_ACTION_STC_IDX_LAST_JUMBO_STE;
338 	}
339 
340 	/* Set next/final hit action */
341 	setter->set_hit(apply, setter);
342 
343 	/* Set number of actions */
344 	apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_CTRL] |=
345 		htobe32(num_of_actions << 29);
346 }
347 
348 #endif /* MLX5DR_ACTION_H_ */
349