1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020 Mellanox Technologies, Ltd
3 */
4
5 #ifndef RTE_PMD_MLX5_FLOW_OS_H_
6 #define RTE_PMD_MLX5_FLOW_OS_H_
7
8 #include "mlx5_flow.h"
9
10 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
11 extern const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops;
12 extern const struct mlx5_flow_driver_ops mlx5_flow_hw_drv_ops;
13 #endif
14
15 /**
16 * Get OS enforced flow type. MLX5_FLOW_TYPE_MAX means "non enforced type".
17 *
18 * @return
19 * Flow type (MLX5_FLOW_TYPE_MAX)
20 */
21 static inline enum mlx5_flow_drv_type
mlx5_flow_os_get_type(void)22 mlx5_flow_os_get_type(void)
23 {
24 return MLX5_FLOW_TYPE_MAX;
25 }
26
27 /**
28 * Check if item type is supported.
29 *
30 * @param item
31 * Item type to check.
32 *
33 * @return
34 * True is this item type is supported, false if not supported.
35 */
36 static inline bool
mlx5_flow_os_item_supported(int item __rte_unused)37 mlx5_flow_os_item_supported(int item __rte_unused)
38 {
39 return true;
40 }
41
42 /**
43 * Check if action type is supported.
44 *
45 * @param action
46 * Action type to check.
47 *
48 * @return
49 * True is this action type is supported, false if not supported.
50 */
51 static inline bool
mlx5_flow_os_action_supported(int action __rte_unused)52 mlx5_flow_os_action_supported(int action __rte_unused)
53 {
54 return true;
55 }
56
57 /**
58 * Create flow rule.
59 *
60 * @param[in] matcher
61 * Pointer to match mask structure.
62 * @param[in] match_value
63 * Pointer to match value structure.
64 * @param[in] num_actions
65 * Number of actions in flow rule.
66 * @param[in] actions
67 * Pointer to array of flow rule actions.
68 * @param[out] flow
69 * Pointer to a valid flow rule object on success, NULL otherwise.
70 *
71 * @return
72 * 0 on success, or -1 on failure and errno is set.
73 */
74 static inline int
mlx5_flow_os_create_flow(void * matcher,void * match_value,size_t num_actions,void * actions[],void ** flow)75 mlx5_flow_os_create_flow(void *matcher, void *match_value,
76 size_t num_actions, void *actions[], void **flow)
77 {
78 *flow = mlx5_glue->dv_create_flow(matcher, match_value,
79 num_actions, actions);
80 return (*flow) ? 0 : -1;
81 }
82
83 /**
84 * Destroy flow rule.
85 *
86 * @param[in] drv_flow_ptr
87 * Pointer to flow rule object.
88 *
89 * @return
90 * 0 on success, or the value of errno on failure.
91 */
92 static inline int
mlx5_flow_os_destroy_flow(void * drv_flow_ptr)93 mlx5_flow_os_destroy_flow(void *drv_flow_ptr)
94 {
95 return mlx5_glue->dv_destroy_flow(drv_flow_ptr);
96 }
97
98 /**
99 * Create flow table.
100 *
101 * @param[in] domain
102 * Pointer to relevant domain.
103 * @param[in] table_id
104 * Table ID.
105 * @param[out] table
106 * Pointer to a valid flow table object on success, NULL otherwise.
107 *
108 * @return
109 * 0 on success, or -1 on failure and errno is set.
110 */
111 static inline int
mlx5_flow_os_create_flow_tbl(void * domain,uint32_t table_id,void ** table)112 mlx5_flow_os_create_flow_tbl(void *domain, uint32_t table_id, void **table)
113 {
114 *table = mlx5_glue->dr_create_flow_tbl(domain, table_id);
115 return (*table) ? 0 : -1;
116 }
117
118 /**
119 * Destroy flow table.
120 *
121 * @param[in] table
122 * Pointer to table object to destroy.
123 *
124 * @return
125 * 0 on success, or the value of errno on failure.
126 */
127 static inline int
mlx5_flow_os_destroy_flow_tbl(void * table)128 mlx5_flow_os_destroy_flow_tbl(void *table)
129 {
130 return mlx5_glue->dr_destroy_flow_tbl(table);
131 }
132
133 /**
134 * Create flow matcher in a flow table.
135 *
136 * @param[in] ctx
137 * Pointer to relevant device context.
138 * @param[in] attr
139 * Pointer to relevant attributes.
140 * @param[in] table
141 * Pointer to table object.
142 * @param[out] matcher
143 * Pointer to a valid flow matcher object on success, NULL otherwise.
144 *
145 * @return
146 * 0 on success, or -1 on failure and errno is set.
147 */
148 static inline int
mlx5_flow_os_create_flow_matcher(void * ctx,void * attr,void * table,void ** matcher)149 mlx5_flow_os_create_flow_matcher(void *ctx, void *attr, void *table,
150 void **matcher)
151 {
152 *matcher = mlx5_glue->dv_create_flow_matcher(ctx, attr, table);
153 return (*matcher) ? 0 : -1;
154 }
155
156 /**
157 * Destroy flow matcher.
158 *
159 * @param[in] matcher
160 * Pointer to matcher object to destroy.
161 *
162 * @return
163 * 0 on success, or the value of errno on failure.
164 */
165 static inline int
mlx5_flow_os_destroy_flow_matcher(void * matcher)166 mlx5_flow_os_destroy_flow_matcher(void *matcher)
167 {
168 return mlx5_glue->dv_destroy_flow_matcher(matcher);
169 }
170
171 /**
172 * Create flow action: packet reformat.
173 *
174 * @param[in] ctx
175 * Pointer to relevant device context.
176 * @param[in] domain
177 * Pointer to domain handler.
178 * @param[in] resource
179 * Pointer to action data resource.
180 * @param[out] action
181 * Pointer to a valid action on success, NULL otherwise.
182 *
183 *
184 * @return
185 * 0 on success, or -1 on failure and errno is set.
186 */
187 static inline int
mlx5_flow_os_create_flow_action_packet_reformat(void * ctx,void * domain,void * resource,void ** action)188 mlx5_flow_os_create_flow_action_packet_reformat(void *ctx, void *domain,
189 void *resource, void **action)
190 {
191 struct mlx5_flow_dv_encap_decap_resource *res =
192 (struct mlx5_flow_dv_encap_decap_resource *)resource;
193
194 *action = mlx5_glue->dv_create_flow_action_packet_reformat
195 (ctx, res->reformat_type, res->ft_type,
196 domain, res->flags, res->size,
197 (res->size ? res->buf : NULL));
198 return (*action) ? 0 : -1;
199 }
200
201 /**
202 * Create flow action: modify header.
203 *
204 * @param[in] ctx
205 * Pointer to relevant device context.
206 * @param[in] domain
207 * Pointer to domain handler.
208 * @param[in] resource
209 * Pointer to action data resource.
210 * @param[in] actions_len
211 * Total length of actions data in resource.
212 * @param[out] action
213 * Pointer to a valid action on success, NULL otherwise.
214 *
215 *
216 * @return
217 * 0 on success, or -1 on failure and errno is set.
218 */
219 static inline int
mlx5_flow_os_create_flow_action_modify_header(void * ctx,void * domain,void * resource,uint32_t actions_len,void ** action)220 mlx5_flow_os_create_flow_action_modify_header(void *ctx, void *domain,
221 void *resource,
222 uint32_t actions_len,
223 void **action)
224 {
225 struct mlx5_flow_dv_modify_hdr_resource *res =
226 (struct mlx5_flow_dv_modify_hdr_resource *)resource;
227
228 *action = mlx5_glue->dv_create_flow_action_modify_header
229 (ctx, res->ft_type, domain, res->root ?
230 MLX5DV_DR_ACTION_FLAGS_ROOT_LEVEL : 0,
231 actions_len, (uint64_t *)res->actions);
232 return (*action) ? 0 : -1;
233 }
234
235 /**
236 * Create flow action: destination flow table.
237 *
238 * @param[in] tbl_obj
239 * Pointer to destination table object.
240 * @param[out] action
241 * Pointer to a valid action on success, NULL otherwise.
242 *
243 * @return
244 * 0 on success, or -1 on failure and errno is set.
245 */
246 static inline int
mlx5_flow_os_create_flow_action_dest_flow_tbl(void * tbl_obj,void ** action)247 mlx5_flow_os_create_flow_action_dest_flow_tbl(void *tbl_obj, void **action)
248 {
249 *action = mlx5_glue->dr_create_flow_action_dest_flow_tbl(tbl_obj);
250 return (*action) ? 0 : -1;
251 }
252
253 /**
254 * Create flow action: destination port.
255 *
256 * @param[in] domain
257 * Pointer to domain handler.
258 * @param[in] port_id
259 * Destination port ID.
260 * @param[out] action
261 * Pointer to a valid action on success, NULL otherwise.
262 *
263 * @return
264 * 0 on success, or -1 on failure and errno is set.
265 */
266 static inline int
mlx5_flow_os_create_flow_action_dest_port(void * domain,uint32_t port_id,void ** action)267 mlx5_flow_os_create_flow_action_dest_port(void *domain, uint32_t port_id,
268 void **action)
269 {
270 /*
271 * Depending on rdma_core version the glue routine calls
272 * either mlx5dv_dr_action_create_dest_ib_port(domain, dev_port)
273 * or mlx5dv_dr_action_create_dest_vport(domain, vport_id).
274 */
275 *action = mlx5_glue->dr_create_flow_action_dest_port(domain, port_id);
276 return (*action) ? 0 : -1;
277 }
278
279 /**
280 * Create flow action: push vlan.
281 *
282 * @param[in] domain
283 * Pointer to domain handler.
284 * @param[in] vlan_tag
285 * VLAN tag value.
286 * @param[out] action
287 * Pointer to a valid action on success, NULL otherwise.
288 *
289 * @return
290 * 0 on success, or -1 on failure and errno is set.
291 */
292 static inline int
mlx5_flow_os_create_flow_action_push_vlan(void * domain,rte_be32_t vlan_tag,void ** action)293 mlx5_flow_os_create_flow_action_push_vlan(void *domain, rte_be32_t vlan_tag,
294 void **action)
295 {
296 *action = mlx5_glue->dr_create_flow_action_push_vlan(domain, vlan_tag);
297 return (*action) ? 0 : -1;
298 }
299
300 /**
301 * Create flow action: count.
302 *
303 * @param[in] cnt_obj
304 * Pointer to DevX counter object.
305 * @param[in] offset
306 * Offset of counter in array.
307 * @param[out] action
308 * Pointer to a valid action on success, NULL otherwise.
309 *
310 * @return
311 * 0 on success, or -1 on failure and errno is set.
312 */
313 static inline int
mlx5_flow_os_create_flow_action_count(void * cnt_obj,uint16_t offset,void ** action)314 mlx5_flow_os_create_flow_action_count(void *cnt_obj, uint16_t offset,
315 void **action)
316 {
317 *action = mlx5_glue->dv_create_flow_action_counter(cnt_obj, offset);
318 return (*action) ? 0 : -1;
319 }
320
321 /**
322 * Create flow action: tag.
323 *
324 * @param[in] tag
325 * Tag value.
326 * @param[out] action
327 * Pointer to a valid action on success, NULL otherwise.
328 *
329 * @return
330 * 0 on success, or -1 on failure and errno is set.
331 */
332 static inline int
mlx5_flow_os_create_flow_action_tag(uint32_t tag,void ** action)333 mlx5_flow_os_create_flow_action_tag(uint32_t tag, void **action)
334 {
335 *action = mlx5_glue->dv_create_flow_action_tag(tag);
336 return (*action) ? 0 : -1;
337 }
338
339 /**
340 * Create flow action: drop.
341 *
342 * @param[out] action
343 * Pointer to a valid action on success, NULL otherwise.
344 *
345 * @return
346 * 0 on success, or -1 on failure and errno is set.
347 */
348 static inline int
mlx5_flow_os_create_flow_action_drop(void ** action)349 mlx5_flow_os_create_flow_action_drop(void **action)
350 {
351 *action = mlx5_glue->dr_create_flow_action_drop();
352 return (*action) ? 0 : -1;
353 }
354
355 /**
356 * Create flow action: default miss.
357 *
358 * @param[out] action
359 * Pointer to a valid action on success, NULL otherwise.
360 *
361 * @return
362 * 0 on success, or -1 on failure and errno is set.
363 */
364 static inline int
mlx5_flow_os_create_flow_action_default_miss(void ** action)365 mlx5_flow_os_create_flow_action_default_miss(void **action)
366 {
367 *action = mlx5_glue->dr_create_flow_action_default_miss();
368 return (*action) ? 0 : -1;
369 }
370
371 /**
372 * Create flow action: send_to_kernel.
373 *
374 * @param[in] tbl
375 * Pointer to destination root table.
376 * @param[in] priority
377 * Priority to which traffic will arrive.
378 * @param[out] action
379 * Pointer to a valid action on success, NULL otherwise.
380 *
381 * @return
382 * 0 on success, or -1 on failure and errno is set.
383 */
384 static inline int
mlx5_flow_os_create_flow_action_send_to_kernel(void * tbl,uint16_t priority,void ** action)385 mlx5_flow_os_create_flow_action_send_to_kernel(void *tbl, uint16_t priority,
386 void **action)
387 {
388 *action = mlx5_glue->dr_create_flow_action_send_to_kernel(tbl,
389 priority);
390 return (*action) ? 0 : -1;
391 }
392
393 /**
394 * Create flow action: dest_devx_tir
395 *
396 * @param[in] tir
397 * Pointer to DevX tir object
398 * @param[out] action
399 * Pointer to a valid action on success, NULL otherwise.
400 *
401 * @return
402 * 0 on success, or -1 on failure and errno is set.
403 */
404 static inline int
mlx5_flow_os_create_flow_action_dest_devx_tir(struct mlx5_devx_obj * tir,void ** action)405 mlx5_flow_os_create_flow_action_dest_devx_tir(struct mlx5_devx_obj *tir,
406 void **action)
407 {
408 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
409 *action = mlx5_glue->dv_create_flow_action_dest_devx_tir(tir->obj);
410 return (*action) ? 0 : -1;
411 #else
412 /* If no DV support - skip the operation and return success */
413 RTE_SET_USED(tir);
414 *action = 0;
415 return 0;
416 #endif
417 }
418
419 /**
420 * Create flow action: sampler
421 *
422 * @param[in] attr
423 * Pointer to sampler attribute
424 * @param[out] action
425 * Pointer to a valid action on success, NULL otherwise.
426 *
427 * @return
428 * 0 on success, or -1 on failure and errno is set.
429 */
430 static inline int
mlx5_os_flow_dr_create_flow_action_sampler(struct mlx5dv_dr_flow_sampler_attr * attr,void ** action)431 mlx5_os_flow_dr_create_flow_action_sampler
432 (struct mlx5dv_dr_flow_sampler_attr *attr,
433 void **action)
434 {
435 *action = mlx5_glue->dr_create_flow_action_sampler(attr);
436 return (*action) ? 0 : -1;
437 }
438
439 /**
440 * Create flow action: dest_array
441 *
442 * @param[in] domain
443 * Pointer to relevant domain.
444 * @param[in] num_dest
445 * Number of destinations array.
446 * @param[in] dests
447 * Array of destination attributes.
448 * @param[out] action
449 * Pointer to a valid action on success, NULL otherwise.
450 *
451 * @return
452 * 0 on success, or -1 on failure and errno is set.
453 */
454 static inline int
mlx5_os_flow_dr_create_flow_action_dest_array(void * domain,size_t num_dest,struct mlx5dv_dr_action_dest_attr * dests[],void ** action)455 mlx5_os_flow_dr_create_flow_action_dest_array
456 (void *domain,
457 size_t num_dest,
458 struct mlx5dv_dr_action_dest_attr *dests[],
459 void **action)
460 {
461 *action = mlx5_glue->dr_create_flow_action_dest_array(
462 domain, num_dest, dests);
463 return (*action) ? 0 : -1;
464 }
465
466 /**
467 * Destroy flow action.
468 *
469 * @param[in] action
470 * Pointer to action object to destroy.
471 *
472 * @return
473 * 0 on success, or the value of errno on failure.
474 */
475 static inline int
mlx5_flow_os_destroy_flow_action(void * action)476 mlx5_flow_os_destroy_flow_action(void *action)
477 {
478 return mlx5_glue->destroy_flow_action(action);
479 }
480
481 /**
482 * OS wrapper over Verbs API.
483 * Adjust flow priority based on the highest layer and the request priority.
484 *
485 * @param[in] dev
486 * Pointer to the Ethernet device structure.
487 * @param[in] priority
488 * The rule base priority.
489 * @param[in] subpriority
490 * The priority based on the items.
491 *
492 * @return
493 * The new priority.
494 */
495 static inline uint32_t
mlx5_os_flow_adjust_priority(struct rte_eth_dev * dev,int32_t priority,uint32_t subpriority)496 mlx5_os_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
497 uint32_t subpriority)
498 {
499 return mlx5_flow_adjust_priority(dev, priority, subpriority);
500 }
501
502 static inline int
mlx5_os_flow_dr_sync_domain(void * domain,uint32_t flags)503 mlx5_os_flow_dr_sync_domain(void *domain, uint32_t flags)
504 {
505 return mlx5_glue->dr_sync_domain(domain, flags);
506 }
507
508 /**
509 * Validate ESP item.
510 *
511 * @param[in] item
512 * Item specification.
513 * @param[in] item_flags
514 * Bit-fields that holds the items detected until now.
515 * @param[in] target_protocol
516 * The next protocol in the previous item.
517 * @param[out] error
518 * Pointer to error structure.
519 *
520 * @return
521 * 0 on success, a negative errno value otherwise and rte_errno is set.
522 */
523 int
524 mlx5_flow_os_validate_item_esp(const struct rte_eth_dev *dev,
525 const struct rte_flow_item *item,
526 uint64_t item_flags,
527 uint8_t target_protocol,
528 struct rte_flow_error *error);
529
530 /**
531 * Add per thread workspace to the global list for garbage collection.
532 *
533 * @param[in] ws
534 * Pointer to the flow workspace.
535 */
536 void mlx5_flow_os_workspace_gc_add(struct mlx5_flow_workspace *ws);
537
538 #endif /* RTE_PMD_MLX5_FLOW_OS_H_ */
539