net/mlx5: add runtime parameter to enable Direct Verbs
[dpdk.git] / drivers / net / mlx5 / mlx5_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016 6WIND S.A.
3  * Copyright 2016 Mellanox Technologies, Ltd
4  */
5
6 #include <netinet/in.h>
7 #include <sys/queue.h>
8 #include <stdalign.h>
9 #include <stdint.h>
10 #include <string.h>
11
12 /* Verbs header. */
13 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
14 #ifdef PEDANTIC
15 #pragma GCC diagnostic ignored "-Wpedantic"
16 #endif
17 #include <infiniband/verbs.h>
18 #ifdef PEDANTIC
19 #pragma GCC diagnostic error "-Wpedantic"
20 #endif
21
22 #include <rte_common.h>
23 #include <rte_ether.h>
24 #include <rte_eth_ctrl.h>
25 #include <rte_ethdev_driver.h>
26 #include <rte_flow.h>
27 #include <rte_flow_driver.h>
28 #include <rte_malloc.h>
29 #include <rte_ip.h>
30
31 #include "mlx5.h"
32 #include "mlx5_defs.h"
33 #include "mlx5_prm.h"
34 #include "mlx5_glue.h"
35 #include "mlx5_flow.h"
36
37 /* Dev ops structure defined in mlx5.c */
38 extern const struct eth_dev_ops mlx5_dev_ops;
39 extern const struct eth_dev_ops mlx5_dev_ops_isolate;
40
41 enum mlx5_expansion {
42         MLX5_EXPANSION_ROOT,
43         MLX5_EXPANSION_ROOT_OUTER,
44         MLX5_EXPANSION_ROOT_ETH_VLAN,
45         MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN,
46         MLX5_EXPANSION_OUTER_ETH,
47         MLX5_EXPANSION_OUTER_ETH_VLAN,
48         MLX5_EXPANSION_OUTER_VLAN,
49         MLX5_EXPANSION_OUTER_IPV4,
50         MLX5_EXPANSION_OUTER_IPV4_UDP,
51         MLX5_EXPANSION_OUTER_IPV4_TCP,
52         MLX5_EXPANSION_OUTER_IPV6,
53         MLX5_EXPANSION_OUTER_IPV6_UDP,
54         MLX5_EXPANSION_OUTER_IPV6_TCP,
55         MLX5_EXPANSION_VXLAN,
56         MLX5_EXPANSION_VXLAN_GPE,
57         MLX5_EXPANSION_GRE,
58         MLX5_EXPANSION_MPLS,
59         MLX5_EXPANSION_ETH,
60         MLX5_EXPANSION_ETH_VLAN,
61         MLX5_EXPANSION_VLAN,
62         MLX5_EXPANSION_IPV4,
63         MLX5_EXPANSION_IPV4_UDP,
64         MLX5_EXPANSION_IPV4_TCP,
65         MLX5_EXPANSION_IPV6,
66         MLX5_EXPANSION_IPV6_UDP,
67         MLX5_EXPANSION_IPV6_TCP,
68 };
69
70 /** Supported expansion of items. */
71 static const struct rte_flow_expand_node mlx5_support_expansion[] = {
72         [MLX5_EXPANSION_ROOT] = {
73                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH,
74                                                  MLX5_EXPANSION_IPV4,
75                                                  MLX5_EXPANSION_IPV6),
76                 .type = RTE_FLOW_ITEM_TYPE_END,
77         },
78         [MLX5_EXPANSION_ROOT_OUTER] = {
79                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_ETH,
80                                                  MLX5_EXPANSION_OUTER_IPV4,
81                                                  MLX5_EXPANSION_OUTER_IPV6),
82                 .type = RTE_FLOW_ITEM_TYPE_END,
83         },
84         [MLX5_EXPANSION_ROOT_ETH_VLAN] = {
85                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH_VLAN),
86                 .type = RTE_FLOW_ITEM_TYPE_END,
87         },
88         [MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN] = {
89                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_ETH_VLAN),
90                 .type = RTE_FLOW_ITEM_TYPE_END,
91         },
92         [MLX5_EXPANSION_OUTER_ETH] = {
93                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4,
94                                                  MLX5_EXPANSION_OUTER_IPV6,
95                                                  MLX5_EXPANSION_MPLS),
96                 .type = RTE_FLOW_ITEM_TYPE_ETH,
97                 .rss_types = 0,
98         },
99         [MLX5_EXPANSION_OUTER_ETH_VLAN] = {
100                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_VLAN),
101                 .type = RTE_FLOW_ITEM_TYPE_ETH,
102                 .rss_types = 0,
103         },
104         [MLX5_EXPANSION_OUTER_VLAN] = {
105                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4,
106                                                  MLX5_EXPANSION_OUTER_IPV6),
107                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
108         },
109         [MLX5_EXPANSION_OUTER_IPV4] = {
110                 .next = RTE_FLOW_EXPAND_RSS_NEXT
111                         (MLX5_EXPANSION_OUTER_IPV4_UDP,
112                          MLX5_EXPANSION_OUTER_IPV4_TCP,
113                          MLX5_EXPANSION_GRE),
114                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
115                 .rss_types = ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 |
116                         ETH_RSS_NONFRAG_IPV4_OTHER,
117         },
118         [MLX5_EXPANSION_OUTER_IPV4_UDP] = {
119                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN,
120                                                  MLX5_EXPANSION_VXLAN_GPE),
121                 .type = RTE_FLOW_ITEM_TYPE_UDP,
122                 .rss_types = ETH_RSS_NONFRAG_IPV4_UDP,
123         },
124         [MLX5_EXPANSION_OUTER_IPV4_TCP] = {
125                 .type = RTE_FLOW_ITEM_TYPE_TCP,
126                 .rss_types = ETH_RSS_NONFRAG_IPV4_TCP,
127         },
128         [MLX5_EXPANSION_OUTER_IPV6] = {
129                 .next = RTE_FLOW_EXPAND_RSS_NEXT
130                         (MLX5_EXPANSION_OUTER_IPV6_UDP,
131                          MLX5_EXPANSION_OUTER_IPV6_TCP),
132                 .type = RTE_FLOW_ITEM_TYPE_IPV6,
133                 .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
134                         ETH_RSS_NONFRAG_IPV6_OTHER,
135         },
136         [MLX5_EXPANSION_OUTER_IPV6_UDP] = {
137                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN,
138                                                  MLX5_EXPANSION_VXLAN_GPE),
139                 .type = RTE_FLOW_ITEM_TYPE_UDP,
140                 .rss_types = ETH_RSS_NONFRAG_IPV6_UDP,
141         },
142         [MLX5_EXPANSION_OUTER_IPV6_TCP] = {
143                 .type = RTE_FLOW_ITEM_TYPE_TCP,
144                 .rss_types = ETH_RSS_NONFRAG_IPV6_TCP,
145         },
146         [MLX5_EXPANSION_VXLAN] = {
147                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH),
148                 .type = RTE_FLOW_ITEM_TYPE_VXLAN,
149         },
150         [MLX5_EXPANSION_VXLAN_GPE] = {
151                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH,
152                                                  MLX5_EXPANSION_IPV4,
153                                                  MLX5_EXPANSION_IPV6),
154                 .type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
155         },
156         [MLX5_EXPANSION_GRE] = {
157                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4),
158                 .type = RTE_FLOW_ITEM_TYPE_GRE,
159         },
160         [MLX5_EXPANSION_MPLS] = {
161                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
162                                                  MLX5_EXPANSION_IPV6),
163                 .type = RTE_FLOW_ITEM_TYPE_MPLS,
164         },
165         [MLX5_EXPANSION_ETH] = {
166                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
167                                                  MLX5_EXPANSION_IPV6),
168                 .type = RTE_FLOW_ITEM_TYPE_ETH,
169         },
170         [MLX5_EXPANSION_ETH_VLAN] = {
171                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VLAN),
172                 .type = RTE_FLOW_ITEM_TYPE_ETH,
173         },
174         [MLX5_EXPANSION_VLAN] = {
175                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
176                                                  MLX5_EXPANSION_IPV6),
177                 .type = RTE_FLOW_ITEM_TYPE_VLAN,
178         },
179         [MLX5_EXPANSION_IPV4] = {
180                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4_UDP,
181                                                  MLX5_EXPANSION_IPV4_TCP),
182                 .type = RTE_FLOW_ITEM_TYPE_IPV4,
183                 .rss_types = ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 |
184                         ETH_RSS_NONFRAG_IPV4_OTHER,
185         },
186         [MLX5_EXPANSION_IPV4_UDP] = {
187                 .type = RTE_FLOW_ITEM_TYPE_UDP,
188                 .rss_types = ETH_RSS_NONFRAG_IPV4_UDP,
189         },
190         [MLX5_EXPANSION_IPV4_TCP] = {
191                 .type = RTE_FLOW_ITEM_TYPE_TCP,
192                 .rss_types = ETH_RSS_NONFRAG_IPV4_TCP,
193         },
194         [MLX5_EXPANSION_IPV6] = {
195                 .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV6_UDP,
196                                                  MLX5_EXPANSION_IPV6_TCP),
197                 .type = RTE_FLOW_ITEM_TYPE_IPV6,
198                 .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
199                         ETH_RSS_NONFRAG_IPV6_OTHER,
200         },
201         [MLX5_EXPANSION_IPV6_UDP] = {
202                 .type = RTE_FLOW_ITEM_TYPE_UDP,
203                 .rss_types = ETH_RSS_NONFRAG_IPV6_UDP,
204         },
205         [MLX5_EXPANSION_IPV6_TCP] = {
206                 .type = RTE_FLOW_ITEM_TYPE_TCP,
207                 .rss_types = ETH_RSS_NONFRAG_IPV6_TCP,
208         },
209 };
210
211 static const struct rte_flow_ops mlx5_flow_ops = {
212         .validate = mlx5_flow_validate,
213         .create = mlx5_flow_create,
214         .destroy = mlx5_flow_destroy,
215         .flush = mlx5_flow_flush,
216         .isolate = mlx5_flow_isolate,
217         .query = mlx5_flow_query,
218 };
219
220 /* Convert FDIR request to Generic flow. */
221 struct mlx5_fdir {
222         struct rte_flow_attr attr;
223         struct rte_flow_action actions[2];
224         struct rte_flow_item items[4];
225         struct rte_flow_item_eth l2;
226         struct rte_flow_item_eth l2_mask;
227         union {
228                 struct rte_flow_item_ipv4 ipv4;
229                 struct rte_flow_item_ipv6 ipv6;
230         } l3;
231         union {
232                 struct rte_flow_item_ipv4 ipv4;
233                 struct rte_flow_item_ipv6 ipv6;
234         } l3_mask;
235         union {
236                 struct rte_flow_item_udp udp;
237                 struct rte_flow_item_tcp tcp;
238         } l4;
239         union {
240                 struct rte_flow_item_udp udp;
241                 struct rte_flow_item_tcp tcp;
242         } l4_mask;
243         struct rte_flow_action_queue queue;
244 };
245
246 /* Map of Verbs to Flow priority with 8 Verbs priorities. */
247 static const uint32_t priority_map_3[][MLX5_PRIORITY_MAP_MAX] = {
248         { 0, 1, 2 }, { 2, 3, 4 }, { 5, 6, 7 },
249 };
250
251 /* Map of Verbs to Flow priority with 16 Verbs priorities. */
252 static const uint32_t priority_map_5[][MLX5_PRIORITY_MAP_MAX] = {
253         { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 },
254         { 9, 10, 11 }, { 12, 13, 14 },
255 };
256
257 /* Tunnel information. */
258 struct mlx5_flow_tunnel_info {
259         uint32_t tunnel; /**< Tunnel bit (see MLX5_FLOW_*). */
260         uint32_t ptype; /**< Tunnel Ptype (see RTE_PTYPE_*). */
261 };
262
263 static struct mlx5_flow_tunnel_info tunnels_info[] = {
264         {
265                 .tunnel = MLX5_FLOW_LAYER_VXLAN,
266                 .ptype = RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP,
267         },
268         {
269                 .tunnel = MLX5_FLOW_LAYER_VXLAN_GPE,
270                 .ptype = RTE_PTYPE_TUNNEL_VXLAN_GPE | RTE_PTYPE_L4_UDP,
271         },
272         {
273                 .tunnel = MLX5_FLOW_LAYER_GRE,
274                 .ptype = RTE_PTYPE_TUNNEL_GRE,
275         },
276         {
277                 .tunnel = MLX5_FLOW_LAYER_MPLS | MLX5_FLOW_LAYER_OUTER_L4_UDP,
278                 .ptype = RTE_PTYPE_TUNNEL_MPLS_IN_GRE | RTE_PTYPE_L4_UDP,
279         },
280         {
281                 .tunnel = MLX5_FLOW_LAYER_MPLS,
282                 .ptype = RTE_PTYPE_TUNNEL_MPLS_IN_GRE,
283         },
284 };
285
286 /* Holds the nic operations that should be used. */
287 struct mlx5_flow_driver_ops nic_ops;
288
289 /**
290  * Discover the maximum number of priority available.
291  *
292  * @param[in] dev
293  *   Pointer to the Ethernet device structure.
294  *
295  * @return
296  *   number of supported flow priority on success, a negative errno
297  *   value otherwise and rte_errno is set.
298  */
299 int
300 mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
301 {
302         struct {
303                 struct ibv_flow_attr attr;
304                 struct ibv_flow_spec_eth eth;
305                 struct ibv_flow_spec_action_drop drop;
306         } flow_attr = {
307                 .attr = {
308                         .num_of_specs = 2,
309                 },
310                 .eth = {
311                         .type = IBV_FLOW_SPEC_ETH,
312                         .size = sizeof(struct ibv_flow_spec_eth),
313                 },
314                 .drop = {
315                         .size = sizeof(struct ibv_flow_spec_action_drop),
316                         .type = IBV_FLOW_SPEC_ACTION_DROP,
317                 },
318         };
319         struct ibv_flow *flow;
320         struct mlx5_hrxq *drop = mlx5_hrxq_drop_new(dev);
321         uint16_t vprio[] = { 8, 16 };
322         int i;
323         int priority = 0;
324
325         if (!drop) {
326                 rte_errno = ENOTSUP;
327                 return -rte_errno;
328         }
329         for (i = 0; i != RTE_DIM(vprio); i++) {
330                 flow_attr.attr.priority = vprio[i] - 1;
331                 flow = mlx5_glue->create_flow(drop->qp, &flow_attr.attr);
332                 if (!flow)
333                         break;
334                 claim_zero(mlx5_glue->destroy_flow(flow));
335                 priority = vprio[i];
336         }
337         switch (priority) {
338         case 8:
339                 priority = RTE_DIM(priority_map_3);
340                 break;
341         case 16:
342                 priority = RTE_DIM(priority_map_5);
343                 break;
344         default:
345                 rte_errno = ENOTSUP;
346                 DRV_LOG(ERR,
347                         "port %u verbs maximum priority: %d expected 8/16",
348                         dev->data->port_id, vprio[i]);
349                 return -rte_errno;
350         }
351         mlx5_hrxq_drop_release(dev);
352         DRV_LOG(INFO, "port %u flow maximum priority: %d",
353                 dev->data->port_id, priority);
354         return priority;
355 }
356
357 /**
358  * Adjust flow priority based on the highest layer and the request priority.
359  *
360  * @param[in] dev
361  *   Pointer to the Ethernet device structure.
362  * @param[in] priority
363  *   The rule base priority.
364  * @param[in] subpriority
365  *   The priority based on the items.
366  *
367  * @return
368  *   The new priority.
369  */
370 uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
371                                    uint32_t subpriority)
372 {
373         uint32_t res = 0;
374         struct priv *priv = dev->data->dev_private;
375
376         switch (priv->config.flow_prio) {
377         case RTE_DIM(priority_map_3):
378                 res = priority_map_3[priority][subpriority];
379                 break;
380         case RTE_DIM(priority_map_5):
381                 res = priority_map_5[priority][subpriority];
382                 break;
383         }
384         return  res;
385 }
386
387 /**
388  * Verify the @p item specifications (spec, last, mask) are compatible with the
389  * NIC capabilities.
390  *
391  * @param[in] item
392  *   Item specification.
393  * @param[in] mask
394  *   @p item->mask or flow default bit-masks.
395  * @param[in] nic_mask
396  *   Bit-masks covering supported fields by the NIC to compare with user mask.
397  * @param[in] size
398  *   Bit-masks size in bytes.
399  * @param[out] error
400  *   Pointer to error structure.
401  *
402  * @return
403  *   0 on success, a negative errno value otherwise and rte_errno is set.
404  */
405 static int
406 mlx5_flow_item_acceptable(const struct rte_flow_item *item,
407                           const uint8_t *mask,
408                           const uint8_t *nic_mask,
409                           unsigned int size,
410                           struct rte_flow_error *error)
411 {
412         unsigned int i;
413
414         assert(nic_mask);
415         for (i = 0; i < size; ++i)
416                 if ((nic_mask[i] | mask[i]) != nic_mask[i])
417                         return rte_flow_error_set(error, ENOTSUP,
418                                                   RTE_FLOW_ERROR_TYPE_ITEM,
419                                                   item,
420                                                   "mask enables non supported"
421                                                   " bits");
422         if (!item->spec && (item->mask || item->last))
423                 return rte_flow_error_set(error, EINVAL,
424                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
425                                           "mask/last without a spec is not"
426                                           " supported");
427         if (item->spec && item->last) {
428                 uint8_t spec[size];
429                 uint8_t last[size];
430                 unsigned int i;
431                 int ret;
432
433                 for (i = 0; i < size; ++i) {
434                         spec[i] = ((const uint8_t *)item->spec)[i] & mask[i];
435                         last[i] = ((const uint8_t *)item->last)[i] & mask[i];
436                 }
437                 ret = memcmp(spec, last, size);
438                 if (ret != 0)
439                         return rte_flow_error_set(error, ENOTSUP,
440                                                   RTE_FLOW_ERROR_TYPE_ITEM,
441                                                   item,
442                                                   "range is not supported");
443         }
444         return 0;
445 }
446
447 /**
448  * Adjust the hash fields according to the @p flow information.
449  *
450  * @param[in] dev_flow.
451  *   Pointer to the mlx5_flow.
452  * @param[in] tunnel
453  *   1 when the hash field is for a tunnel item.
454  * @param[in] layer_types
455  *   ETH_RSS_* types.
456  * @param[in] hash_fields
457  *   Item hash fields.
458  *
459  * @return
460  *   The hash fileds that should be used.
461  */
462 uint64_t
463 mlx5_flow_hashfields_adjust(struct mlx5_flow *dev_flow,
464                             int tunnel __rte_unused, uint32_t layer_types,
465                             uint64_t hash_fields)
466 {
467         struct rte_flow *flow = dev_flow->flow;
468 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
469         int rss_request_inner = flow->rss.level >= 2;
470
471         /* Check RSS hash level for tunnel. */
472         if (tunnel && rss_request_inner)
473                 hash_fields |= IBV_RX_HASH_INNER;
474         else if (tunnel || rss_request_inner)
475                 return 0;
476 #endif
477         /* Check if requested layer matches RSS hash fields. */
478         if (!(flow->rss.types & layer_types))
479                 return 0;
480         return hash_fields;
481 }
482
483 /**
484  * Lookup and set the ptype in the data Rx part.  A single Ptype can be used,
485  * if several tunnel rules are used on this queue, the tunnel ptype will be
486  * cleared.
487  *
488  * @param rxq_ctrl
489  *   Rx queue to update.
490  */
491 static void
492 mlx5_flow_rxq_tunnel_ptype_update(struct mlx5_rxq_ctrl *rxq_ctrl)
493 {
494         unsigned int i;
495         uint32_t tunnel_ptype = 0;
496
497         /* Look up for the ptype to use. */
498         for (i = 0; i != MLX5_FLOW_TUNNEL; ++i) {
499                 if (!rxq_ctrl->flow_tunnels_n[i])
500                         continue;
501                 if (!tunnel_ptype) {
502                         tunnel_ptype = tunnels_info[i].ptype;
503                 } else {
504                         tunnel_ptype = 0;
505                         break;
506                 }
507         }
508         rxq_ctrl->rxq.tunnel = tunnel_ptype;
509 }
510
511 /**
512  * Set the Rx queue flags (Mark/Flag and Tunnel Ptypes) according to the flow.
513  *
514  * @param[in] dev
515  *   Pointer to the Ethernet device structure.
516  * @param[in] flow
517  *   Pointer to flow structure.
518  */
519 static void
520 mlx5_flow_rxq_flags_set(struct rte_eth_dev *dev, struct rte_flow *flow)
521 {
522         struct priv *priv = dev->data->dev_private;
523         const int mark = !!(flow->actions &
524                             (MLX5_FLOW_ACTION_FLAG | MLX5_FLOW_ACTION_MARK));
525         const int tunnel = !!(flow->layers & MLX5_FLOW_LAYER_TUNNEL);
526         unsigned int i;
527
528         for (i = 0; i != flow->rss.queue_num; ++i) {
529                 int idx = (*flow->queue)[i];
530                 struct mlx5_rxq_ctrl *rxq_ctrl =
531                         container_of((*priv->rxqs)[idx],
532                                      struct mlx5_rxq_ctrl, rxq);
533
534                 if (mark) {
535                         rxq_ctrl->rxq.mark = 1;
536                         rxq_ctrl->flow_mark_n++;
537                 }
538                 if (tunnel) {
539                         unsigned int j;
540
541                         /* Increase the counter matching the flow. */
542                         for (j = 0; j != MLX5_FLOW_TUNNEL; ++j) {
543                                 if ((tunnels_info[j].tunnel & flow->layers) ==
544                                     tunnels_info[j].tunnel) {
545                                         rxq_ctrl->flow_tunnels_n[j]++;
546                                         break;
547                                 }
548                         }
549                         mlx5_flow_rxq_tunnel_ptype_update(rxq_ctrl);
550                 }
551         }
552 }
553
554 /**
555  * Clear the Rx queue flags (Mark/Flag and Tunnel Ptype) associated with the
556  * @p flow if no other flow uses it with the same kind of request.
557  *
558  * @param dev
559  *   Pointer to Ethernet device.
560  * @param[in] flow
561  *   Pointer to the flow.
562  */
563 static void
564 mlx5_flow_rxq_flags_trim(struct rte_eth_dev *dev, struct rte_flow *flow)
565 {
566         struct priv *priv = dev->data->dev_private;
567         const int mark = !!(flow->actions &
568                             (MLX5_FLOW_ACTION_FLAG | MLX5_FLOW_ACTION_MARK));
569         const int tunnel = !!(flow->layers & MLX5_FLOW_LAYER_TUNNEL);
570         unsigned int i;
571
572         assert(dev->data->dev_started);
573         for (i = 0; i != flow->rss.queue_num; ++i) {
574                 int idx = (*flow->queue)[i];
575                 struct mlx5_rxq_ctrl *rxq_ctrl =
576                         container_of((*priv->rxqs)[idx],
577                                      struct mlx5_rxq_ctrl, rxq);
578
579                 if (mark) {
580                         rxq_ctrl->flow_mark_n--;
581                         rxq_ctrl->rxq.mark = !!rxq_ctrl->flow_mark_n;
582                 }
583                 if (tunnel) {
584                         unsigned int j;
585
586                         /* Decrease the counter matching the flow. */
587                         for (j = 0; j != MLX5_FLOW_TUNNEL; ++j) {
588                                 if ((tunnels_info[j].tunnel & flow->layers) ==
589                                     tunnels_info[j].tunnel) {
590                                         rxq_ctrl->flow_tunnels_n[j]--;
591                                         break;
592                                 }
593                         }
594                         mlx5_flow_rxq_tunnel_ptype_update(rxq_ctrl);
595                 }
596         }
597 }
598
599 /**
600  * Clear the Mark/Flag and Tunnel ptype information in all Rx queues.
601  *
602  * @param dev
603  *   Pointer to Ethernet device.
604  */
605 static void
606 mlx5_flow_rxq_flags_clear(struct rte_eth_dev *dev)
607 {
608         struct priv *priv = dev->data->dev_private;
609         unsigned int i;
610
611         for (i = 0; i != priv->rxqs_n; ++i) {
612                 struct mlx5_rxq_ctrl *rxq_ctrl;
613                 unsigned int j;
614
615                 if (!(*priv->rxqs)[i])
616                         continue;
617                 rxq_ctrl = container_of((*priv->rxqs)[i],
618                                         struct mlx5_rxq_ctrl, rxq);
619                 rxq_ctrl->flow_mark_n = 0;
620                 rxq_ctrl->rxq.mark = 0;
621                 for (j = 0; j != MLX5_FLOW_TUNNEL; ++j)
622                         rxq_ctrl->flow_tunnels_n[j] = 0;
623                 rxq_ctrl->rxq.tunnel = 0;
624         }
625 }
626
627 /*
628  * Validate the flag action.
629  *
630  * @param[in] action_flags
631  *   Bit-fields that holds the actions detected until now.
632  * @param[out] error
633  *   Pointer to error structure.
634  *
635  * @return
636  *   0 on success, a negative errno value otherwise and rte_errno is set.
637  */
638 int
639 mlx5_flow_validate_action_flag(uint64_t action_flags,
640                                struct rte_flow_error *error)
641 {
642
643         if (action_flags & MLX5_FLOW_ACTION_DROP)
644                 return rte_flow_error_set(error, EINVAL,
645                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
646                                           "can't drop and flag in same flow");
647         if (action_flags & MLX5_FLOW_ACTION_MARK)
648                 return rte_flow_error_set(error, EINVAL,
649                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
650                                           "can't mark and flag in same flow");
651         if (action_flags & MLX5_FLOW_ACTION_FLAG)
652                 return rte_flow_error_set(error, EINVAL,
653                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
654                                           "can't have 2 flag"
655                                           " actions in same flow");
656         return 0;
657 }
658
659 /*
660  * Validate the mark action.
661  *
662  * @param[in] action
663  *   Pointer to the queue action.
664  * @param[in] action_flags
665  *   Bit-fields that holds the actions detected until now.
666  * @param[out] error
667  *   Pointer to error structure.
668  *
669  * @return
670  *   0 on success, a negative errno value otherwise and rte_errno is set.
671  */
672 int
673 mlx5_flow_validate_action_mark(const struct rte_flow_action *action,
674                                uint64_t action_flags,
675                                struct rte_flow_error *error)
676 {
677         const struct rte_flow_action_mark *mark = action->conf;
678
679         if (!mark)
680                 return rte_flow_error_set(error, EINVAL,
681                                           RTE_FLOW_ERROR_TYPE_ACTION,
682                                           action,
683                                           "configuration cannot be null");
684         if (mark->id >= MLX5_FLOW_MARK_MAX)
685                 return rte_flow_error_set(error, EINVAL,
686                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
687                                           &mark->id,
688                                           "mark id must in 0 <= id < "
689                                           RTE_STR(MLX5_FLOW_MARK_MAX));
690         if (action_flags & MLX5_FLOW_ACTION_DROP)
691                 return rte_flow_error_set(error, EINVAL,
692                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
693                                           "can't drop and mark in same flow");
694         if (action_flags & MLX5_FLOW_ACTION_FLAG)
695                 return rte_flow_error_set(error, EINVAL,
696                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
697                                           "can't flag and mark in same flow");
698         if (action_flags & MLX5_FLOW_ACTION_MARK)
699                 return rte_flow_error_set(error, EINVAL,
700                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
701                                           "can't have 2 mark actions in same"
702                                           " flow");
703         return 0;
704 }
705
706 /*
707  * Validate the drop action.
708  *
709  * @param[in] action_flags
710  *   Bit-fields that holds the actions detected until now.
711  * @param[out] error
712  *   Pointer to error structure.
713  *
714  * @return
715  *   0 on success, a negative errno value otherwise and rte_ernno is set.
716  */
717 int
718 mlx5_flow_validate_action_drop(uint64_t action_flags,
719                                struct rte_flow_error *error)
720 {
721         if (action_flags & MLX5_FLOW_ACTION_FLAG)
722                 return rte_flow_error_set(error, EINVAL,
723                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
724                                           "can't drop and flag in same flow");
725         if (action_flags & MLX5_FLOW_ACTION_MARK)
726                 return rte_flow_error_set(error, EINVAL,
727                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
728                                           "can't drop and mark in same flow");
729         if (action_flags & MLX5_FLOW_FATE_ACTIONS)
730                 return rte_flow_error_set(error, EINVAL,
731                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
732                                           "can't have 2 fate actions in"
733                                           " same flow");
734         return 0;
735 }
736
737 /*
738  * Validate the queue action.
739  *
740  * @param[in] action
741  *   Pointer to the queue action.
742  * @param[in] action_flags
743  *   Bit-fields that holds the actions detected until now.
744  * @param[in] dev
745  *   Pointer to the Ethernet device structure.
746  * @param[out] error
747  *   Pointer to error structure.
748  *
749  * @return
750  *   0 on success, a negative errno value otherwise and rte_ernno is set.
751  */
752 int
753 mlx5_flow_validate_action_queue(const struct rte_flow_action *action,
754                                 uint64_t action_flags,
755                                 struct rte_eth_dev *dev,
756                                 struct rte_flow_error *error)
757 {
758         struct priv *priv = dev->data->dev_private;
759         const struct rte_flow_action_queue *queue = action->conf;
760
761         if (action_flags & MLX5_FLOW_FATE_ACTIONS)
762                 return rte_flow_error_set(error, EINVAL,
763                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
764                                           "can't have 2 fate actions in"
765                                           " same flow");
766         if (queue->index >= priv->rxqs_n)
767                 return rte_flow_error_set(error, EINVAL,
768                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
769                                           &queue->index,
770                                           "queue index out of range");
771         if (!(*priv->rxqs)[queue->index])
772                 return rte_flow_error_set(error, EINVAL,
773                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
774                                           &queue->index,
775                                           "queue is not configured");
776         return 0;
777 }
778
779 /*
780  * Validate the rss action.
781  *
782  * @param[in] action
783  *   Pointer to the queue action.
784  * @param[in] action_flags
785  *   Bit-fields that holds the actions detected until now.
786  * @param[in] dev
787  *   Pointer to the Ethernet device structure.
788  * @param[out] error
789  *   Pointer to error structure.
790  *
791  * @return
792  *   0 on success, a negative errno value otherwise and rte_ernno is set.
793  */
794 int
795 mlx5_flow_validate_action_rss(const struct rte_flow_action *action,
796                               uint64_t action_flags,
797                               struct rte_eth_dev *dev,
798                               struct rte_flow_error *error)
799 {
800         struct priv *priv = dev->data->dev_private;
801         const struct rte_flow_action_rss *rss = action->conf;
802         unsigned int i;
803
804         if (action_flags & MLX5_FLOW_FATE_ACTIONS)
805                 return rte_flow_error_set(error, EINVAL,
806                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
807                                           "can't have 2 fate actions"
808                                           " in same flow");
809         if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT &&
810             rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ)
811                 return rte_flow_error_set(error, ENOTSUP,
812                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
813                                           &rss->func,
814                                           "RSS hash function not supported");
815 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
816         if (rss->level > 2)
817 #else
818         if (rss->level > 1)
819 #endif
820                 return rte_flow_error_set(error, ENOTSUP,
821                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
822                                           &rss->level,
823                                           "tunnel RSS is not supported");
824         if (rss->key_len < MLX5_RSS_HASH_KEY_LEN)
825                 return rte_flow_error_set(error, ENOTSUP,
826                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
827                                           &rss->key_len,
828                                           "RSS hash key too small");
829         if (rss->key_len > MLX5_RSS_HASH_KEY_LEN)
830                 return rte_flow_error_set(error, ENOTSUP,
831                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
832                                           &rss->key_len,
833                                           "RSS hash key too large");
834         if (rss->queue_num > priv->config.ind_table_max_size)
835                 return rte_flow_error_set(error, ENOTSUP,
836                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
837                                           &rss->queue_num,
838                                           "number of queues too large");
839         if (rss->types & MLX5_RSS_HF_MASK)
840                 return rte_flow_error_set(error, ENOTSUP,
841                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
842                                           &rss->types,
843                                           "some RSS protocols are not"
844                                           " supported");
845         for (i = 0; i != rss->queue_num; ++i) {
846                 if (!(*priv->rxqs)[rss->queue[i]])
847                         return rte_flow_error_set
848                                 (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_CONF,
849                                  &rss->queue[i], "queue is not configured");
850         }
851         return 0;
852 }
853
854 /*
855  * Validate the count action.
856  *
857  * @param[in] dev
858  *   Pointer to the Ethernet device structure.
859  * @param[out] error
860  *   Pointer to error structure.
861  *
862  * @return
863  *   0 on success, a negative errno value otherwise and rte_ernno is set.
864  */
865 int
866 mlx5_flow_validate_action_count(struct rte_eth_dev *dev,
867                                 struct rte_flow_error *error)
868 {
869         struct priv *priv = dev->data->dev_private;
870
871         if (!priv->config.flow_counter_en)
872                 return rte_flow_error_set(error, ENOTSUP,
873                                           RTE_FLOW_ERROR_TYPE_ACTION, NULL,
874                                           "flow counters are not supported.");
875         return 0;
876 }
877
878 /**
879  * Verify the @p attributes will be correctly understood by the NIC and store
880  * them in the @p flow if everything is correct.
881  *
882  * @param[in] dev
883  *   Pointer to the Ethernet device structure.
884  * @param[in] attributes
885  *   Pointer to flow attributes
886  * @param[out] error
887  *   Pointer to error structure.
888  *
889  * @return
890  *   0 on success, a negative errno value otherwise and rte_errno is set.
891  */
892 int
893 mlx5_flow_validate_attributes(struct rte_eth_dev *dev,
894                               const struct rte_flow_attr *attributes,
895                               struct rte_flow_error *error)
896 {
897         struct priv *priv = dev->data->dev_private;
898         uint32_t priority_max = priv->config.flow_prio - 1;
899
900         if (attributes->group)
901                 return rte_flow_error_set(error, ENOTSUP,
902                                           RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
903                                           NULL, "groups is not supported");
904         if (attributes->priority != MLX5_FLOW_PRIO_RSVD &&
905             attributes->priority >= priority_max)
906                 return rte_flow_error_set(error, ENOTSUP,
907                                           RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
908                                           NULL, "priority out of range");
909         if (attributes->egress)
910                 return rte_flow_error_set(error, ENOTSUP,
911                                           RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL,
912                                           "egress is not supported");
913         if (attributes->transfer)
914                 return rte_flow_error_set(error, ENOTSUP,
915                                           RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
916                                           NULL, "transfer is not supported");
917         if (!attributes->ingress)
918                 return rte_flow_error_set(error, EINVAL,
919                                           RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
920                                           NULL,
921                                           "ingress attribute is mandatory");
922         return 0;
923 }
924
925 /**
926  * Validate Ethernet item.
927  *
928  * @param[in] item
929  *   Item specification.
930  * @param[in] item_flags
931  *   Bit-fields that holds the items detected until now.
932  * @param[out] error
933  *   Pointer to error structure.
934  *
935  * @return
936  *   0 on success, a negative errno value otherwise and rte_errno is set.
937  */
938 int
939 mlx5_flow_validate_item_eth(const struct rte_flow_item *item,
940                             uint64_t item_flags,
941                             struct rte_flow_error *error)
942 {
943         const struct rte_flow_item_eth *mask = item->mask;
944         const struct rte_flow_item_eth nic_mask = {
945                 .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
946                 .src.addr_bytes = "\xff\xff\xff\xff\xff\xff",
947                 .type = RTE_BE16(0xffff),
948         };
949         int ret;
950         int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
951
952         if (item_flags & MLX5_FLOW_LAYER_OUTER_L2)
953                 return rte_flow_error_set(error, ENOTSUP,
954                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
955                                           "3 levels of l2 are not supported");
956         if ((item_flags & MLX5_FLOW_LAYER_INNER_L2) && !tunnel)
957                 return rte_flow_error_set(error, ENOTSUP,
958                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
959                                           "2 L2 without tunnel are not supported");
960         if (!mask)
961                 mask = &rte_flow_item_eth_mask;
962         ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
963                                         (const uint8_t *)&nic_mask,
964                                         sizeof(struct rte_flow_item_eth),
965                                         error);
966         return ret;
967 }
968
969 /**
970  * Validate VLAN item.
971  *
972  * @param[in] item
973  *   Item specification.
974  * @param[in] item_flags
975  *   Bit-fields that holds the items detected until now.
976  * @param[out] error
977  *   Pointer to error structure.
978  *
979  * @return
980  *   0 on success, a negative errno value otherwise and rte_errno is set.
981  */
982 int
983 mlx5_flow_validate_item_vlan(const struct rte_flow_item *item,
984                              int64_t item_flags,
985                              struct rte_flow_error *error)
986 {
987         const struct rte_flow_item_vlan *spec = item->spec;
988         const struct rte_flow_item_vlan *mask = item->mask;
989         const struct rte_flow_item_vlan nic_mask = {
990                 .tci = RTE_BE16(0x0fff),
991                 .inner_type = RTE_BE16(0xffff),
992         };
993         uint16_t vlan_tag = 0;
994         const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
995         int ret;
996         const uint32_t l34m = tunnel ? (MLX5_FLOW_LAYER_INNER_L3 |
997                                         MLX5_FLOW_LAYER_INNER_L4) :
998                                        (MLX5_FLOW_LAYER_OUTER_L3 |
999                                         MLX5_FLOW_LAYER_OUTER_L4);
1000         const uint32_t vlanm = tunnel ? MLX5_FLOW_LAYER_INNER_VLAN :
1001                                         MLX5_FLOW_LAYER_OUTER_VLAN;
1002
1003         if (item_flags & vlanm)
1004                 return rte_flow_error_set(error, EINVAL,
1005                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1006                                           "VLAN layer already configured");
1007         else if ((item_flags & l34m) != 0)
1008                 return rte_flow_error_set(error, EINVAL,
1009                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1010                                           "L2 layer cannot follow L3/L4 layer");
1011         if (!mask)
1012                 mask = &rte_flow_item_vlan_mask;
1013         ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
1014                                         (const uint8_t *)&nic_mask,
1015                                         sizeof(struct rte_flow_item_vlan),
1016                                         error);
1017         if (ret)
1018                 return ret;
1019         if (spec) {
1020                 vlan_tag = spec->tci;
1021                 vlan_tag &= mask->tci;
1022         }
1023         /*
1024          * From verbs perspective an empty VLAN is equivalent
1025          * to a packet without VLAN layer.
1026          */
1027         if (!vlan_tag)
1028                 return rte_flow_error_set(error, EINVAL,
1029                                           RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
1030                                           item->spec,
1031                                           "VLAN cannot be empty");
1032         return 0;
1033 }
1034
1035 /**
1036  * Validate IPV4 item.
1037  *
1038  * @param[in] item
1039  *   Item specification.
1040  * @param[in] item_flags
1041  *   Bit-fields that holds the items detected until now.
1042  * @param[out] error
1043  *   Pointer to error structure.
1044  *
1045  * @return
1046  *   0 on success, a negative errno value otherwise and rte_errno is set.
1047  */
1048 int
1049 mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item,
1050                              int64_t item_flags,
1051                              struct rte_flow_error *error)
1052 {
1053         const struct rte_flow_item_ipv4 *mask = item->mask;
1054         const struct rte_flow_item_ipv4 nic_mask = {
1055                 .hdr = {
1056                         .src_addr = RTE_BE32(0xffffffff),
1057                         .dst_addr = RTE_BE32(0xffffffff),
1058                         .type_of_service = 0xff,
1059                         .next_proto_id = 0xff,
1060                 },
1061         };
1062         const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
1063         int ret;
1064
1065         if (item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L3 :
1066                                    MLX5_FLOW_LAYER_OUTER_L3))
1067                 return rte_flow_error_set(error, ENOTSUP,
1068                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1069                                           "multiple L3 layers not supported");
1070         else if (item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
1071                                         MLX5_FLOW_LAYER_OUTER_L4))
1072                 return rte_flow_error_set(error, EINVAL,
1073                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1074                                           "L3 cannot follow an L4 layer.");
1075         if (!mask)
1076                 mask = &rte_flow_item_ipv4_mask;
1077         ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
1078                                         (const uint8_t *)&nic_mask,
1079                                         sizeof(struct rte_flow_item_ipv4),
1080                                         error);
1081         if (ret < 0)
1082                 return ret;
1083         return 0;
1084 }
1085
1086 /**
1087  * Validate IPV6 item.
1088  *
1089  * @param[in] item
1090  *   Item specification.
1091  * @param[in] item_flags
1092  *   Bit-fields that holds the items detected until now.
1093  * @param[out] error
1094  *   Pointer to error structure.
1095  *
1096  * @return
1097  *   0 on success, a negative errno value otherwise and rte_errno is set.
1098  */
1099 int
1100 mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item,
1101                              uint64_t item_flags,
1102                              struct rte_flow_error *error)
1103 {
1104         const struct rte_flow_item_ipv6 *mask = item->mask;
1105         const struct rte_flow_item_ipv6 nic_mask = {
1106                 .hdr = {
1107                         .src_addr =
1108                                 "\xff\xff\xff\xff\xff\xff\xff\xff"
1109                                 "\xff\xff\xff\xff\xff\xff\xff\xff",
1110                         .dst_addr =
1111                                 "\xff\xff\xff\xff\xff\xff\xff\xff"
1112                                 "\xff\xff\xff\xff\xff\xff\xff\xff",
1113                         .vtc_flow = RTE_BE32(0xffffffff),
1114                         .proto = 0xff,
1115                         .hop_limits = 0xff,
1116                 },
1117         };
1118         const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
1119         int ret;
1120
1121         if (item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L3 :
1122                                    MLX5_FLOW_LAYER_OUTER_L3))
1123                 return rte_flow_error_set(error, ENOTSUP,
1124                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1125                                           "multiple L3 layers not supported");
1126         else if (item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
1127                                         MLX5_FLOW_LAYER_OUTER_L4))
1128                 return rte_flow_error_set(error, EINVAL,
1129                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1130                                           "L3 cannot follow an L4 layer.");
1131         /*
1132          * IPv6 is not recognised by the NIC inside a GRE tunnel.
1133          * Such support has to be disabled as the rule will be
1134          * accepted.  Issue reproduced with Mellanox OFED 4.3-3.0.2.1 and
1135          * Mellanox OFED 4.4-1.0.0.0.
1136          */
1137         if (tunnel && item_flags & MLX5_FLOW_LAYER_GRE)
1138                 return rte_flow_error_set(error, ENOTSUP,
1139                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1140                                           "IPv6 inside a GRE tunnel is"
1141                                           " not recognised.");
1142         if (!mask)
1143                 mask = &rte_flow_item_ipv6_mask;
1144         ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
1145                                         (const uint8_t *)&nic_mask,
1146                                         sizeof(struct rte_flow_item_ipv6),
1147                                         error);
1148         if (ret < 0)
1149                 return ret;
1150         return 0;
1151 }
1152
1153 /**
1154  * Validate UDP item.
1155  *
1156  * @param[in] item
1157  *   Item specification.
1158  * @param[in] item_flags
1159  *   Bit-fields that holds the items detected until now.
1160  * @param[in] target_protocol
1161  *   The next protocol in the previous item.
1162  * @param[out] error
1163  *   Pointer to error structure.
1164  *
1165  * @return
1166  *   0 on success, a negative errno value otherwise and rte_errno is set.
1167  */
1168 int
1169 mlx5_flow_validate_item_udp(const struct rte_flow_item *item,
1170                             uint64_t item_flags,
1171                             uint8_t target_protocol,
1172                             struct rte_flow_error *error)
1173 {
1174         const struct rte_flow_item_udp *mask = item->mask;
1175         const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
1176         int ret;
1177
1178         if (target_protocol != 0xff && target_protocol != IPPROTO_UDP)
1179                 return rte_flow_error_set(error, EINVAL,
1180                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1181                                           "protocol filtering not compatible"
1182                                           " with UDP layer");
1183         if (!(item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L3 :
1184                                      MLX5_FLOW_LAYER_OUTER_L3)))
1185                 return rte_flow_error_set(error, EINVAL,
1186                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1187                                           "L3 is mandatory to filter on L4");
1188         if (item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
1189                                    MLX5_FLOW_LAYER_OUTER_L4))
1190                 return rte_flow_error_set(error, EINVAL,
1191                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1192                                           "L4 layer is already present");
1193         if (!mask)
1194                 mask = &rte_flow_item_udp_mask;
1195         ret = mlx5_flow_item_acceptable
1196                 (item, (const uint8_t *)mask,
1197                  (const uint8_t *)&rte_flow_item_udp_mask,
1198                  sizeof(struct rte_flow_item_udp), error);
1199         if (ret < 0)
1200                 return ret;
1201         return 0;
1202 }
1203
1204 /**
1205  * Validate TCP item.
1206  *
1207  * @param[in] item
1208  *   Item specification.
1209  * @param[in] item_flags
1210  *   Bit-fields that holds the items detected until now.
1211  * @param[in] target_protocol
1212  *   The next protocol in the previous item.
1213  * @param[out] error
1214  *   Pointer to error structure.
1215  *
1216  * @return
1217  *   0 on success, a negative errno value otherwise and rte_errno is set.
1218  */
1219 int
1220 mlx5_flow_validate_item_tcp(const struct rte_flow_item *item,
1221                             uint64_t item_flags,
1222                             uint8_t target_protocol,
1223                             struct rte_flow_error *error)
1224 {
1225         const struct rte_flow_item_tcp *mask = item->mask;
1226         const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
1227         int ret;
1228
1229         if (target_protocol != 0xff && target_protocol != IPPROTO_TCP)
1230                 return rte_flow_error_set(error, EINVAL,
1231                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1232                                           "protocol filtering not compatible"
1233                                           " with TCP layer");
1234         if (!(item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L3 :
1235                                      MLX5_FLOW_LAYER_OUTER_L3)))
1236                 return rte_flow_error_set(error, EINVAL,
1237                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1238                                           "L3 is mandatory to filter on L4");
1239         if (item_flags & (tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
1240                                    MLX5_FLOW_LAYER_OUTER_L4))
1241                 return rte_flow_error_set(error, EINVAL,
1242                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1243                                           "L4 layer is already present");
1244         if (!mask)
1245                 mask = &rte_flow_item_tcp_mask;
1246         ret = mlx5_flow_item_acceptable
1247                 (item, (const uint8_t *)mask,
1248                  (const uint8_t *)&rte_flow_item_tcp_mask,
1249                  sizeof(struct rte_flow_item_tcp), error);
1250         if (ret < 0)
1251                 return ret;
1252         return 0;
1253 }
1254
1255 /**
1256  * Validate VXLAN item.
1257  *
1258  * @param[in] item
1259  *   Item specification.
1260  * @param[in] item_flags
1261  *   Bit-fields that holds the items detected until now.
1262  * @param[in] target_protocol
1263  *   The next protocol in the previous item.
1264  * @param[out] error
1265  *   Pointer to error structure.
1266  *
1267  * @return
1268  *   0 on success, a negative errno value otherwise and rte_errno is set.
1269  */
1270 int
1271 mlx5_flow_validate_item_vxlan(const struct rte_flow_item *item,
1272                               uint64_t item_flags,
1273                               struct rte_flow_error *error)
1274 {
1275         const struct rte_flow_item_vxlan *spec = item->spec;
1276         const struct rte_flow_item_vxlan *mask = item->mask;
1277         int ret;
1278         union vni {
1279                 uint32_t vlan_id;
1280                 uint8_t vni[4];
1281         } id = { .vlan_id = 0, };
1282         uint32_t vlan_id = 0;
1283
1284
1285         if (item_flags & MLX5_FLOW_LAYER_TUNNEL)
1286                 return rte_flow_error_set(error, ENOTSUP,
1287                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1288                                           "a tunnel is already present");
1289         /*
1290          * Verify only UDPv4 is present as defined in
1291          * https://tools.ietf.org/html/rfc7348
1292          */
1293         if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP))
1294                 return rte_flow_error_set(error, EINVAL,
1295                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1296                                           "no outer UDP layer found");
1297         if (!mask)
1298                 mask = &rte_flow_item_vxlan_mask;
1299         ret = mlx5_flow_item_acceptable
1300                 (item, (const uint8_t *)mask,
1301                  (const uint8_t *)&rte_flow_item_vxlan_mask,
1302                  sizeof(struct rte_flow_item_vxlan),
1303                  error);
1304         if (ret < 0)
1305                 return ret;
1306         if (spec) {
1307                 memcpy(&id.vni[1], spec->vni, 3);
1308                 vlan_id = id.vlan_id;
1309                 memcpy(&id.vni[1], mask->vni, 3);
1310                 vlan_id &= id.vlan_id;
1311         }
1312         /*
1313          * Tunnel id 0 is equivalent as not adding a VXLAN layer, if
1314          * only this layer is defined in the Verbs specification it is
1315          * interpreted as wildcard and all packets will match this
1316          * rule, if it follows a full stack layer (ex: eth / ipv4 /
1317          * udp), all packets matching the layers before will also
1318          * match this rule.  To avoid such situation, VNI 0 is
1319          * currently refused.
1320          */
1321         if (!vlan_id)
1322                 return rte_flow_error_set(error, ENOTSUP,
1323                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1324                                           "VXLAN vni cannot be 0");
1325         if (!(item_flags & MLX5_FLOW_LAYER_OUTER))
1326                 return rte_flow_error_set(error, ENOTSUP,
1327                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1328                                           "VXLAN tunnel must be fully defined");
1329         return 0;
1330 }
1331
1332 /**
1333  * Validate VXLAN_GPE item.
1334  *
1335  * @param[in] item
1336  *   Item specification.
1337  * @param[in] item_flags
1338  *   Bit-fields that holds the items detected until now.
1339  * @param[in] priv
1340  *   Pointer to the private data structure.
1341  * @param[in] target_protocol
1342  *   The next protocol in the previous item.
1343  * @param[out] error
1344  *   Pointer to error structure.
1345  *
1346  * @return
1347  *   0 on success, a negative errno value otherwise and rte_errno is set.
1348  */
1349 int
1350 mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item,
1351                                   uint64_t item_flags,
1352                                   struct rte_eth_dev *dev,
1353                                   struct rte_flow_error *error)
1354 {
1355         struct priv *priv = dev->data->dev_private;
1356         const struct rte_flow_item_vxlan_gpe *spec = item->spec;
1357         const struct rte_flow_item_vxlan_gpe *mask = item->mask;
1358         int ret;
1359         union vni {
1360                 uint32_t vlan_id;
1361                 uint8_t vni[4];
1362         } id = { .vlan_id = 0, };
1363         uint32_t vlan_id = 0;
1364
1365         if (!priv->config.l3_vxlan_en)
1366                 return rte_flow_error_set(error, ENOTSUP,
1367                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1368                                           "L3 VXLAN is not enabled by device"
1369                                           " parameter and/or not configured in"
1370                                           " firmware");
1371         if (item_flags & MLX5_FLOW_LAYER_TUNNEL)
1372                 return rte_flow_error_set(error, ENOTSUP,
1373                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1374                                           "a tunnel is already present");
1375         /*
1376          * Verify only UDPv4 is present as defined in
1377          * https://tools.ietf.org/html/rfc7348
1378          */
1379         if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP))
1380                 return rte_flow_error_set(error, EINVAL,
1381                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1382                                           "no outer UDP layer found");
1383         if (!mask)
1384                 mask = &rte_flow_item_vxlan_gpe_mask;
1385         ret = mlx5_flow_item_acceptable
1386                 (item, (const uint8_t *)mask,
1387                  (const uint8_t *)&rte_flow_item_vxlan_gpe_mask,
1388                  sizeof(struct rte_flow_item_vxlan_gpe),
1389                  error);
1390         if (ret < 0)
1391                 return ret;
1392         if (spec) {
1393                 if (spec->protocol)
1394                         return rte_flow_error_set(error, ENOTSUP,
1395                                                   RTE_FLOW_ERROR_TYPE_ITEM,
1396                                                   item,
1397                                                   "VxLAN-GPE protocol"
1398                                                   " not supported");
1399                 memcpy(&id.vni[1], spec->vni, 3);
1400                 vlan_id = id.vlan_id;
1401                 memcpy(&id.vni[1], mask->vni, 3);
1402                 vlan_id &= id.vlan_id;
1403         }
1404         /*
1405          * Tunnel id 0 is equivalent as not adding a VXLAN layer, if only this
1406          * layer is defined in the Verbs specification it is interpreted as
1407          * wildcard and all packets will match this rule, if it follows a full
1408          * stack layer (ex: eth / ipv4 / udp), all packets matching the layers
1409          * before will also match this rule.  To avoid such situation, VNI 0
1410          * is currently refused.
1411          */
1412         if (!vlan_id)
1413                 return rte_flow_error_set(error, ENOTSUP,
1414                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1415                                           "VXLAN-GPE vni cannot be 0");
1416         if (!(item_flags & MLX5_FLOW_LAYER_OUTER))
1417                 return rte_flow_error_set(error, ENOTSUP,
1418                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1419                                           "VXLAN-GPE tunnel must be fully"
1420                                           " defined");
1421         return 0;
1422 }
1423
1424 /**
1425  * Validate GRE item.
1426  *
1427  * @param[in] item
1428  *   Item specification.
1429  * @param[in] item_flags
1430  *   Bit flags to mark detected items.
1431  * @param[in] target_protocol
1432  *   The next protocol in the previous item.
1433  * @param[out] error
1434  *   Pointer to error structure.
1435  *
1436  * @return
1437  *   0 on success, a negative errno value otherwise and rte_errno is set.
1438  */
1439 int
1440 mlx5_flow_validate_item_gre(const struct rte_flow_item *item,
1441                             uint64_t item_flags,
1442                             uint8_t target_protocol,
1443                             struct rte_flow_error *error)
1444 {
1445         const struct rte_flow_item_gre *spec __rte_unused = item->spec;
1446         const struct rte_flow_item_gre *mask = item->mask;
1447         int ret;
1448
1449         if (target_protocol != 0xff && target_protocol != IPPROTO_GRE)
1450                 return rte_flow_error_set(error, EINVAL,
1451                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1452                                           "protocol filtering not compatible"
1453                                           " with this GRE layer");
1454         if (item_flags & MLX5_FLOW_LAYER_TUNNEL)
1455                 return rte_flow_error_set(error, ENOTSUP,
1456                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1457                                           "a tunnel is already present");
1458         if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L3))
1459                 return rte_flow_error_set(error, ENOTSUP,
1460                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1461                                           "L3 Layer is missing");
1462         if (!mask)
1463                 mask = &rte_flow_item_gre_mask;
1464         ret = mlx5_flow_item_acceptable
1465                 (item, (const uint8_t *)mask,
1466                  (const uint8_t *)&rte_flow_item_gre_mask,
1467                  sizeof(struct rte_flow_item_gre), error);
1468         if (ret < 0)
1469                 return ret;
1470 #ifndef HAVE_IBV_DEVICE_MPLS_SUPPORT
1471         if (spec && (spec->protocol & mask->protocol))
1472                 return rte_flow_error_set(error, ENOTSUP,
1473                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1474                                           "without MPLS support the"
1475                                           " specification cannot be used for"
1476                                           " filtering");
1477 #endif
1478         return 0;
1479 }
1480
1481 /**
1482  * Validate MPLS item.
1483  *
1484  * @param[in] item
1485  *   Item specification.
1486  * @param[in] item_flags
1487  *   Bit-fields that holds the items detected until now.
1488  * @param[in] target_protocol
1489  *   The next protocol in the previous item.
1490  * @param[out] error
1491  *   Pointer to error structure.
1492  *
1493  * @return
1494  *   0 on success, a negative errno value otherwise and rte_errno is set.
1495  */
1496 int
1497 mlx5_flow_validate_item_mpls(const struct rte_flow_item *item __rte_unused,
1498                              uint64_t item_flags __rte_unused,
1499                              uint8_t target_protocol __rte_unused,
1500                              struct rte_flow_error *error)
1501 {
1502 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
1503         const struct rte_flow_item_mpls *mask = item->mask;
1504         int ret;
1505
1506         if (target_protocol != 0xff && target_protocol != IPPROTO_MPLS)
1507                 return rte_flow_error_set(error, EINVAL,
1508                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1509                                           "protocol filtering not compatible"
1510                                           " with MPLS layer");
1511         if (item_flags & MLX5_FLOW_LAYER_TUNNEL)
1512                 return rte_flow_error_set(error, ENOTSUP,
1513                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
1514                                           "a tunnel is already"
1515                                           " present");
1516         if (!mask)
1517                 mask = &rte_flow_item_mpls_mask;
1518         ret = mlx5_flow_item_acceptable
1519                 (item, (const uint8_t *)mask,
1520                  (const uint8_t *)&rte_flow_item_mpls_mask,
1521                  sizeof(struct rte_flow_item_mpls), error);
1522         if (ret < 0)
1523                 return ret;
1524         return 0;
1525 #endif
1526         return rte_flow_error_set(error, ENOTSUP,
1527                                   RTE_FLOW_ERROR_TYPE_ITEM, item,
1528                                   "MPLS is not supported by Verbs, please"
1529                                   " update.");
1530 }
1531
1532 /**
1533  * Validate a flow supported by the NIC.
1534  *
1535  * @see rte_flow_validate()
1536  * @see rte_flow_ops
1537  */
1538 int
1539 mlx5_flow_validate(struct rte_eth_dev *dev,
1540                    const struct rte_flow_attr *attr,
1541                    const struct rte_flow_item items[],
1542                    const struct rte_flow_action actions[],
1543                    struct rte_flow_error *error)
1544 {
1545         int ret;
1546
1547         ret =  nic_ops.validate(dev, attr, items, actions, error);
1548         if (ret < 0)
1549                 return ret;
1550         return 0;
1551 }
1552
1553 /**
1554  * Get RSS action from the action list.
1555  *
1556  * @param[in] actions
1557  *   Pointer to the list of actions.
1558  *
1559  * @return
1560  *   Pointer to the RSS action if exist, else return NULL.
1561  */
1562 static const struct rte_flow_action_rss*
1563 mlx5_flow_get_rss_action(const struct rte_flow_action actions[])
1564 {
1565         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
1566                 switch (actions->type) {
1567                 case RTE_FLOW_ACTION_TYPE_RSS:
1568                         return (const struct rte_flow_action_rss *)
1569                                actions->conf;
1570                 default:
1571                         break;
1572                 }
1573         }
1574         return NULL;
1575 }
1576
1577 static unsigned int
1578 mlx5_find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level)
1579 {
1580         const struct rte_flow_item *item;
1581         unsigned int has_vlan = 0;
1582
1583         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
1584                 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1585                         has_vlan = 1;
1586                         break;
1587                 }
1588         }
1589         if (has_vlan)
1590                 return rss_level < 2 ? MLX5_EXPANSION_ROOT_ETH_VLAN :
1591                                        MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN;
1592         return rss_level < 2 ? MLX5_EXPANSION_ROOT :
1593                                MLX5_EXPANSION_ROOT_OUTER;
1594 }
1595
1596 /**
1597  * Create a flow and add it to @p list.
1598  *
1599  * @param dev
1600  *   Pointer to Ethernet device.
1601  * @param list
1602  *   Pointer to a TAILQ flow list.
1603  * @param[in] attr
1604  *   Flow rule attributes.
1605  * @param[in] items
1606  *   Pattern specification (list terminated by the END pattern item).
1607  * @param[in] actions
1608  *   Associated actions (list terminated by the END action).
1609  * @param[out] error
1610  *   Perform verbose error reporting if not NULL.
1611  *
1612  * @return
1613  *   A flow on success, NULL otherwise and rte_errno is set.
1614  */
1615 static struct rte_flow *
1616 mlx5_flow_list_create(struct rte_eth_dev *dev,
1617                       struct mlx5_flows *list,
1618                       const struct rte_flow_attr *attr,
1619                       const struct rte_flow_item items[],
1620                       const struct rte_flow_action actions[],
1621                       struct rte_flow_error *error)
1622 {
1623         struct rte_flow *flow = NULL;
1624         struct mlx5_flow *dev_flow;
1625         uint64_t action_flags = 0;
1626         uint64_t item_flags = 0;
1627         const struct rte_flow_action_rss *rss;
1628         union {
1629                 struct rte_flow_expand_rss buf;
1630                 uint8_t buffer[2048];
1631         } expand_buffer;
1632         struct rte_flow_expand_rss *buf = &expand_buffer.buf;
1633         int ret;
1634         uint32_t i;
1635         uint32_t flow_size;
1636
1637         ret = mlx5_flow_validate(dev, attr, items, actions, error);
1638         if (ret < 0)
1639                 return NULL;
1640         flow_size = sizeof(struct rte_flow);
1641         rss = mlx5_flow_get_rss_action(actions);
1642         if (rss)
1643                 flow_size += RTE_ALIGN_CEIL(rss->queue_num * sizeof(uint16_t),
1644                                             sizeof(void *));
1645         else
1646                 flow_size += RTE_ALIGN_CEIL(sizeof(uint16_t), sizeof(void *));
1647         flow = rte_calloc(__func__, 1, flow_size, 0);
1648         flow->queue = (void *)(flow + 1);
1649         LIST_INIT(&flow->dev_flows);
1650         if (rss && rss->types) {
1651                 unsigned int graph_root;
1652
1653                 graph_root = mlx5_find_graph_root(items, rss->level);
1654                 ret = rte_flow_expand_rss(buf, sizeof(expand_buffer.buffer),
1655                                           items, rss->types,
1656                                           mlx5_support_expansion,
1657                                           graph_root);
1658                 assert(ret > 0 &&
1659                        (unsigned int)ret < sizeof(expand_buffer.buffer));
1660         } else {
1661                 buf->entries = 1;
1662                 buf->entry[0].pattern = (void *)(uintptr_t)items;
1663         }
1664         for (i = 0; i < buf->entries; ++i) {
1665                 dev_flow = nic_ops.prepare(attr, buf->entry[i].pattern,
1666                                            actions, &item_flags,
1667                                            &action_flags, error);
1668                 if (!dev_flow)
1669                         goto error;
1670                 dev_flow->flow = flow;
1671                 LIST_INSERT_HEAD(&flow->dev_flows, dev_flow, next);
1672                 ret = nic_ops.translate(dev, dev_flow, attr,
1673                                         buf->entry[i].pattern,
1674                                         actions, error);
1675                 if (ret < 0)
1676                         goto error;
1677         }
1678         if (dev->data->dev_started) {
1679                 ret = nic_ops.apply(dev, flow, error);
1680                 if (ret < 0)
1681                         goto error;
1682         }
1683         TAILQ_INSERT_TAIL(list, flow, next);
1684         mlx5_flow_rxq_flags_set(dev, flow);
1685         return flow;
1686 error:
1687         ret = rte_errno; /* Save rte_errno before cleanup. */
1688         assert(flow);
1689         nic_ops.destroy(dev, flow);
1690         rte_free(flow);
1691         rte_errno = ret; /* Restore rte_errno. */
1692         return NULL;
1693 }
1694
1695 /**
1696  * Create a flow.
1697  *
1698  * @see rte_flow_create()
1699  * @see rte_flow_ops
1700  */
1701 struct rte_flow *
1702 mlx5_flow_create(struct rte_eth_dev *dev,
1703                  const struct rte_flow_attr *attr,
1704                  const struct rte_flow_item items[],
1705                  const struct rte_flow_action actions[],
1706                  struct rte_flow_error *error)
1707 {
1708         return mlx5_flow_list_create
1709                 (dev, &((struct priv *)dev->data->dev_private)->flows,
1710                  attr, items, actions, error);
1711 }
1712
1713 /**
1714  * Destroy a flow in a list.
1715  *
1716  * @param dev
1717  *   Pointer to Ethernet device.
1718  * @param list
1719  *   Pointer to a TAILQ flow list.
1720  * @param[in] flow
1721  *   Flow to destroy.
1722  */
1723 static void
1724 mlx5_flow_list_destroy(struct rte_eth_dev *dev, struct mlx5_flows *list,
1725                        struct rte_flow *flow)
1726 {
1727         nic_ops.destroy(dev, flow);
1728         TAILQ_REMOVE(list, flow, next);
1729         /*
1730          * Update RX queue flags only if port is started, otherwise it is
1731          * already clean.
1732          */
1733         if (dev->data->dev_started)
1734                 mlx5_flow_rxq_flags_trim(dev, flow);
1735         rte_free(flow);
1736 }
1737
1738 /**
1739  * Destroy all flows.
1740  *
1741  * @param dev
1742  *   Pointer to Ethernet device.
1743  * @param list
1744  *   Pointer to a TAILQ flow list.
1745  */
1746 void
1747 mlx5_flow_list_flush(struct rte_eth_dev *dev, struct mlx5_flows *list)
1748 {
1749         while (!TAILQ_EMPTY(list)) {
1750                 struct rte_flow *flow;
1751
1752                 flow = TAILQ_FIRST(list);
1753                 mlx5_flow_list_destroy(dev, list, flow);
1754         }
1755 }
1756
1757 /**
1758  * Remove all flows.
1759  *
1760  * @param dev
1761  *   Pointer to Ethernet device.
1762  * @param list
1763  *   Pointer to a TAILQ flow list.
1764  */
1765 void
1766 mlx5_flow_stop(struct rte_eth_dev *dev, struct mlx5_flows *list)
1767 {
1768         struct rte_flow *flow;
1769
1770         TAILQ_FOREACH_REVERSE(flow, list, mlx5_flows, next)
1771                 nic_ops.remove(dev, flow);
1772         mlx5_flow_rxq_flags_clear(dev);
1773 }
1774
1775 /**
1776  * Add all flows.
1777  *
1778  * @param dev
1779  *   Pointer to Ethernet device.
1780  * @param list
1781  *   Pointer to a TAILQ flow list.
1782  *
1783  * @return
1784  *   0 on success, a negative errno value otherwise and rte_errno is set.
1785  */
1786 int
1787 mlx5_flow_start(struct rte_eth_dev *dev, struct mlx5_flows *list)
1788 {
1789         struct rte_flow *flow;
1790         struct rte_flow_error error;
1791         int ret = 0;
1792
1793         TAILQ_FOREACH(flow, list, next) {
1794                 ret = nic_ops.apply(dev, flow, &error);
1795                 if (ret < 0)
1796                         goto error;
1797                 mlx5_flow_rxq_flags_set(dev, flow);
1798         }
1799         return 0;
1800 error:
1801         ret = rte_errno; /* Save rte_errno before cleanup. */
1802         mlx5_flow_stop(dev, list);
1803         rte_errno = ret; /* Restore rte_errno. */
1804         return -rte_errno;
1805 }
1806
1807 /**
1808  * Verify the flow list is empty
1809  *
1810  * @param dev
1811  *  Pointer to Ethernet device.
1812  *
1813  * @return the number of flows not released.
1814  */
1815 int
1816 mlx5_flow_verify(struct rte_eth_dev *dev)
1817 {
1818         struct priv *priv = dev->data->dev_private;
1819         struct rte_flow *flow;
1820         int ret = 0;
1821
1822         TAILQ_FOREACH(flow, &priv->flows, next) {
1823                 DRV_LOG(DEBUG, "port %u flow %p still referenced",
1824                         dev->data->port_id, (void *)flow);
1825                 ++ret;
1826         }
1827         return ret;
1828 }
1829
1830 /**
1831  * Enable a control flow configured from the control plane.
1832  *
1833  * @param dev
1834  *   Pointer to Ethernet device.
1835  * @param eth_spec
1836  *   An Ethernet flow spec to apply.
1837  * @param eth_mask
1838  *   An Ethernet flow mask to apply.
1839  * @param vlan_spec
1840  *   A VLAN flow spec to apply.
1841  * @param vlan_mask
1842  *   A VLAN flow mask to apply.
1843  *
1844  * @return
1845  *   0 on success, a negative errno value otherwise and rte_errno is set.
1846  */
1847 int
1848 mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev,
1849                     struct rte_flow_item_eth *eth_spec,
1850                     struct rte_flow_item_eth *eth_mask,
1851                     struct rte_flow_item_vlan *vlan_spec,
1852                     struct rte_flow_item_vlan *vlan_mask)
1853 {
1854         struct priv *priv = dev->data->dev_private;
1855         const struct rte_flow_attr attr = {
1856                 .ingress = 1,
1857                 .priority = MLX5_FLOW_PRIO_RSVD,
1858         };
1859         struct rte_flow_item items[] = {
1860                 {
1861                         .type = RTE_FLOW_ITEM_TYPE_ETH,
1862                         .spec = eth_spec,
1863                         .last = NULL,
1864                         .mask = eth_mask,
1865                 },
1866                 {
1867                         .type = (vlan_spec) ? RTE_FLOW_ITEM_TYPE_VLAN :
1868                                               RTE_FLOW_ITEM_TYPE_END,
1869                         .spec = vlan_spec,
1870                         .last = NULL,
1871                         .mask = vlan_mask,
1872                 },
1873                 {
1874                         .type = RTE_FLOW_ITEM_TYPE_END,
1875                 },
1876         };
1877         uint16_t queue[priv->reta_idx_n];
1878         struct rte_flow_action_rss action_rss = {
1879                 .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
1880                 .level = 0,
1881                 .types = priv->rss_conf.rss_hf,
1882                 .key_len = priv->rss_conf.rss_key_len,
1883                 .queue_num = priv->reta_idx_n,
1884                 .key = priv->rss_conf.rss_key,
1885                 .queue = queue,
1886         };
1887         struct rte_flow_action actions[] = {
1888                 {
1889                         .type = RTE_FLOW_ACTION_TYPE_RSS,
1890                         .conf = &action_rss,
1891                 },
1892                 {
1893                         .type = RTE_FLOW_ACTION_TYPE_END,
1894                 },
1895         };
1896         struct rte_flow *flow;
1897         struct rte_flow_error error;
1898         unsigned int i;
1899
1900         if (!priv->reta_idx_n) {
1901                 rte_errno = EINVAL;
1902                 return -rte_errno;
1903         }
1904         for (i = 0; i != priv->reta_idx_n; ++i)
1905                 queue[i] = (*priv->reta_idx)[i];
1906         flow = mlx5_flow_list_create(dev, &priv->ctrl_flows, &attr, items,
1907                                      actions, &error);
1908         if (!flow)
1909                 return -rte_errno;
1910         return 0;
1911 }
1912
1913 /**
1914  * Enable a flow control configured from the control plane.
1915  *
1916  * @param dev
1917  *   Pointer to Ethernet device.
1918  * @param eth_spec
1919  *   An Ethernet flow spec to apply.
1920  * @param eth_mask
1921  *   An Ethernet flow mask to apply.
1922  *
1923  * @return
1924  *   0 on success, a negative errno value otherwise and rte_errno is set.
1925  */
1926 int
1927 mlx5_ctrl_flow(struct rte_eth_dev *dev,
1928                struct rte_flow_item_eth *eth_spec,
1929                struct rte_flow_item_eth *eth_mask)
1930 {
1931         return mlx5_ctrl_flow_vlan(dev, eth_spec, eth_mask, NULL, NULL);
1932 }
1933
1934 /**
1935  * Destroy a flow.
1936  *
1937  * @see rte_flow_destroy()
1938  * @see rte_flow_ops
1939  */
1940 int
1941 mlx5_flow_destroy(struct rte_eth_dev *dev,
1942                   struct rte_flow *flow,
1943                   struct rte_flow_error *error __rte_unused)
1944 {
1945         struct priv *priv = dev->data->dev_private;
1946
1947         mlx5_flow_list_destroy(dev, &priv->flows, flow);
1948         return 0;
1949 }
1950
1951 /**
1952  * Destroy all flows.
1953  *
1954  * @see rte_flow_flush()
1955  * @see rte_flow_ops
1956  */
1957 int
1958 mlx5_flow_flush(struct rte_eth_dev *dev,
1959                 struct rte_flow_error *error __rte_unused)
1960 {
1961         struct priv *priv = dev->data->dev_private;
1962
1963         mlx5_flow_list_flush(dev, &priv->flows);
1964         return 0;
1965 }
1966
1967 /**
1968  * Isolated mode.
1969  *
1970  * @see rte_flow_isolate()
1971  * @see rte_flow_ops
1972  */
1973 int
1974 mlx5_flow_isolate(struct rte_eth_dev *dev,
1975                   int enable,
1976                   struct rte_flow_error *error)
1977 {
1978         struct priv *priv = dev->data->dev_private;
1979
1980         if (dev->data->dev_started) {
1981                 rte_flow_error_set(error, EBUSY,
1982                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1983                                    NULL,
1984                                    "port must be stopped first");
1985                 return -rte_errno;
1986         }
1987         priv->isolated = !!enable;
1988         if (enable)
1989                 dev->dev_ops = &mlx5_dev_ops_isolate;
1990         else
1991                 dev->dev_ops = &mlx5_dev_ops;
1992         return 0;
1993 }
1994
1995 /**
1996  * Query flow counter.
1997  *
1998  * @param flow
1999  *   Pointer to the flow.
2000  *
2001  * @return
2002  *   0 on success, a negative errno value otherwise and rte_errno is set.
2003  */
2004 static int
2005 mlx5_flow_query_count(struct rte_flow *flow __rte_unused,
2006                       void *data __rte_unused,
2007                       struct rte_flow_error *error)
2008 {
2009 #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
2010         if (flow->actions & MLX5_FLOW_ACTION_COUNT) {
2011                 struct rte_flow_query_count *qc = data;
2012                 uint64_t counters[2] = {0, 0};
2013                 struct ibv_query_counter_set_attr query_cs_attr = {
2014                         .cs = flow->counter->cs,
2015                         .query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
2016                 };
2017                 struct ibv_counter_set_data query_out = {
2018                         .out = counters,
2019                         .outlen = 2 * sizeof(uint64_t),
2020                 };
2021                 int err = mlx5_glue->query_counter_set(&query_cs_attr,
2022                                                        &query_out);
2023
2024                 if (err)
2025                         return rte_flow_error_set
2026                                 (error, err,
2027                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2028                                  NULL,
2029                                  "cannot read counter");
2030                 qc->hits_set = 1;
2031                 qc->bytes_set = 1;
2032                 qc->hits = counters[0] - flow->counter->hits;
2033                 qc->bytes = counters[1] - flow->counter->bytes;
2034                 if (qc->reset) {
2035                         flow->counter->hits = counters[0];
2036                         flow->counter->bytes = counters[1];
2037                 }
2038                 return 0;
2039         }
2040         return rte_flow_error_set(error, ENOTSUP,
2041                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2042                                   NULL,
2043                                   "flow does not have counter");
2044 #endif
2045         return rte_flow_error_set(error, ENOTSUP,
2046                                   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2047                                   NULL,
2048                                   "counters are not available");
2049 }
2050
2051 /**
2052  * Query a flows.
2053  *
2054  * @see rte_flow_query()
2055  * @see rte_flow_ops
2056  */
2057 int
2058 mlx5_flow_query(struct rte_eth_dev *dev __rte_unused,
2059                 struct rte_flow *flow,
2060                 const struct rte_flow_action *actions,
2061                 void *data,
2062                 struct rte_flow_error *error)
2063 {
2064         int ret = 0;
2065
2066         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
2067                 switch (actions->type) {
2068                 case RTE_FLOW_ACTION_TYPE_VOID:
2069                         break;
2070                 case RTE_FLOW_ACTION_TYPE_COUNT:
2071                         ret = mlx5_flow_query_count(flow, data, error);
2072                         break;
2073                 default:
2074                         return rte_flow_error_set(error, ENOTSUP,
2075                                                   RTE_FLOW_ERROR_TYPE_ACTION,
2076                                                   actions,
2077                                                   "action not supported");
2078                 }
2079                 if (ret < 0)
2080                         return ret;
2081         }
2082         return 0;
2083 }
2084
2085 /**
2086  * Convert a flow director filter to a generic flow.
2087  *
2088  * @param dev
2089  *   Pointer to Ethernet device.
2090  * @param fdir_filter
2091  *   Flow director filter to add.
2092  * @param attributes
2093  *   Generic flow parameters structure.
2094  *
2095  * @return
2096  *   0 on success, a negative errno value otherwise and rte_errno is set.
2097  */
2098 static int
2099 mlx5_fdir_filter_convert(struct rte_eth_dev *dev,
2100                          const struct rte_eth_fdir_filter *fdir_filter,
2101                          struct mlx5_fdir *attributes)
2102 {
2103         struct priv *priv = dev->data->dev_private;
2104         const struct rte_eth_fdir_input *input = &fdir_filter->input;
2105         const struct rte_eth_fdir_masks *mask =
2106                 &dev->data->dev_conf.fdir_conf.mask;
2107
2108         /* Validate queue number. */
2109         if (fdir_filter->action.rx_queue >= priv->rxqs_n) {
2110                 DRV_LOG(ERR, "port %u invalid queue number %d",
2111                         dev->data->port_id, fdir_filter->action.rx_queue);
2112                 rte_errno = EINVAL;
2113                 return -rte_errno;
2114         }
2115         attributes->attr.ingress = 1;
2116         attributes->items[0] = (struct rte_flow_item) {
2117                 .type = RTE_FLOW_ITEM_TYPE_ETH,
2118                 .spec = &attributes->l2,
2119                 .mask = &attributes->l2_mask,
2120         };
2121         switch (fdir_filter->action.behavior) {
2122         case RTE_ETH_FDIR_ACCEPT:
2123                 attributes->actions[0] = (struct rte_flow_action){
2124                         .type = RTE_FLOW_ACTION_TYPE_QUEUE,
2125                         .conf = &attributes->queue,
2126                 };
2127                 break;
2128         case RTE_ETH_FDIR_REJECT:
2129                 attributes->actions[0] = (struct rte_flow_action){
2130                         .type = RTE_FLOW_ACTION_TYPE_DROP,
2131                 };
2132                 break;
2133         default:
2134                 DRV_LOG(ERR, "port %u invalid behavior %d",
2135                         dev->data->port_id,
2136                         fdir_filter->action.behavior);
2137                 rte_errno = ENOTSUP;
2138                 return -rte_errno;
2139         }
2140         attributes->queue.index = fdir_filter->action.rx_queue;
2141         /* Handle L3. */
2142         switch (fdir_filter->input.flow_type) {
2143         case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
2144         case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
2145         case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
2146                 attributes->l3.ipv4.hdr = (struct ipv4_hdr){
2147                         .src_addr = input->flow.ip4_flow.src_ip,
2148                         .dst_addr = input->flow.ip4_flow.dst_ip,
2149                         .time_to_live = input->flow.ip4_flow.ttl,
2150                         .type_of_service = input->flow.ip4_flow.tos,
2151                 };
2152                 attributes->l3_mask.ipv4.hdr = (struct ipv4_hdr){
2153                         .src_addr = mask->ipv4_mask.src_ip,
2154                         .dst_addr = mask->ipv4_mask.dst_ip,
2155                         .time_to_live = mask->ipv4_mask.ttl,
2156                         .type_of_service = mask->ipv4_mask.tos,
2157                         .next_proto_id = mask->ipv4_mask.proto,
2158                 };
2159                 attributes->items[1] = (struct rte_flow_item){
2160                         .type = RTE_FLOW_ITEM_TYPE_IPV4,
2161                         .spec = &attributes->l3,
2162                         .mask = &attributes->l3_mask,
2163                 };
2164                 break;
2165         case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
2166         case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
2167         case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
2168                 attributes->l3.ipv6.hdr = (struct ipv6_hdr){
2169                         .hop_limits = input->flow.ipv6_flow.hop_limits,
2170                         .proto = input->flow.ipv6_flow.proto,
2171                 };
2172
2173                 memcpy(attributes->l3.ipv6.hdr.src_addr,
2174                        input->flow.ipv6_flow.src_ip,
2175                        RTE_DIM(attributes->l3.ipv6.hdr.src_addr));
2176                 memcpy(attributes->l3.ipv6.hdr.dst_addr,
2177                        input->flow.ipv6_flow.dst_ip,
2178                        RTE_DIM(attributes->l3.ipv6.hdr.src_addr));
2179                 memcpy(attributes->l3_mask.ipv6.hdr.src_addr,
2180                        mask->ipv6_mask.src_ip,
2181                        RTE_DIM(attributes->l3_mask.ipv6.hdr.src_addr));
2182                 memcpy(attributes->l3_mask.ipv6.hdr.dst_addr,
2183                        mask->ipv6_mask.dst_ip,
2184                        RTE_DIM(attributes->l3_mask.ipv6.hdr.src_addr));
2185                 attributes->items[1] = (struct rte_flow_item){
2186                         .type = RTE_FLOW_ITEM_TYPE_IPV6,
2187                         .spec = &attributes->l3,
2188                         .mask = &attributes->l3_mask,
2189                 };
2190                 break;
2191         default:
2192                 DRV_LOG(ERR, "port %u invalid flow type%d",
2193                         dev->data->port_id, fdir_filter->input.flow_type);
2194                 rte_errno = ENOTSUP;
2195                 return -rte_errno;
2196         }
2197         /* Handle L4. */
2198         switch (fdir_filter->input.flow_type) {
2199         case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
2200                 attributes->l4.udp.hdr = (struct udp_hdr){
2201                         .src_port = input->flow.udp4_flow.src_port,
2202                         .dst_port = input->flow.udp4_flow.dst_port,
2203                 };
2204                 attributes->l4_mask.udp.hdr = (struct udp_hdr){
2205                         .src_port = mask->src_port_mask,
2206                         .dst_port = mask->dst_port_mask,
2207                 };
2208                 attributes->items[2] = (struct rte_flow_item){
2209                         .type = RTE_FLOW_ITEM_TYPE_UDP,
2210                         .spec = &attributes->l4,
2211                         .mask = &attributes->l4_mask,
2212                 };
2213                 break;
2214         case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
2215                 attributes->l4.tcp.hdr = (struct tcp_hdr){
2216                         .src_port = input->flow.tcp4_flow.src_port,
2217                         .dst_port = input->flow.tcp4_flow.dst_port,
2218                 };
2219                 attributes->l4_mask.tcp.hdr = (struct tcp_hdr){
2220                         .src_port = mask->src_port_mask,
2221                         .dst_port = mask->dst_port_mask,
2222                 };
2223                 attributes->items[2] = (struct rte_flow_item){
2224                         .type = RTE_FLOW_ITEM_TYPE_TCP,
2225                         .spec = &attributes->l4,
2226                         .mask = &attributes->l4_mask,
2227                 };
2228                 break;
2229         case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
2230                 attributes->l4.udp.hdr = (struct udp_hdr){
2231                         .src_port = input->flow.udp6_flow.src_port,
2232                         .dst_port = input->flow.udp6_flow.dst_port,
2233                 };
2234                 attributes->l4_mask.udp.hdr = (struct udp_hdr){
2235                         .src_port = mask->src_port_mask,
2236                         .dst_port = mask->dst_port_mask,
2237                 };
2238                 attributes->items[2] = (struct rte_flow_item){
2239                         .type = RTE_FLOW_ITEM_TYPE_UDP,
2240                         .spec = &attributes->l4,
2241                         .mask = &attributes->l4_mask,
2242                 };
2243                 break;
2244         case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
2245                 attributes->l4.tcp.hdr = (struct tcp_hdr){
2246                         .src_port = input->flow.tcp6_flow.src_port,
2247                         .dst_port = input->flow.tcp6_flow.dst_port,
2248                 };
2249                 attributes->l4_mask.tcp.hdr = (struct tcp_hdr){
2250                         .src_port = mask->src_port_mask,
2251                         .dst_port = mask->dst_port_mask,
2252                 };
2253                 attributes->items[2] = (struct rte_flow_item){
2254                         .type = RTE_FLOW_ITEM_TYPE_TCP,
2255                         .spec = &attributes->l4,
2256                         .mask = &attributes->l4_mask,
2257                 };
2258                 break;
2259         case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
2260         case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
2261                 break;
2262         default:
2263                 DRV_LOG(ERR, "port %u invalid flow type%d",
2264                         dev->data->port_id, fdir_filter->input.flow_type);
2265                 rte_errno = ENOTSUP;
2266                 return -rte_errno;
2267         }
2268         return 0;
2269 }
2270
2271 /**
2272  * Add new flow director filter and store it in list.
2273  *
2274  * @param dev
2275  *   Pointer to Ethernet device.
2276  * @param fdir_filter
2277  *   Flow director filter to add.
2278  *
2279  * @return
2280  *   0 on success, a negative errno value otherwise and rte_errno is set.
2281  */
2282 static int
2283 mlx5_fdir_filter_add(struct rte_eth_dev *dev,
2284                      const struct rte_eth_fdir_filter *fdir_filter)
2285 {
2286         struct priv *priv = dev->data->dev_private;
2287         struct mlx5_fdir attributes = {
2288                 .attr.group = 0,
2289                 .l2_mask = {
2290                         .dst.addr_bytes = "\x00\x00\x00\x00\x00\x00",
2291                         .src.addr_bytes = "\x00\x00\x00\x00\x00\x00",
2292                         .type = 0,
2293                 },
2294         };
2295         struct rte_flow_error error;
2296         struct rte_flow *flow;
2297         int ret;
2298
2299         ret = mlx5_fdir_filter_convert(dev, fdir_filter, &attributes);
2300         if (ret)
2301                 return ret;
2302         flow = mlx5_flow_list_create(dev, &priv->flows, &attributes.attr,
2303                                      attributes.items, attributes.actions,
2304                                      &error);
2305         if (flow) {
2306                 DRV_LOG(DEBUG, "port %u FDIR created %p", dev->data->port_id,
2307                         (void *)flow);
2308                 return 0;
2309         }
2310         return -rte_errno;
2311 }
2312
2313 /**
2314  * Delete specific filter.
2315  *
2316  * @param dev
2317  *   Pointer to Ethernet device.
2318  * @param fdir_filter
2319  *   Filter to be deleted.
2320  *
2321  * @return
2322  *   0 on success, a negative errno value otherwise and rte_errno is set.
2323  */
2324 static int
2325 mlx5_fdir_filter_delete(struct rte_eth_dev *dev __rte_unused,
2326                         const struct rte_eth_fdir_filter *fdir_filter
2327                         __rte_unused)
2328 {
2329         rte_errno = ENOTSUP;
2330         return -rte_errno;
2331 }
2332
2333 /**
2334  * Update queue for specific filter.
2335  *
2336  * @param dev
2337  *   Pointer to Ethernet device.
2338  * @param fdir_filter
2339  *   Filter to be updated.
2340  *
2341  * @return
2342  *   0 on success, a negative errno value otherwise and rte_errno is set.
2343  */
2344 static int
2345 mlx5_fdir_filter_update(struct rte_eth_dev *dev,
2346                         const struct rte_eth_fdir_filter *fdir_filter)
2347 {
2348         int ret;
2349
2350         ret = mlx5_fdir_filter_delete(dev, fdir_filter);
2351         if (ret)
2352                 return ret;
2353         return mlx5_fdir_filter_add(dev, fdir_filter);
2354 }
2355
2356 /**
2357  * Flush all filters.
2358  *
2359  * @param dev
2360  *   Pointer to Ethernet device.
2361  */
2362 static void
2363 mlx5_fdir_filter_flush(struct rte_eth_dev *dev)
2364 {
2365         struct priv *priv = dev->data->dev_private;
2366
2367         mlx5_flow_list_flush(dev, &priv->flows);
2368 }
2369
2370 /**
2371  * Get flow director information.
2372  *
2373  * @param dev
2374  *   Pointer to Ethernet device.
2375  * @param[out] fdir_info
2376  *   Resulting flow director information.
2377  */
2378 static void
2379 mlx5_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info)
2380 {
2381         struct rte_eth_fdir_masks *mask =
2382                 &dev->data->dev_conf.fdir_conf.mask;
2383
2384         fdir_info->mode = dev->data->dev_conf.fdir_conf.mode;
2385         fdir_info->guarant_spc = 0;
2386         rte_memcpy(&fdir_info->mask, mask, sizeof(fdir_info->mask));
2387         fdir_info->max_flexpayload = 0;
2388         fdir_info->flow_types_mask[0] = 0;
2389         fdir_info->flex_payload_unit = 0;
2390         fdir_info->max_flex_payload_segment_num = 0;
2391         fdir_info->flex_payload_limit = 0;
2392         memset(&fdir_info->flex_conf, 0, sizeof(fdir_info->flex_conf));
2393 }
2394
2395 /**
2396  * Deal with flow director operations.
2397  *
2398  * @param dev
2399  *   Pointer to Ethernet device.
2400  * @param filter_op
2401  *   Operation to perform.
2402  * @param arg
2403  *   Pointer to operation-specific structure.
2404  *
2405  * @return
2406  *   0 on success, a negative errno value otherwise and rte_errno is set.
2407  */
2408 static int
2409 mlx5_fdir_ctrl_func(struct rte_eth_dev *dev, enum rte_filter_op filter_op,
2410                     void *arg)
2411 {
2412         enum rte_fdir_mode fdir_mode =
2413                 dev->data->dev_conf.fdir_conf.mode;
2414
2415         if (filter_op == RTE_ETH_FILTER_NOP)
2416                 return 0;
2417         if (fdir_mode != RTE_FDIR_MODE_PERFECT &&
2418             fdir_mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
2419                 DRV_LOG(ERR, "port %u flow director mode %d not supported",
2420                         dev->data->port_id, fdir_mode);
2421                 rte_errno = EINVAL;
2422                 return -rte_errno;
2423         }
2424         switch (filter_op) {
2425         case RTE_ETH_FILTER_ADD:
2426                 return mlx5_fdir_filter_add(dev, arg);
2427         case RTE_ETH_FILTER_UPDATE:
2428                 return mlx5_fdir_filter_update(dev, arg);
2429         case RTE_ETH_FILTER_DELETE:
2430                 return mlx5_fdir_filter_delete(dev, arg);
2431         case RTE_ETH_FILTER_FLUSH:
2432                 mlx5_fdir_filter_flush(dev);
2433                 break;
2434         case RTE_ETH_FILTER_INFO:
2435                 mlx5_fdir_info_get(dev, arg);
2436                 break;
2437         default:
2438                 DRV_LOG(DEBUG, "port %u unknown operation %u",
2439                         dev->data->port_id, filter_op);
2440                 rte_errno = EINVAL;
2441                 return -rte_errno;
2442         }
2443         return 0;
2444 }
2445
2446 /**
2447  * Manage filter operations.
2448  *
2449  * @param dev
2450  *   Pointer to Ethernet device structure.
2451  * @param filter_type
2452  *   Filter type.
2453  * @param filter_op
2454  *   Operation to perform.
2455  * @param arg
2456  *   Pointer to operation-specific structure.
2457  *
2458  * @return
2459  *   0 on success, a negative errno value otherwise and rte_errno is set.
2460  */
2461 int
2462 mlx5_dev_filter_ctrl(struct rte_eth_dev *dev,
2463                      enum rte_filter_type filter_type,
2464                      enum rte_filter_op filter_op,
2465                      void *arg)
2466 {
2467         switch (filter_type) {
2468         case RTE_ETH_FILTER_GENERIC:
2469                 if (filter_op != RTE_ETH_FILTER_GET) {
2470                         rte_errno = EINVAL;
2471                         return -rte_errno;
2472                 }
2473                 *(const void **)arg = &mlx5_flow_ops;
2474                 return 0;
2475         case RTE_ETH_FILTER_FDIR:
2476                 return mlx5_fdir_ctrl_func(dev, filter_op, arg);
2477         default:
2478                 DRV_LOG(ERR, "port %u filter type (%d) not supported",
2479                         dev->data->port_id, filter_type);
2480                 rte_errno = ENOTSUP;
2481                 return -rte_errno;
2482         }
2483         return 0;
2484 }
2485
2486 /**
2487  * Init the driver ops structure.
2488  *
2489  * @param dev
2490  *   Pointer to Ethernet device structure.
2491  */
2492 void
2493 mlx5_flow_init_driver_ops(struct rte_eth_dev *dev)
2494 {
2495         struct priv *priv __rte_unused = dev->data->dev_private;
2496
2497 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
2498         if (priv->config.dv_flow_en)
2499                 mlx5_flow_dv_get_driver_ops(&nic_ops);
2500         else
2501                 mlx5_flow_verbs_get_driver_ops(&nic_ops);
2502 #else
2503         mlx5_flow_verbs_get_driver_ops(&nic_ops);
2504 #endif
2505 }