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