Branch data Line data Source code
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 : : uint16_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 : : struct {
230 : : struct mlx5dr_devx_obj *devx_obj;
231 : : enum mlx5dr_table_type type;
232 : : } dest_tbl;
233 : : };
234 : : };
235 : :
236 : : struct ibv_flow_action *flow_action;
237 : : struct mlx5dv_devx_obj *devx_obj;
238 : : struct ibv_qp *qp;
239 : : };
240 : : };
241 : :
242 : : int mlx5dr_action_root_build_attr(struct mlx5dr_rule_action rule_actions[],
243 : : uint32_t num_actions,
244 : : struct mlx5dv_flow_action_attr *attr);
245 : :
246 : : int mlx5dr_action_get_default_stc(struct mlx5dr_context *ctx,
247 : : uint8_t tbl_type);
248 : :
249 : : void mlx5dr_action_put_default_stc(struct mlx5dr_context *ctx,
250 : : uint8_t tbl_type);
251 : :
252 : : void mlx5dr_action_prepare_decap_l3_data(uint8_t *src, uint8_t *dst,
253 : : uint16_t num_of_actions);
254 : :
255 : : int mlx5dr_action_template_process(struct mlx5dr_action_template *at);
256 : :
257 : : bool mlx5dr_action_check_combo(enum mlx5dr_action_type *user_actions,
258 : : enum mlx5dr_table_type table_type);
259 : :
260 : : int mlx5dr_action_alloc_single_stc(struct mlx5dr_context *ctx,
261 : : struct mlx5dr_cmd_stc_modify_attr *stc_attr,
262 : : uint32_t table_type,
263 : : struct mlx5dr_pool_chunk *stc);
264 : :
265 : : void mlx5dr_action_free_single_stc(struct mlx5dr_context *ctx,
266 : : uint32_t table_type,
267 : : struct mlx5dr_pool_chunk *stc);
268 : : struct mlx5dr_action *
269 : : mlx5dr_action_create_modify_header_reparse(struct mlx5dr_context *ctx,
270 : : uint8_t num_of_patterns,
271 : : struct mlx5dr_action_mh_pattern *patterns,
272 : : uint32_t log_bulk_size,
273 : : uint32_t flags, uint32_t reparse);
274 : :
275 : :
276 : : static inline void
277 : : mlx5dr_action_setter_default_single(struct mlx5dr_actions_apply_data *apply,
278 : : __rte_unused struct mlx5dr_actions_wqe_setter *setter)
279 : : {
280 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
281 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] =
282 : 0 : htobe32(apply->common_res->default_stc->nop_dw5.offset);
283 : 0 : }
284 : :
285 : : static inline void
286 : : mlx5dr_action_setter_default_double(struct mlx5dr_actions_apply_data *apply,
287 : : __rte_unused struct mlx5dr_actions_wqe_setter *setter)
288 : : {
289 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
290 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;
291 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] =
292 : 0 : htobe32(apply->common_res->default_stc->nop_dw6.offset);
293 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] =
294 : 0 : htobe32(apply->common_res->default_stc->nop_dw7.offset);
295 : 0 : }
296 : :
297 : : static inline void
298 : : mlx5dr_action_setter_default_ctr(struct mlx5dr_actions_apply_data *apply,
299 : : __rte_unused struct mlx5dr_actions_wqe_setter *setter)
300 : : {
301 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW0] = 0;
302 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_CTRL] =
303 : 0 : htobe32(apply->common_res->default_stc->nop_ctr.offset);
304 : 0 : }
305 : :
306 : : static inline void
307 : 0 : mlx5dr_action_apply_setter(struct mlx5dr_actions_apply_data *apply,
308 : : struct mlx5dr_actions_wqe_setter *setter,
309 : : bool is_jumbo)
310 : : {
311 : : uint8_t num_of_actions;
312 : :
313 : : /* Set control counter */
314 [ # # ]: 0 : if (setter->flags & ASF_CTR)
315 : 0 : setter->set_ctr(apply, setter);
316 : : else
317 : : mlx5dr_action_setter_default_ctr(apply, setter);
318 : :
319 : : /* Set single and double on match */
320 [ # # ]: 0 : if (!is_jumbo) {
321 [ # # ]: 0 : if (setter->flags & ASF_SINGLE1)
322 : 0 : setter->set_single(apply, setter);
323 : : else
324 : : mlx5dr_action_setter_default_single(apply, setter);
325 : :
326 [ # # ]: 0 : if (setter->flags & ASF_DOUBLE)
327 : 0 : setter->set_double(apply, setter);
328 : : else
329 : : mlx5dr_action_setter_default_double(apply, setter);
330 : :
331 [ # # ]: 0 : num_of_actions = setter->flags & ASF_DOUBLE ?
332 : : MLX5DR_ACTION_STC_IDX_LAST_COMBO1 :
333 : : MLX5DR_ACTION_STC_IDX_LAST_COMBO2;
334 : : } else {
335 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
336 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;
337 : 0 : apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;
338 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] = 0;
339 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = 0;
340 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0;
341 : : num_of_actions = MLX5DR_ACTION_STC_IDX_LAST_JUMBO_STE;
342 : : }
343 : :
344 : : /* Set next/final hit action */
345 : 0 : setter->set_hit(apply, setter);
346 : :
347 : : /* Set number of actions */
348 : 0 : apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_CTRL] |=
349 : 0 : htobe32(num_of_actions << 29);
350 : 0 : }
351 : :
352 : : #endif /* MLX5DR_ACTION_H_ */
|