New upstream version 18.08
[deb_dpdk.git] / drivers / net / mvpp2 / mrvl_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Marvell International Ltd.
3  * Copyright(c) 2018 Semihalf.
4  * All rights reserved.
5  */
6
7 #include <rte_flow.h>
8 #include <rte_flow_driver.h>
9 #include <rte_malloc.h>
10 #include <rte_log.h>
11
12 #include <arpa/inet.h>
13
14 #ifdef container_of
15 #undef container_of
16 #endif
17
18 #include "mrvl_ethdev.h"
19 #include "mrvl_qos.h"
20 #include "env/mv_common.h" /* for BIT() */
21
22 /** Number of rules in the classifier table. */
23 #define MRVL_CLS_MAX_NUM_RULES 20
24
25 /** Size of the classifier key and mask strings. */
26 #define MRVL_CLS_STR_SIZE_MAX 40
27
28 /** Parsed fields in processed rte_flow_item. */
29 enum mrvl_parsed_fields {
30         /* eth flags */
31         F_DMAC =         BIT(0),
32         F_SMAC =         BIT(1),
33         F_TYPE =         BIT(2),
34         /* vlan flags */
35         F_VLAN_ID =      BIT(3),
36         F_VLAN_PRI =     BIT(4),
37         F_VLAN_TCI =     BIT(5), /* not supported by MUSDK yet */
38         /* ip4 flags */
39         F_IP4_TOS =      BIT(6),
40         F_IP4_SIP =      BIT(7),
41         F_IP4_DIP =      BIT(8),
42         F_IP4_PROTO =    BIT(9),
43         /* ip6 flags */
44         F_IP6_TC =       BIT(10), /* not supported by MUSDK yet */
45         F_IP6_SIP =      BIT(11),
46         F_IP6_DIP =      BIT(12),
47         F_IP6_FLOW =     BIT(13),
48         F_IP6_NEXT_HDR = BIT(14),
49         /* tcp flags */
50         F_TCP_SPORT =    BIT(15),
51         F_TCP_DPORT =    BIT(16),
52         /* udp flags */
53         F_UDP_SPORT =    BIT(17),
54         F_UDP_DPORT =    BIT(18),
55 };
56
57 /** PMD-specific definition of a flow rule handle. */
58 struct rte_flow {
59         LIST_ENTRY(rte_flow) next;
60
61         enum mrvl_parsed_fields pattern;
62
63         struct pp2_cls_tbl_rule rule;
64         struct pp2_cls_cos_desc cos;
65         struct pp2_cls_tbl_action action;
66 };
67
68 static const enum rte_flow_item_type pattern_eth[] = {
69         RTE_FLOW_ITEM_TYPE_ETH,
70         RTE_FLOW_ITEM_TYPE_END
71 };
72
73 static const enum rte_flow_item_type pattern_eth_vlan[] = {
74         RTE_FLOW_ITEM_TYPE_ETH,
75         RTE_FLOW_ITEM_TYPE_VLAN,
76         RTE_FLOW_ITEM_TYPE_END
77 };
78
79 static const enum rte_flow_item_type pattern_eth_vlan_ip[] = {
80         RTE_FLOW_ITEM_TYPE_ETH,
81         RTE_FLOW_ITEM_TYPE_VLAN,
82         RTE_FLOW_ITEM_TYPE_IPV4,
83         RTE_FLOW_ITEM_TYPE_END
84 };
85
86 static const enum rte_flow_item_type pattern_eth_vlan_ip6[] = {
87         RTE_FLOW_ITEM_TYPE_ETH,
88         RTE_FLOW_ITEM_TYPE_VLAN,
89         RTE_FLOW_ITEM_TYPE_IPV6,
90         RTE_FLOW_ITEM_TYPE_END
91 };
92
93 static const enum rte_flow_item_type pattern_eth_ip4[] = {
94         RTE_FLOW_ITEM_TYPE_ETH,
95         RTE_FLOW_ITEM_TYPE_IPV4,
96         RTE_FLOW_ITEM_TYPE_END
97 };
98
99 static const enum rte_flow_item_type pattern_eth_ip4_tcp[] = {
100         RTE_FLOW_ITEM_TYPE_ETH,
101         RTE_FLOW_ITEM_TYPE_IPV4,
102         RTE_FLOW_ITEM_TYPE_TCP,
103         RTE_FLOW_ITEM_TYPE_END
104 };
105
106 static const enum rte_flow_item_type pattern_eth_ip4_udp[] = {
107         RTE_FLOW_ITEM_TYPE_ETH,
108         RTE_FLOW_ITEM_TYPE_IPV4,
109         RTE_FLOW_ITEM_TYPE_UDP,
110         RTE_FLOW_ITEM_TYPE_END
111 };
112
113 static const enum rte_flow_item_type pattern_eth_ip6[] = {
114         RTE_FLOW_ITEM_TYPE_ETH,
115         RTE_FLOW_ITEM_TYPE_IPV6,
116         RTE_FLOW_ITEM_TYPE_END
117 };
118
119 static const enum rte_flow_item_type pattern_eth_ip6_tcp[] = {
120         RTE_FLOW_ITEM_TYPE_ETH,
121         RTE_FLOW_ITEM_TYPE_IPV6,
122         RTE_FLOW_ITEM_TYPE_TCP,
123         RTE_FLOW_ITEM_TYPE_END
124 };
125
126 static const enum rte_flow_item_type pattern_eth_ip6_udp[] = {
127         RTE_FLOW_ITEM_TYPE_ETH,
128         RTE_FLOW_ITEM_TYPE_IPV6,
129         RTE_FLOW_ITEM_TYPE_UDP,
130         RTE_FLOW_ITEM_TYPE_END
131 };
132
133 static const enum rte_flow_item_type pattern_vlan[] = {
134         RTE_FLOW_ITEM_TYPE_VLAN,
135         RTE_FLOW_ITEM_TYPE_END
136 };
137
138 static const enum rte_flow_item_type pattern_vlan_ip[] = {
139         RTE_FLOW_ITEM_TYPE_VLAN,
140         RTE_FLOW_ITEM_TYPE_IPV4,
141         RTE_FLOW_ITEM_TYPE_END
142 };
143
144 static const enum rte_flow_item_type pattern_vlan_ip_tcp[] = {
145         RTE_FLOW_ITEM_TYPE_VLAN,
146         RTE_FLOW_ITEM_TYPE_IPV4,
147         RTE_FLOW_ITEM_TYPE_TCP,
148         RTE_FLOW_ITEM_TYPE_END
149 };
150
151 static const enum rte_flow_item_type pattern_vlan_ip_udp[] = {
152         RTE_FLOW_ITEM_TYPE_VLAN,
153         RTE_FLOW_ITEM_TYPE_IPV4,
154         RTE_FLOW_ITEM_TYPE_UDP,
155         RTE_FLOW_ITEM_TYPE_END
156 };
157
158 static const enum rte_flow_item_type pattern_vlan_ip6[] = {
159         RTE_FLOW_ITEM_TYPE_VLAN,
160         RTE_FLOW_ITEM_TYPE_IPV6,
161         RTE_FLOW_ITEM_TYPE_END
162 };
163
164 static const enum rte_flow_item_type pattern_vlan_ip6_tcp[] = {
165         RTE_FLOW_ITEM_TYPE_VLAN,
166         RTE_FLOW_ITEM_TYPE_IPV6,
167         RTE_FLOW_ITEM_TYPE_TCP,
168         RTE_FLOW_ITEM_TYPE_END
169 };
170
171 static const enum rte_flow_item_type pattern_vlan_ip6_udp[] = {
172         RTE_FLOW_ITEM_TYPE_VLAN,
173         RTE_FLOW_ITEM_TYPE_IPV6,
174         RTE_FLOW_ITEM_TYPE_UDP,
175         RTE_FLOW_ITEM_TYPE_END
176 };
177
178 static const enum rte_flow_item_type pattern_ip[] = {
179         RTE_FLOW_ITEM_TYPE_IPV4,
180         RTE_FLOW_ITEM_TYPE_END
181 };
182
183 static const enum rte_flow_item_type pattern_ip6[] = {
184         RTE_FLOW_ITEM_TYPE_IPV6,
185         RTE_FLOW_ITEM_TYPE_END
186 };
187
188 static const enum rte_flow_item_type pattern_ip_tcp[] = {
189         RTE_FLOW_ITEM_TYPE_IPV4,
190         RTE_FLOW_ITEM_TYPE_TCP,
191         RTE_FLOW_ITEM_TYPE_END
192 };
193
194 static const enum rte_flow_item_type pattern_ip6_tcp[] = {
195         RTE_FLOW_ITEM_TYPE_IPV6,
196         RTE_FLOW_ITEM_TYPE_TCP,
197         RTE_FLOW_ITEM_TYPE_END
198 };
199
200 static const enum rte_flow_item_type pattern_ip_udp[] = {
201         RTE_FLOW_ITEM_TYPE_IPV4,
202         RTE_FLOW_ITEM_TYPE_UDP,
203         RTE_FLOW_ITEM_TYPE_END
204 };
205
206 static const enum rte_flow_item_type pattern_ip6_udp[] = {
207         RTE_FLOW_ITEM_TYPE_IPV6,
208         RTE_FLOW_ITEM_TYPE_UDP,
209         RTE_FLOW_ITEM_TYPE_END
210 };
211
212 static const enum rte_flow_item_type pattern_tcp[] = {
213         RTE_FLOW_ITEM_TYPE_TCP,
214         RTE_FLOW_ITEM_TYPE_END
215 };
216
217 static const enum rte_flow_item_type pattern_udp[] = {
218         RTE_FLOW_ITEM_TYPE_UDP,
219         RTE_FLOW_ITEM_TYPE_END
220 };
221
222 #define MRVL_VLAN_ID_MASK 0x0fff
223 #define MRVL_VLAN_PRI_MASK 0x7000
224 #define MRVL_IPV4_DSCP_MASK 0xfc
225 #define MRVL_IPV4_ADDR_MASK 0xffffffff
226 #define MRVL_IPV6_FLOW_MASK 0x0fffff
227
228 /**
229  * Given a flow item, return the next non-void one.
230  *
231  * @param items Pointer to the item in the table.
232  * @returns Next not-void item, NULL otherwise.
233  */
234 static const struct rte_flow_item *
235 mrvl_next_item(const struct rte_flow_item *items)
236 {
237         const struct rte_flow_item *item = items;
238
239         for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
240                 if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
241                         return item;
242         }
243
244         return NULL;
245 }
246
247 /**
248  * Allocate memory for classifier rule key and mask fields.
249  *
250  * @param field Pointer to the classifier rule.
251  * @returns 0 in case of success, negative value otherwise.
252  */
253 static int
254 mrvl_alloc_key_mask(struct pp2_cls_rule_key_field *field)
255 {
256         unsigned int id = rte_socket_id();
257
258         field->key = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id);
259         if (!field->key)
260                 goto out;
261
262         field->mask = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id);
263         if (!field->mask)
264                 goto out_mask;
265
266         return 0;
267 out_mask:
268         rte_free(field->key);
269 out:
270         field->key = NULL;
271         field->mask = NULL;
272         return -1;
273 }
274
275 /**
276  * Free memory allocated for classifier rule key and mask fields.
277  *
278  * @param field Pointer to the classifier rule.
279  */
280 static void
281 mrvl_free_key_mask(struct pp2_cls_rule_key_field *field)
282 {
283         rte_free(field->key);
284         rte_free(field->mask);
285         field->key = NULL;
286         field->mask = NULL;
287 }
288
289 /**
290  * Free memory allocated for all classifier rule key and mask fields.
291  *
292  * @param rule Pointer to the classifier table rule.
293  */
294 static void
295 mrvl_free_all_key_mask(struct pp2_cls_tbl_rule *rule)
296 {
297         int i;
298
299         for (i = 0; i < rule->num_fields; i++)
300                 mrvl_free_key_mask(&rule->fields[i]);
301         rule->num_fields = 0;
302 }
303
304 /*
305  * Initialize rte flow item parsing.
306  *
307  * @param item Pointer to the flow item.
308  * @param spec_ptr Pointer to the specific item pointer.
309  * @param mask_ptr Pointer to the specific item's mask pointer.
310  * @def_mask Pointer to the default mask.
311  * @size Size of the flow item.
312  * @error Pointer to the rte flow error.
313  * @returns 0 in case of success, negative value otherwise.
314  */
315 static int
316 mrvl_parse_init(const struct rte_flow_item *item,
317                 const void **spec_ptr,
318                 const void **mask_ptr,
319                 const void *def_mask,
320                 unsigned int size,
321                 struct rte_flow_error *error)
322 {
323         const uint8_t *spec;
324         const uint8_t *mask;
325         const uint8_t *last;
326         uint8_t zeros[size];
327
328         memset(zeros, 0, size);
329
330         if (item == NULL) {
331                 rte_flow_error_set(error, EINVAL,
332                                    RTE_FLOW_ERROR_TYPE_ITEM, NULL,
333                                    "NULL item\n");
334                 return -rte_errno;
335         }
336
337         if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) {
338                 rte_flow_error_set(error, EINVAL,
339                                    RTE_FLOW_ERROR_TYPE_ITEM, item,
340                                    "Mask or last is set without spec\n");
341                 return -rte_errno;
342         }
343
344         /*
345          * If "mask" is not set, default mask is used,
346          * but if default mask is NULL, "mask" should be set.
347          */
348         if (item->mask == NULL) {
349                 if (def_mask == NULL) {
350                         rte_flow_error_set(error, EINVAL,
351                                            RTE_FLOW_ERROR_TYPE_ITEM, NULL,
352                                            "Mask should be specified\n");
353                         return -rte_errno;
354                 }
355
356                 mask = (const uint8_t *)def_mask;
357         } else {
358                 mask = (const uint8_t *)item->mask;
359         }
360
361         spec = (const uint8_t *)item->spec;
362         last = (const uint8_t *)item->last;
363
364         if (spec == NULL) {
365                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
366                                    NULL, "Spec should be specified\n");
367                 return -rte_errno;
368         }
369
370         /*
371          * If field values in "last" are either 0 or equal to the corresponding
372          * values in "spec" then they are ignored.
373          */
374         if (last != NULL &&
375             !memcmp(last, zeros, size) &&
376             memcmp(last, spec, size) != 0) {
377                 rte_flow_error_set(error, ENOTSUP,
378                                    RTE_FLOW_ERROR_TYPE_ITEM, NULL,
379                                    "Ranging is not supported\n");
380                 return -rte_errno;
381         }
382
383         *spec_ptr = spec;
384         *mask_ptr = mask;
385
386         return 0;
387 }
388
389 /**
390  * Parse the eth flow item.
391  *
392  * This will create classifier rule that matches either destination or source
393  * mac.
394  *
395  * @param spec Pointer to the specific flow item.
396  * @param mask Pointer to the specific flow item's mask.
397  * @param mask Pointer to the flow.
398  * @return 0 in case of success, negative error value otherwise.
399  */
400 static int
401 mrvl_parse_mac(const struct rte_flow_item_eth *spec,
402                const struct rte_flow_item_eth *mask,
403                int parse_dst, struct rte_flow *flow)
404 {
405         struct pp2_cls_rule_key_field *key_field;
406         const uint8_t *k, *m;
407
408         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
409                 return -ENOSPC;
410
411         if (parse_dst) {
412                 k = spec->dst.addr_bytes;
413                 m = mask->dst.addr_bytes;
414
415                 flow->pattern |= F_DMAC;
416         } else {
417                 k = spec->src.addr_bytes;
418                 m = mask->src.addr_bytes;
419
420                 flow->pattern |= F_SMAC;
421         }
422
423         key_field = &flow->rule.fields[flow->rule.num_fields];
424         mrvl_alloc_key_mask(key_field);
425         key_field->size = 6;
426
427         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX,
428                  "%02x:%02x:%02x:%02x:%02x:%02x",
429                  k[0], k[1], k[2], k[3], k[4], k[5]);
430
431         snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX,
432                  "%02x:%02x:%02x:%02x:%02x:%02x",
433                  m[0], m[1], m[2], m[3], m[4], m[5]);
434
435         flow->rule.num_fields += 1;
436
437         return 0;
438 }
439
440 /**
441  * Helper for parsing the eth flow item destination mac address.
442  *
443  * @param spec Pointer to the specific flow item.
444  * @param mask Pointer to the specific flow item's mask.
445  * @param flow Pointer to the flow.
446  * @return 0 in case of success, negative error value otherwise.
447  */
448 static inline int
449 mrvl_parse_dmac(const struct rte_flow_item_eth *spec,
450                 const struct rte_flow_item_eth *mask,
451                 struct rte_flow *flow)
452 {
453         return mrvl_parse_mac(spec, mask, 1, flow);
454 }
455
456 /**
457  * Helper for parsing the eth flow item source mac address.
458  *
459  * @param spec Pointer to the specific flow item.
460  * @param mask Pointer to the specific flow item's mask.
461  * @param flow Pointer to the flow.
462  * @return 0 in case of success, negative error value otherwise.
463  */
464 static inline int
465 mrvl_parse_smac(const struct rte_flow_item_eth *spec,
466                 const struct rte_flow_item_eth *mask,
467                 struct rte_flow *flow)
468 {
469         return mrvl_parse_mac(spec, mask, 0, flow);
470 }
471
472 /**
473  * Parse the ether type field of the eth flow item.
474  *
475  * @param spec Pointer to the specific flow item.
476  * @param mask Pointer to the specific flow item's mask.
477  * @param flow Pointer to the flow.
478  * @return 0 in case of success, negative error value otherwise.
479  */
480 static int
481 mrvl_parse_type(const struct rte_flow_item_eth *spec,
482                 const struct rte_flow_item_eth *mask __rte_unused,
483                 struct rte_flow *flow)
484 {
485         struct pp2_cls_rule_key_field *key_field;
486         uint16_t k;
487
488         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
489                 return -ENOSPC;
490
491         key_field = &flow->rule.fields[flow->rule.num_fields];
492         mrvl_alloc_key_mask(key_field);
493         key_field->size = 2;
494
495         k = rte_be_to_cpu_16(spec->type);
496         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
497
498         flow->pattern |= F_TYPE;
499         flow->rule.num_fields += 1;
500
501         return 0;
502 }
503
504 /**
505  * Parse the vid field of the vlan rte flow item.
506  *
507  * This will create classifier rule that matches vid.
508  *
509  * @param spec Pointer to the specific flow item.
510  * @param mask Pointer to the specific flow item's mask.
511  * @param flow Pointer to the flow.
512  * @return 0 in case of success, negative error value otherwise.
513  */
514 static int
515 mrvl_parse_vlan_id(const struct rte_flow_item_vlan *spec,
516                    const struct rte_flow_item_vlan *mask __rte_unused,
517                    struct rte_flow *flow)
518 {
519         struct pp2_cls_rule_key_field *key_field;
520         uint16_t k;
521
522         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
523                 return -ENOSPC;
524
525         key_field = &flow->rule.fields[flow->rule.num_fields];
526         mrvl_alloc_key_mask(key_field);
527         key_field->size = 2;
528
529         k = rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_ID_MASK;
530         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
531
532         flow->pattern |= F_VLAN_ID;
533         flow->rule.num_fields += 1;
534
535         return 0;
536 }
537
538 /**
539  * Parse the pri field of the vlan rte flow item.
540  *
541  * This will create classifier rule that matches pri.
542  *
543  * @param spec Pointer to the specific flow item.
544  * @param mask Pointer to the specific flow item's mask.
545  * @param flow Pointer to the flow.
546  * @return 0 in case of success, negative error value otherwise.
547  */
548 static int
549 mrvl_parse_vlan_pri(const struct rte_flow_item_vlan *spec,
550                     const struct rte_flow_item_vlan *mask __rte_unused,
551                     struct rte_flow *flow)
552 {
553         struct pp2_cls_rule_key_field *key_field;
554         uint16_t k;
555
556         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
557                 return -ENOSPC;
558
559         key_field = &flow->rule.fields[flow->rule.num_fields];
560         mrvl_alloc_key_mask(key_field);
561         key_field->size = 1;
562
563         k = (rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_PRI_MASK) >> 13;
564         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
565
566         flow->pattern |= F_VLAN_PRI;
567         flow->rule.num_fields += 1;
568
569         return 0;
570 }
571
572 /**
573  * Parse the dscp field of the ipv4 rte flow item.
574  *
575  * This will create classifier rule that matches dscp field.
576  *
577  * @param spec Pointer to the specific flow item.
578  * @param mask Pointer to the specific flow item's mask.
579  * @param flow Pointer to the flow.
580  * @return 0 in case of success, negative error value otherwise.
581  */
582 static int
583 mrvl_parse_ip4_dscp(const struct rte_flow_item_ipv4 *spec,
584                     const struct rte_flow_item_ipv4 *mask,
585                     struct rte_flow *flow)
586 {
587         struct pp2_cls_rule_key_field *key_field;
588         uint8_t k, m;
589
590         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
591                 return -ENOSPC;
592
593         key_field = &flow->rule.fields[flow->rule.num_fields];
594         mrvl_alloc_key_mask(key_field);
595         key_field->size = 1;
596
597         k = (spec->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2;
598         m = (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2;
599         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
600         snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m);
601
602         flow->pattern |= F_IP4_TOS;
603         flow->rule.num_fields += 1;
604
605         return 0;
606 }
607
608 /**
609  * Parse either source or destination ip addresses of the ipv4 flow item.
610  *
611  * This will create classifier rule that matches either destination
612  * or source ip field.
613  *
614  * @param spec Pointer to the specific flow item.
615  * @param mask Pointer to the specific flow item's mask.
616  * @param flow Pointer to the flow.
617  * @return 0 in case of success, negative error value otherwise.
618  */
619 static int
620 mrvl_parse_ip4_addr(const struct rte_flow_item_ipv4 *spec,
621                     const struct rte_flow_item_ipv4 *mask,
622                     int parse_dst, struct rte_flow *flow)
623 {
624         struct pp2_cls_rule_key_field *key_field;
625         struct in_addr k;
626         uint32_t m;
627
628         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
629                 return -ENOSPC;
630
631         memset(&k, 0, sizeof(k));
632         if (parse_dst) {
633                 k.s_addr = spec->hdr.dst_addr;
634                 m = rte_be_to_cpu_32(mask->hdr.dst_addr);
635
636                 flow->pattern |= F_IP4_DIP;
637         } else {
638                 k.s_addr = spec->hdr.src_addr;
639                 m = rte_be_to_cpu_32(mask->hdr.src_addr);
640
641                 flow->pattern |= F_IP4_SIP;
642         }
643
644         key_field = &flow->rule.fields[flow->rule.num_fields];
645         mrvl_alloc_key_mask(key_field);
646         key_field->size = 4;
647
648         inet_ntop(AF_INET, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX);
649         snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "0x%x", m);
650
651         flow->rule.num_fields += 1;
652
653         return 0;
654 }
655
656 /**
657  * Helper for parsing destination ip of the ipv4 flow item.
658  *
659  * @param spec Pointer to the specific flow item.
660  * @param mask Pointer to the specific flow item's mask.
661  * @param flow Pointer to the flow.
662  * @return 0 in case of success, negative error value otherwise.
663  */
664 static inline int
665 mrvl_parse_ip4_dip(const struct rte_flow_item_ipv4 *spec,
666                    const struct rte_flow_item_ipv4 *mask,
667                    struct rte_flow *flow)
668 {
669         return mrvl_parse_ip4_addr(spec, mask, 1, flow);
670 }
671
672 /**
673  * Helper for parsing source ip of the ipv4 flow item.
674  *
675  * @param spec Pointer to the specific flow item.
676  * @param mask Pointer to the specific flow item's mask.
677  * @param flow Pointer to the flow.
678  * @return 0 in case of success, negative error value otherwise.
679  */
680 static inline int
681 mrvl_parse_ip4_sip(const struct rte_flow_item_ipv4 *spec,
682                    const struct rte_flow_item_ipv4 *mask,
683                    struct rte_flow *flow)
684 {
685         return mrvl_parse_ip4_addr(spec, mask, 0, flow);
686 }
687
688 /**
689  * Parse the proto field of the ipv4 rte flow item.
690  *
691  * This will create classifier rule that matches proto field.
692  *
693  * @param spec Pointer to the specific flow item.
694  * @param mask Pointer to the specific flow item's mask.
695  * @param flow Pointer to the flow.
696  * @return 0 in case of success, negative error value otherwise.
697  */
698 static int
699 mrvl_parse_ip4_proto(const struct rte_flow_item_ipv4 *spec,
700                      const struct rte_flow_item_ipv4 *mask __rte_unused,
701                      struct rte_flow *flow)
702 {
703         struct pp2_cls_rule_key_field *key_field;
704         uint8_t k = spec->hdr.next_proto_id;
705
706         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
707                 return -ENOSPC;
708
709         key_field = &flow->rule.fields[flow->rule.num_fields];
710         mrvl_alloc_key_mask(key_field);
711         key_field->size = 1;
712
713         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
714
715         flow->pattern |= F_IP4_PROTO;
716         flow->rule.num_fields += 1;
717
718         return 0;
719 }
720
721 /**
722  * Parse either source or destination ip addresses of the ipv6 rte flow item.
723  *
724  * This will create classifier rule that matches either destination
725  * or source ip field.
726  *
727  * @param spec Pointer to the specific flow item.
728  * @param mask Pointer to the specific flow item's mask.
729  * @param flow Pointer to the flow.
730  * @return 0 in case of success, negative error value otherwise.
731  */
732 static int
733 mrvl_parse_ip6_addr(const struct rte_flow_item_ipv6 *spec,
734                const struct rte_flow_item_ipv6 *mask,
735                int parse_dst, struct rte_flow *flow)
736 {
737         struct pp2_cls_rule_key_field *key_field;
738         int size = sizeof(spec->hdr.dst_addr);
739         struct in6_addr k, m;
740
741         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
742                 return -ENOSPC;
743
744         memset(&k, 0, sizeof(k));
745         if (parse_dst) {
746                 memcpy(k.s6_addr, spec->hdr.dst_addr, size);
747                 memcpy(m.s6_addr, mask->hdr.dst_addr, size);
748
749                 flow->pattern |= F_IP6_DIP;
750         } else {
751                 memcpy(k.s6_addr, spec->hdr.src_addr, size);
752                 memcpy(m.s6_addr, mask->hdr.src_addr, size);
753
754                 flow->pattern |= F_IP6_SIP;
755         }
756
757         key_field = &flow->rule.fields[flow->rule.num_fields];
758         mrvl_alloc_key_mask(key_field);
759         key_field->size = 16;
760
761         inet_ntop(AF_INET6, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX);
762         inet_ntop(AF_INET6, &m, (char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX);
763
764         flow->rule.num_fields += 1;
765
766         return 0;
767 }
768
769 /**
770  * Helper for parsing destination ip of the ipv6 flow item.
771  *
772  * @param spec Pointer to the specific flow item.
773  * @param mask Pointer to the specific flow item's mask.
774  * @param flow Pointer to the flow.
775  * @return 0 in case of success, negative error value otherwise.
776  */
777 static inline int
778 mrvl_parse_ip6_dip(const struct rte_flow_item_ipv6 *spec,
779                    const struct rte_flow_item_ipv6 *mask,
780                    struct rte_flow *flow)
781 {
782         return mrvl_parse_ip6_addr(spec, mask, 1, flow);
783 }
784
785 /**
786  * Helper for parsing source ip of the ipv6 flow item.
787  *
788  * @param spec Pointer to the specific flow item.
789  * @param mask Pointer to the specific flow item's mask.
790  * @param flow Pointer to the flow.
791  * @return 0 in case of success, negative error value otherwise.
792  */
793 static inline int
794 mrvl_parse_ip6_sip(const struct rte_flow_item_ipv6 *spec,
795                    const struct rte_flow_item_ipv6 *mask,
796                    struct rte_flow *flow)
797 {
798         return mrvl_parse_ip6_addr(spec, mask, 0, flow);
799 }
800
801 /**
802  * Parse the flow label of the ipv6 flow item.
803  *
804  * This will create classifier rule that matches flow field.
805  *
806  * @param spec Pointer to the specific flow item.
807  * @param mask Pointer to the specific flow item's mask.
808  * @param flow Pointer to the flow.
809  * @return 0 in case of success, negative error value otherwise.
810  */
811 static int
812 mrvl_parse_ip6_flow(const struct rte_flow_item_ipv6 *spec,
813                     const struct rte_flow_item_ipv6 *mask,
814                     struct rte_flow *flow)
815 {
816         struct pp2_cls_rule_key_field *key_field;
817         uint32_t k = rte_be_to_cpu_32(spec->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK,
818                  m = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK;
819
820         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
821                 return -ENOSPC;
822
823         key_field = &flow->rule.fields[flow->rule.num_fields];
824         mrvl_alloc_key_mask(key_field);
825         key_field->size = 3;
826
827         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
828         snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m);
829
830         flow->pattern |= F_IP6_FLOW;
831         flow->rule.num_fields += 1;
832
833         return 0;
834 }
835
836 /**
837  * Parse the next header of the ipv6 flow item.
838  *
839  * This will create classifier rule that matches next header field.
840  *
841  * @param spec Pointer to the specific flow item.
842  * @param mask Pointer to the specific flow item's mask.
843  * @param flow Pointer to the flow.
844  * @return 0 in case of success, negative error value otherwise.
845  */
846 static int
847 mrvl_parse_ip6_next_hdr(const struct rte_flow_item_ipv6 *spec,
848                         const struct rte_flow_item_ipv6 *mask __rte_unused,
849                         struct rte_flow *flow)
850 {
851         struct pp2_cls_rule_key_field *key_field;
852         uint8_t k = spec->hdr.proto;
853
854         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
855                 return -ENOSPC;
856
857         key_field = &flow->rule.fields[flow->rule.num_fields];
858         mrvl_alloc_key_mask(key_field);
859         key_field->size = 1;
860
861         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
862
863         flow->pattern |= F_IP6_NEXT_HDR;
864         flow->rule.num_fields += 1;
865
866         return 0;
867 }
868
869 /**
870  * Parse destination or source port of the tcp flow item.
871  *
872  * This will create classifier rule that matches either destination or
873  * source tcp port.
874  *
875  * @param spec Pointer to the specific flow item.
876  * @param mask Pointer to the specific flow item's mask.
877  * @param flow Pointer to the flow.
878  * @return 0 in case of success, negative error value otherwise.
879  */
880 static int
881 mrvl_parse_tcp_port(const struct rte_flow_item_tcp *spec,
882                     const struct rte_flow_item_tcp *mask __rte_unused,
883                     int parse_dst, struct rte_flow *flow)
884 {
885         struct pp2_cls_rule_key_field *key_field;
886         uint16_t k;
887
888         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
889                 return -ENOSPC;
890
891         key_field = &flow->rule.fields[flow->rule.num_fields];
892         mrvl_alloc_key_mask(key_field);
893         key_field->size = 2;
894
895         if (parse_dst) {
896                 k = rte_be_to_cpu_16(spec->hdr.dst_port);
897
898                 flow->pattern |= F_TCP_DPORT;
899         } else {
900                 k = rte_be_to_cpu_16(spec->hdr.src_port);
901
902                 flow->pattern |= F_TCP_SPORT;
903         }
904
905         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
906
907         flow->rule.num_fields += 1;
908
909         return 0;
910 }
911
912 /**
913  * Helper for parsing the tcp source port of the tcp flow item.
914  *
915  * @param spec Pointer to the specific flow item.
916  * @param mask Pointer to the specific flow item's mask.
917  * @param flow Pointer to the flow.
918  * @return 0 in case of success, negative error value otherwise.
919  */
920 static inline int
921 mrvl_parse_tcp_sport(const struct rte_flow_item_tcp *spec,
922                      const struct rte_flow_item_tcp *mask,
923                      struct rte_flow *flow)
924 {
925         return mrvl_parse_tcp_port(spec, mask, 0, flow);
926 }
927
928 /**
929  * Helper for parsing the tcp destination port of the tcp flow item.
930  *
931  * @param spec Pointer to the specific flow item.
932  * @param mask Pointer to the specific flow item's mask.
933  * @param flow Pointer to the flow.
934  * @return 0 in case of success, negative error value otherwise.
935  */
936 static inline int
937 mrvl_parse_tcp_dport(const struct rte_flow_item_tcp *spec,
938                      const struct rte_flow_item_tcp *mask,
939                      struct rte_flow *flow)
940 {
941         return mrvl_parse_tcp_port(spec, mask, 1, flow);
942 }
943
944 /**
945  * Parse destination or source port of the udp flow item.
946  *
947  * This will create classifier rule that matches either destination or
948  * source udp port.
949  *
950  * @param spec Pointer to the specific flow item.
951  * @param mask Pointer to the specific flow item's mask.
952  * @param flow Pointer to the flow.
953  * @return 0 in case of success, negative error value otherwise.
954  */
955 static int
956 mrvl_parse_udp_port(const struct rte_flow_item_udp *spec,
957                     const struct rte_flow_item_udp *mask __rte_unused,
958                     int parse_dst, struct rte_flow *flow)
959 {
960         struct pp2_cls_rule_key_field *key_field;
961         uint16_t k;
962
963         if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
964                 return -ENOSPC;
965
966         key_field = &flow->rule.fields[flow->rule.num_fields];
967         mrvl_alloc_key_mask(key_field);
968         key_field->size = 2;
969
970         if (parse_dst) {
971                 k = rte_be_to_cpu_16(spec->hdr.dst_port);
972
973                 flow->pattern |= F_UDP_DPORT;
974         } else {
975                 k = rte_be_to_cpu_16(spec->hdr.src_port);
976
977                 flow->pattern |= F_UDP_SPORT;
978         }
979
980         snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
981
982         flow->rule.num_fields += 1;
983
984         return 0;
985 }
986
987 /**
988  * Helper for parsing the udp source port of the udp flow item.
989  *
990  * @param spec Pointer to the specific flow item.
991  * @param mask Pointer to the specific flow item's mask.
992  * @param flow Pointer to the flow.
993  * @return 0 in case of success, negative error value otherwise.
994  */
995 static inline int
996 mrvl_parse_udp_sport(const struct rte_flow_item_udp *spec,
997                      const struct rte_flow_item_udp *mask,
998                      struct rte_flow *flow)
999 {
1000         return mrvl_parse_udp_port(spec, mask, 0, flow);
1001 }
1002
1003 /**
1004  * Helper for parsing the udp destination port of the udp flow item.
1005  *
1006  * @param spec Pointer to the specific flow item.
1007  * @param mask Pointer to the specific flow item's mask.
1008  * @param flow Pointer to the flow.
1009  * @return 0 in case of success, negative error value otherwise.
1010  */
1011 static inline int
1012 mrvl_parse_udp_dport(const struct rte_flow_item_udp *spec,
1013                      const struct rte_flow_item_udp *mask,
1014                      struct rte_flow *flow)
1015 {
1016         return mrvl_parse_udp_port(spec, mask, 1, flow);
1017 }
1018
1019 /**
1020  * Parse eth flow item.
1021  *
1022  * @param item Pointer to the flow item.
1023  * @param flow Pointer to the flow.
1024  * @param error Pointer to the flow error.
1025  * @param fields Pointer to the parsed parsed fields enum.
1026  * @returns 0 on success, negative value otherwise.
1027  */
1028 static int
1029 mrvl_parse_eth(const struct rte_flow_item *item, struct rte_flow *flow,
1030                struct rte_flow_error *error)
1031 {
1032         const struct rte_flow_item_eth *spec = NULL, *mask = NULL;
1033         struct ether_addr zero;
1034         int ret;
1035
1036         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1037                               &rte_flow_item_eth_mask,
1038                               sizeof(struct rte_flow_item_eth), error);
1039         if (ret)
1040                 return ret;
1041
1042         memset(&zero, 0, sizeof(zero));
1043
1044         if (memcmp(&mask->dst, &zero, sizeof(mask->dst))) {
1045                 ret = mrvl_parse_dmac(spec, mask, flow);
1046                 if (ret)
1047                         goto out;
1048         }
1049
1050         if (memcmp(&mask->src, &zero, sizeof(mask->src))) {
1051                 ret = mrvl_parse_smac(spec, mask, flow);
1052                 if (ret)
1053                         goto out;
1054         }
1055
1056         if (mask->type) {
1057                 MRVL_LOG(WARNING, "eth type mask is ignored");
1058                 ret = mrvl_parse_type(spec, mask, flow);
1059                 if (ret)
1060                         goto out;
1061         }
1062
1063         return 0;
1064 out:
1065         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1066                            "Reached maximum number of fields in cls tbl key\n");
1067         return -rte_errno;
1068 }
1069
1070 /**
1071  * Parse vlan flow item.
1072  *
1073  * @param item Pointer to the flow item.
1074  * @param flow Pointer to the flow.
1075  * @param error Pointer to the flow error.
1076  * @param fields Pointer to the parsed parsed fields enum.
1077  * @returns 0 on success, negative value otherwise.
1078  */
1079 static int
1080 mrvl_parse_vlan(const struct rte_flow_item *item,
1081                 struct rte_flow *flow,
1082                 struct rte_flow_error *error)
1083 {
1084         const struct rte_flow_item_vlan *spec = NULL, *mask = NULL;
1085         uint16_t m;
1086         int ret;
1087
1088         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1089                               &rte_flow_item_vlan_mask,
1090                               sizeof(struct rte_flow_item_vlan), error);
1091         if (ret)
1092                 return ret;
1093
1094         m = rte_be_to_cpu_16(mask->tci);
1095         if (m & MRVL_VLAN_ID_MASK) {
1096                 MRVL_LOG(WARNING, "vlan id mask is ignored");
1097                 ret = mrvl_parse_vlan_id(spec, mask, flow);
1098                 if (ret)
1099                         goto out;
1100         }
1101
1102         if (m & MRVL_VLAN_PRI_MASK) {
1103                 MRVL_LOG(WARNING, "vlan pri mask is ignored");
1104                 ret = mrvl_parse_vlan_pri(spec, mask, flow);
1105                 if (ret)
1106                         goto out;
1107         }
1108
1109         if (flow->pattern & F_TYPE) {
1110                 rte_flow_error_set(error, ENOTSUP,
1111                                    RTE_FLOW_ERROR_TYPE_ITEM, item,
1112                                    "VLAN TPID matching is not supported");
1113                 return -rte_errno;
1114         }
1115         if (mask->inner_type) {
1116                 struct rte_flow_item_eth spec_eth = {
1117                         .type = spec->inner_type,
1118                 };
1119                 struct rte_flow_item_eth mask_eth = {
1120                         .type = mask->inner_type,
1121                 };
1122
1123                 MRVL_LOG(WARNING, "inner eth type mask is ignored");
1124                 ret = mrvl_parse_type(&spec_eth, &mask_eth, flow);
1125                 if (ret)
1126                         goto out;
1127         }
1128
1129         return 0;
1130 out:
1131         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1132                            "Reached maximum number of fields in cls tbl key\n");
1133         return -rte_errno;
1134 }
1135
1136 /**
1137  * Parse ipv4 flow item.
1138  *
1139  * @param item Pointer to the flow item.
1140  * @param flow Pointer to the flow.
1141  * @param error Pointer to the flow error.
1142  * @param fields Pointer to the parsed parsed fields enum.
1143  * @returns 0 on success, negative value otherwise.
1144  */
1145 static int
1146 mrvl_parse_ip4(const struct rte_flow_item *item,
1147                struct rte_flow *flow,
1148                struct rte_flow_error *error)
1149 {
1150         const struct rte_flow_item_ipv4 *spec = NULL, *mask = NULL;
1151         int ret;
1152
1153         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1154                               &rte_flow_item_ipv4_mask,
1155                               sizeof(struct rte_flow_item_ipv4), error);
1156         if (ret)
1157                 return ret;
1158
1159         if (mask->hdr.version_ihl ||
1160             mask->hdr.total_length ||
1161             mask->hdr.packet_id ||
1162             mask->hdr.fragment_offset ||
1163             mask->hdr.time_to_live ||
1164             mask->hdr.hdr_checksum) {
1165                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1166                                    NULL, "Not supported by classifier\n");
1167                 return -rte_errno;
1168         }
1169
1170         if (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) {
1171                 ret = mrvl_parse_ip4_dscp(spec, mask, flow);
1172                 if (ret)
1173                         goto out;
1174         }
1175
1176         if (mask->hdr.src_addr) {
1177                 ret = mrvl_parse_ip4_sip(spec, mask, flow);
1178                 if (ret)
1179                         goto out;
1180         }
1181
1182         if (mask->hdr.dst_addr) {
1183                 ret = mrvl_parse_ip4_dip(spec, mask, flow);
1184                 if (ret)
1185                         goto out;
1186         }
1187
1188         if (mask->hdr.next_proto_id) {
1189                 MRVL_LOG(WARNING, "next proto id mask is ignored");
1190                 ret = mrvl_parse_ip4_proto(spec, mask, flow);
1191                 if (ret)
1192                         goto out;
1193         }
1194
1195         return 0;
1196 out:
1197         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1198                            "Reached maximum number of fields in cls tbl key\n");
1199         return -rte_errno;
1200 }
1201
1202 /**
1203  * Parse ipv6 flow item.
1204  *
1205  * @param item Pointer to the flow item.
1206  * @param flow Pointer to the flow.
1207  * @param error Pointer to the flow error.
1208  * @param fields Pointer to the parsed parsed fields enum.
1209  * @returns 0 on success, negative value otherwise.
1210  */
1211 static int
1212 mrvl_parse_ip6(const struct rte_flow_item *item,
1213                struct rte_flow *flow,
1214                struct rte_flow_error *error)
1215 {
1216         const struct rte_flow_item_ipv6 *spec = NULL, *mask = NULL;
1217         struct ipv6_hdr zero;
1218         uint32_t flow_mask;
1219         int ret;
1220
1221         ret = mrvl_parse_init(item, (const void **)&spec,
1222                               (const void **)&mask,
1223                               &rte_flow_item_ipv6_mask,
1224                               sizeof(struct rte_flow_item_ipv6),
1225                               error);
1226         if (ret)
1227                 return ret;
1228
1229         memset(&zero, 0, sizeof(zero));
1230
1231         if (mask->hdr.payload_len ||
1232             mask->hdr.hop_limits) {
1233                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1234                                    NULL, "Not supported by classifier\n");
1235                 return -rte_errno;
1236         }
1237
1238         if (memcmp(mask->hdr.src_addr,
1239                    zero.src_addr, sizeof(mask->hdr.src_addr))) {
1240                 ret = mrvl_parse_ip6_sip(spec, mask, flow);
1241                 if (ret)
1242                         goto out;
1243         }
1244
1245         if (memcmp(mask->hdr.dst_addr,
1246                    zero.dst_addr, sizeof(mask->hdr.dst_addr))) {
1247                 ret = mrvl_parse_ip6_dip(spec, mask, flow);
1248                 if (ret)
1249                         goto out;
1250         }
1251
1252         flow_mask = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK;
1253         if (flow_mask) {
1254                 ret = mrvl_parse_ip6_flow(spec, mask, flow);
1255                 if (ret)
1256                         goto out;
1257         }
1258
1259         if (mask->hdr.proto) {
1260                 MRVL_LOG(WARNING, "next header mask is ignored");
1261                 ret = mrvl_parse_ip6_next_hdr(spec, mask, flow);
1262                 if (ret)
1263                         goto out;
1264         }
1265
1266         return 0;
1267 out:
1268         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1269                            "Reached maximum number of fields in cls tbl key\n");
1270         return -rte_errno;
1271 }
1272
1273 /**
1274  * Parse tcp flow item.
1275  *
1276  * @param item Pointer to the flow item.
1277  * @param flow Pointer to the flow.
1278  * @param error Pointer to the flow error.
1279  * @param fields Pointer to the parsed parsed fields enum.
1280  * @returns 0 on success, negative value otherwise.
1281  */
1282 static int
1283 mrvl_parse_tcp(const struct rte_flow_item *item,
1284                struct rte_flow *flow,
1285                struct rte_flow_error *error)
1286 {
1287         const struct rte_flow_item_tcp *spec = NULL, *mask = NULL;
1288         int ret;
1289
1290         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1291                               &rte_flow_item_ipv4_mask,
1292                               sizeof(struct rte_flow_item_ipv4), error);
1293         if (ret)
1294                 return ret;
1295
1296         if (mask->hdr.sent_seq ||
1297             mask->hdr.recv_ack ||
1298             mask->hdr.data_off ||
1299             mask->hdr.tcp_flags ||
1300             mask->hdr.rx_win ||
1301             mask->hdr.cksum ||
1302             mask->hdr.tcp_urp) {
1303                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1304                                    NULL, "Not supported by classifier\n");
1305                 return -rte_errno;
1306         }
1307
1308         if (mask->hdr.src_port) {
1309                 MRVL_LOG(WARNING, "tcp sport mask is ignored");
1310                 ret = mrvl_parse_tcp_sport(spec, mask, flow);
1311                 if (ret)
1312                         goto out;
1313         }
1314
1315         if (mask->hdr.dst_port) {
1316                 MRVL_LOG(WARNING, "tcp dport mask is ignored");
1317                 ret = mrvl_parse_tcp_dport(spec, mask, flow);
1318                 if (ret)
1319                         goto out;
1320         }
1321
1322         return 0;
1323 out:
1324         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1325                            "Reached maximum number of fields in cls tbl key\n");
1326         return -rte_errno;
1327 }
1328
1329 /**
1330  * Parse udp flow item.
1331  *
1332  * @param item Pointer to the flow item.
1333  * @param flow Pointer to the flow.
1334  * @param error Pointer to the flow error.
1335  * @param fields Pointer to the parsed parsed fields enum.
1336  * @returns 0 on success, negative value otherwise.
1337  */
1338 static int
1339 mrvl_parse_udp(const struct rte_flow_item *item,
1340                struct rte_flow *flow,
1341                struct rte_flow_error *error)
1342 {
1343         const struct rte_flow_item_udp *spec = NULL, *mask = NULL;
1344         int ret;
1345
1346         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1347                               &rte_flow_item_ipv4_mask,
1348                               sizeof(struct rte_flow_item_ipv4), error);
1349         if (ret)
1350                 return ret;
1351
1352         if (mask->hdr.dgram_len ||
1353             mask->hdr.dgram_cksum) {
1354                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1355                                    NULL, "Not supported by classifier\n");
1356                 return -rte_errno;
1357         }
1358
1359         if (mask->hdr.src_port) {
1360                 MRVL_LOG(WARNING, "udp sport mask is ignored");
1361                 ret = mrvl_parse_udp_sport(spec, mask, flow);
1362                 if (ret)
1363                         goto out;
1364         }
1365
1366         if (mask->hdr.dst_port) {
1367                 MRVL_LOG(WARNING, "udp dport mask is ignored");
1368                 ret = mrvl_parse_udp_dport(spec, mask, flow);
1369                 if (ret)
1370                         goto out;
1371         }
1372
1373         return 0;
1374 out:
1375         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1376                            "Reached maximum number of fields in cls tbl key\n");
1377         return -rte_errno;
1378 }
1379
1380 /**
1381  * Parse flow pattern composed of the the eth item.
1382  *
1383  * @param pattern Pointer to the flow pattern table.
1384  * @param flow Pointer to the flow.
1385  * @param error Pointer to the flow error.
1386  * @returns 0 in case of success, negative value otherwise.
1387  */
1388 static int
1389 mrvl_parse_pattern_eth(const struct rte_flow_item pattern[],
1390                        struct rte_flow *flow,
1391                        struct rte_flow_error *error)
1392 {
1393         return mrvl_parse_eth(pattern, flow, error);
1394 }
1395
1396 /**
1397  * Parse flow pattern composed of the eth and vlan items.
1398  *
1399  * @param pattern Pointer to the flow pattern table.
1400  * @param flow Pointer to the flow.
1401  * @param error Pointer to the flow error.
1402  * @returns 0 in case of success, negative value otherwise.
1403  */
1404 static int
1405 mrvl_parse_pattern_eth_vlan(const struct rte_flow_item pattern[],
1406                             struct rte_flow *flow,
1407                             struct rte_flow_error *error)
1408 {
1409         const struct rte_flow_item *item = mrvl_next_item(pattern);
1410         int ret;
1411
1412         ret = mrvl_parse_eth(item, flow, error);
1413         if (ret)
1414                 return ret;
1415
1416         item = mrvl_next_item(item + 1);
1417
1418         return mrvl_parse_vlan(item, flow, error);
1419 }
1420
1421 /**
1422  * Parse flow pattern composed of the eth, vlan and ip4/ip6 items.
1423  *
1424  * @param pattern Pointer to the flow pattern table.
1425  * @param flow Pointer to the flow.
1426  * @param error Pointer to the flow error.
1427  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1428  * @returns 0 in case of success, negative value otherwise.
1429  */
1430 static int
1431 mrvl_parse_pattern_eth_vlan_ip4_ip6(const struct rte_flow_item pattern[],
1432                                     struct rte_flow *flow,
1433                                     struct rte_flow_error *error, int ip6)
1434 {
1435         const struct rte_flow_item *item = mrvl_next_item(pattern);
1436         int ret;
1437
1438         ret = mrvl_parse_eth(item, flow, error);
1439         if (ret)
1440                 return ret;
1441
1442         item = mrvl_next_item(item + 1);
1443         ret = mrvl_parse_vlan(item, flow, error);
1444         if (ret)
1445                 return ret;
1446
1447         item = mrvl_next_item(item + 1);
1448
1449         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1450                      mrvl_parse_ip4(item, flow, error);
1451 }
1452
1453 /**
1454  * Parse flow pattern composed of the eth, vlan and ipv4 items.
1455  *
1456  * @param pattern Pointer to the flow pattern table.
1457  * @param flow Pointer to the flow.
1458  * @param error Pointer to the flow error.
1459  * @returns 0 in case of success, negative value otherwise.
1460  */
1461 static int
1462 mrvl_parse_pattern_eth_vlan_ip4(const struct rte_flow_item pattern[],
1463                                 struct rte_flow *flow,
1464                                 struct rte_flow_error *error)
1465 {
1466         return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 0);
1467 }
1468
1469 /**
1470  * Parse flow pattern composed of the eth, vlan and ipv6 items.
1471  *
1472  * @param pattern Pointer to the flow pattern table.
1473  * @param flow Pointer to the flow.
1474  * @param error Pointer to the flow error.
1475  * @returns 0 in case of success, negative value otherwise.
1476  */
1477 static int
1478 mrvl_parse_pattern_eth_vlan_ip6(const struct rte_flow_item pattern[],
1479                                 struct rte_flow *flow,
1480                                 struct rte_flow_error *error)
1481 {
1482         return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 1);
1483 }
1484
1485 /**
1486  * Parse flow pattern composed of the eth and ip4/ip6 items.
1487  *
1488  * @param pattern Pointer to the flow pattern table.
1489  * @param flow Pointer to the flow.
1490  * @param error Pointer to the flow error.
1491  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1492  * @returns 0 in case of success, negative value otherwise.
1493  */
1494 static int
1495 mrvl_parse_pattern_eth_ip4_ip6(const struct rte_flow_item pattern[],
1496                                struct rte_flow *flow,
1497                                struct rte_flow_error *error, int ip6)
1498 {
1499         const struct rte_flow_item *item = mrvl_next_item(pattern);
1500         int ret;
1501
1502         ret = mrvl_parse_eth(item, flow, error);
1503         if (ret)
1504                 return ret;
1505
1506         item = mrvl_next_item(item + 1);
1507
1508         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1509                      mrvl_parse_ip4(item, flow, error);
1510 }
1511
1512 /**
1513  * Parse flow pattern composed of the eth and ipv4 items.
1514  *
1515  * @param pattern Pointer to the flow pattern table.
1516  * @param flow Pointer to the flow.
1517  * @param error Pointer to the flow error.
1518  * @returns 0 in case of success, negative value otherwise.
1519  */
1520 static inline int
1521 mrvl_parse_pattern_eth_ip4(const struct rte_flow_item pattern[],
1522                            struct rte_flow *flow,
1523                            struct rte_flow_error *error)
1524 {
1525         return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0);
1526 }
1527
1528 /**
1529  * Parse flow pattern composed of the eth and ipv6 items.
1530  *
1531  * @param pattern Pointer to the flow pattern table.
1532  * @param flow Pointer to the flow.
1533  * @param error Pointer to the flow error.
1534  * @returns 0 in case of success, negative value otherwise.
1535  */
1536 static inline int
1537 mrvl_parse_pattern_eth_ip6(const struct rte_flow_item pattern[],
1538                            struct rte_flow *flow,
1539                            struct rte_flow_error *error)
1540 {
1541         return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1);
1542 }
1543
1544 /**
1545  * Parse flow pattern composed of the eth, ip4 and tcp/udp items.
1546  *
1547  * @param pattern Pointer to the flow pattern table.
1548  * @param flow Pointer to the flow.
1549  * @param error Pointer to the flow error.
1550  * @param tcp 1 to parse tcp item, 0 to parse udp item.
1551  * @returns 0 in case of success, negative value otherwise.
1552  */
1553 static int
1554 mrvl_parse_pattern_eth_ip4_tcp_udp(const struct rte_flow_item pattern[],
1555                                    struct rte_flow *flow,
1556                                    struct rte_flow_error *error, int tcp)
1557 {
1558         const struct rte_flow_item *item = mrvl_next_item(pattern);
1559         int ret;
1560
1561         ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0);
1562         if (ret)
1563                 return ret;
1564
1565         item = mrvl_next_item(item + 1);
1566         item = mrvl_next_item(item + 1);
1567
1568         if (tcp)
1569                 return mrvl_parse_tcp(item, flow, error);
1570
1571         return mrvl_parse_udp(item, flow, error);
1572 }
1573
1574 /**
1575  * Parse flow pattern composed of the eth, ipv4 and tcp items.
1576  *
1577  * @param pattern Pointer to the flow pattern table.
1578  * @param flow Pointer to the flow.
1579  * @param error Pointer to the flow error.
1580  * @returns 0 in case of success, negative value otherwise.
1581  */
1582 static inline int
1583 mrvl_parse_pattern_eth_ip4_tcp(const struct rte_flow_item pattern[],
1584                                struct rte_flow *flow,
1585                                struct rte_flow_error *error)
1586 {
1587         return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 1);
1588 }
1589
1590 /**
1591  * Parse flow pattern composed of the eth, ipv4 and udp items.
1592  *
1593  * @param pattern Pointer to the flow pattern table.
1594  * @param flow Pointer to the flow.
1595  * @param error Pointer to the flow error.
1596  * @returns 0 in case of success, negative value otherwise.
1597  */
1598 static inline int
1599 mrvl_parse_pattern_eth_ip4_udp(const struct rte_flow_item pattern[],
1600                                struct rte_flow *flow,
1601                                struct rte_flow_error *error)
1602 {
1603         return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 0);
1604 }
1605
1606 /**
1607  * Parse flow pattern composed of the eth, ipv6 and tcp/udp items.
1608  *
1609  * @param pattern Pointer to the flow pattern table.
1610  * @param flow Pointer to the flow.
1611  * @param error Pointer to the flow error.
1612  * @param tcp 1 to parse tcp item, 0 to parse udp item.
1613  * @returns 0 in case of success, negative value otherwise.
1614  */
1615 static int
1616 mrvl_parse_pattern_eth_ip6_tcp_udp(const struct rte_flow_item pattern[],
1617                                    struct rte_flow *flow,
1618                                    struct rte_flow_error *error, int tcp)
1619 {
1620         const struct rte_flow_item *item = mrvl_next_item(pattern);
1621         int ret;
1622
1623         ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1);
1624         if (ret)
1625                 return ret;
1626
1627         item = mrvl_next_item(item + 1);
1628         item = mrvl_next_item(item + 1);
1629
1630         if (tcp)
1631                 return mrvl_parse_tcp(item, flow, error);
1632
1633         return mrvl_parse_udp(item, flow, error);
1634 }
1635
1636 /**
1637  * Parse flow pattern composed of the eth, ipv6 and tcp items.
1638  *
1639  * @param pattern Pointer to the flow pattern table.
1640  * @param flow Pointer to the flow.
1641  * @param error Pointer to the flow error.
1642  * @returns 0 in case of success, negative value otherwise.
1643  */
1644 static inline int
1645 mrvl_parse_pattern_eth_ip6_tcp(const struct rte_flow_item pattern[],
1646                                struct rte_flow *flow,
1647                                struct rte_flow_error *error)
1648 {
1649         return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 1);
1650 }
1651
1652 /**
1653  * Parse flow pattern composed of the eth, ipv6 and udp items.
1654  *
1655  * @param pattern Pointer to the flow pattern table.
1656  * @param flow Pointer to the flow.
1657  * @param error Pointer to the flow error.
1658  * @returns 0 in case of success, negative value otherwise.
1659  */
1660 static inline int
1661 mrvl_parse_pattern_eth_ip6_udp(const struct rte_flow_item pattern[],
1662                                struct rte_flow *flow,
1663                                struct rte_flow_error *error)
1664 {
1665         return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 0);
1666 }
1667
1668 /**
1669  * Parse flow pattern composed of the vlan item.
1670  *
1671  * @param pattern Pointer to the flow pattern table.
1672  * @param flow Pointer to the flow.
1673  * @param error Pointer to the flow error.
1674  * @returns 0 in case of success, negative value otherwise.
1675  */
1676 static int
1677 mrvl_parse_pattern_vlan(const struct rte_flow_item pattern[],
1678                             struct rte_flow *flow,
1679                             struct rte_flow_error *error)
1680 {
1681         const struct rte_flow_item *item = mrvl_next_item(pattern);
1682
1683         return mrvl_parse_vlan(item, flow, error);
1684 }
1685
1686 /**
1687  * Parse flow pattern composed of the vlan and ip4/ip6 items.
1688  *
1689  * @param pattern Pointer to the flow pattern table.
1690  * @param flow Pointer to the flow.
1691  * @param error Pointer to the flow error.
1692  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1693  * @returns 0 in case of success, negative value otherwise.
1694  */
1695 static int
1696 mrvl_parse_pattern_vlan_ip4_ip6(const struct rte_flow_item pattern[],
1697                                 struct rte_flow *flow,
1698                                 struct rte_flow_error *error, int ip6)
1699 {
1700         const struct rte_flow_item *item = mrvl_next_item(pattern);
1701         int ret;
1702
1703         ret = mrvl_parse_vlan(item, flow, error);
1704         if (ret)
1705                 return ret;
1706
1707         item = mrvl_next_item(item + 1);
1708
1709         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1710                      mrvl_parse_ip4(item, flow, error);
1711 }
1712
1713 /**
1714  * Parse flow pattern composed of the vlan and ipv4 items.
1715  *
1716  * @param pattern Pointer to the flow pattern table.
1717  * @param flow Pointer to the flow.
1718  * @param error Pointer to the flow error.
1719  * @returns 0 in case of success, negative value otherwise.
1720  */
1721 static inline int
1722 mrvl_parse_pattern_vlan_ip4(const struct rte_flow_item pattern[],
1723                             struct rte_flow *flow,
1724                             struct rte_flow_error *error)
1725 {
1726         return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0);
1727 }
1728
1729 /**
1730  * Parse flow pattern composed of the vlan, ipv4 and tcp/udp items.
1731  *
1732  * @param pattern Pointer to the flow pattern table.
1733  * @param flow Pointer to the flow.
1734  * @param error Pointer to the flow error.
1735  * @returns 0 in case of success, negative value otherwise.
1736  */
1737 static int
1738 mrvl_parse_pattern_vlan_ip_tcp_udp(const struct rte_flow_item pattern[],
1739                                    struct rte_flow *flow,
1740                                    struct rte_flow_error *error, int tcp)
1741 {
1742         const struct rte_flow_item *item = mrvl_next_item(pattern);
1743         int ret;
1744
1745         ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0);
1746         if (ret)
1747                 return ret;
1748
1749         item = mrvl_next_item(item + 1);
1750         item = mrvl_next_item(item + 1);
1751
1752         if (tcp)
1753                 return mrvl_parse_tcp(item, flow, error);
1754
1755         return mrvl_parse_udp(item, flow, error);
1756 }
1757
1758 /**
1759  * Parse flow pattern composed of the vlan, ipv4 and tcp items.
1760  *
1761  * @param pattern Pointer to the flow pattern table.
1762  * @param flow Pointer to the flow.
1763  * @param error Pointer to the flow error.
1764  * @returns 0 in case of success, negative value otherwise.
1765  */
1766 static inline int
1767 mrvl_parse_pattern_vlan_ip_tcp(const struct rte_flow_item pattern[],
1768                                struct rte_flow *flow,
1769                                struct rte_flow_error *error)
1770 {
1771         return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 1);
1772 }
1773
1774 /**
1775  * Parse flow pattern composed of the vlan, ipv4 and udp items.
1776  *
1777  * @param pattern Pointer to the flow pattern table.
1778  * @param flow Pointer to the flow.
1779  * @param error Pointer to the flow error.
1780  * @returns 0 in case of success, negative value otherwise.
1781  */
1782 static inline int
1783 mrvl_parse_pattern_vlan_ip_udp(const struct rte_flow_item pattern[],
1784                                struct rte_flow *flow,
1785                                struct rte_flow_error *error)
1786 {
1787         return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 0);
1788 }
1789
1790 /**
1791  * Parse flow pattern composed of the vlan and ipv6 items.
1792  *
1793  * @param pattern Pointer to the flow pattern table.
1794  * @param flow Pointer to the flow.
1795  * @param error Pointer to the flow error.
1796  * @returns 0 in case of success, negative value otherwise.
1797  */
1798 static inline int
1799 mrvl_parse_pattern_vlan_ip6(const struct rte_flow_item pattern[],
1800                             struct rte_flow *flow,
1801                             struct rte_flow_error *error)
1802 {
1803         return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1);
1804 }
1805
1806 /**
1807  * Parse flow pattern composed of the vlan, ipv6 and tcp/udp items.
1808  *
1809  * @param pattern Pointer to the flow pattern table.
1810  * @param flow Pointer to the flow.
1811  * @param error Pointer to the flow error.
1812  * @returns 0 in case of success, negative value otherwise.
1813  */
1814 static int
1815 mrvl_parse_pattern_vlan_ip6_tcp_udp(const struct rte_flow_item pattern[],
1816                                     struct rte_flow *flow,
1817                                     struct rte_flow_error *error, int tcp)
1818 {
1819         const struct rte_flow_item *item = mrvl_next_item(pattern);
1820         int ret;
1821
1822         ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1);
1823         if (ret)
1824                 return ret;
1825
1826         item = mrvl_next_item(item + 1);
1827         item = mrvl_next_item(item + 1);
1828
1829         if (tcp)
1830                 return mrvl_parse_tcp(item, flow, error);
1831
1832         return mrvl_parse_udp(item, flow, error);
1833 }
1834
1835 /**
1836  * Parse flow pattern composed of the vlan, ipv6 and tcp items.
1837  *
1838  * @param pattern Pointer to the flow pattern table.
1839  * @param flow Pointer to the flow.
1840  * @param error Pointer to the flow error.
1841  * @returns 0 in case of success, negative value otherwise.
1842  */
1843 static inline int
1844 mrvl_parse_pattern_vlan_ip6_tcp(const struct rte_flow_item pattern[],
1845                                 struct rte_flow *flow,
1846                                 struct rte_flow_error *error)
1847 {
1848         return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 1);
1849 }
1850
1851 /**
1852  * Parse flow pattern composed of the vlan, ipv6 and udp items.
1853  *
1854  * @param pattern Pointer to the flow pattern table.
1855  * @param flow Pointer to the flow.
1856  * @param error Pointer to the flow error.
1857  * @returns 0 in case of success, negative value otherwise.
1858  */
1859 static inline int
1860 mrvl_parse_pattern_vlan_ip6_udp(const struct rte_flow_item pattern[],
1861                                 struct rte_flow *flow,
1862                                 struct rte_flow_error *error)
1863 {
1864         return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 0);
1865 }
1866
1867 /**
1868  * Parse flow pattern composed of the ip4/ip6 item.
1869  *
1870  * @param pattern Pointer to the flow pattern table.
1871  * @param flow Pointer to the flow.
1872  * @param error Pointer to the flow error.
1873  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1874  * @returns 0 in case of success, negative value otherwise.
1875  */
1876 static int
1877 mrvl_parse_pattern_ip4_ip6(const struct rte_flow_item pattern[],
1878                        struct rte_flow *flow,
1879                        struct rte_flow_error *error, int ip6)
1880 {
1881         const struct rte_flow_item *item = mrvl_next_item(pattern);
1882
1883         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1884                      mrvl_parse_ip4(item, flow, error);
1885 }
1886
1887 /**
1888  * Parse flow pattern composed of the ipv4 item.
1889  *
1890  * @param pattern Pointer to the flow pattern table.
1891  * @param flow Pointer to the flow.
1892  * @param error Pointer to the flow error.
1893  * @returns 0 in case of success, negative value otherwise.
1894  */
1895 static inline int
1896 mrvl_parse_pattern_ip4(const struct rte_flow_item pattern[],
1897                        struct rte_flow *flow,
1898                        struct rte_flow_error *error)
1899 {
1900         return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 0);
1901 }
1902
1903 /**
1904  * Parse flow pattern composed of the ipv6 item.
1905  *
1906  * @param pattern Pointer to the flow pattern table.
1907  * @param flow Pointer to the flow.
1908  * @param error Pointer to the flow error.
1909  * @returns 0 in case of success, negative value otherwise.
1910  */
1911 static inline int
1912 mrvl_parse_pattern_ip6(const struct rte_flow_item pattern[],
1913                        struct rte_flow *flow,
1914                        struct rte_flow_error *error)
1915 {
1916         return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 1);
1917 }
1918
1919 /**
1920  * Parse flow pattern composed of the ip4/ip6 and tcp items.
1921  *
1922  * @param pattern Pointer to the flow pattern table.
1923  * @param flow Pointer to the flow.
1924  * @param error Pointer to the flow error.
1925  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1926  * @returns 0 in case of success, negative value otherwise.
1927  */
1928 static int
1929 mrvl_parse_pattern_ip4_ip6_tcp(const struct rte_flow_item pattern[],
1930                            struct rte_flow *flow,
1931                            struct rte_flow_error *error, int ip6)
1932 {
1933         const struct rte_flow_item *item = mrvl_next_item(pattern);
1934         int ret;
1935
1936         ret = ip6 ? mrvl_parse_ip6(item, flow, error) :
1937                     mrvl_parse_ip4(item, flow, error);
1938         if (ret)
1939                 return ret;
1940
1941         item = mrvl_next_item(item + 1);
1942
1943         return mrvl_parse_tcp(item, flow, error);
1944 }
1945
1946 /**
1947  * Parse flow pattern composed of the ipv4 and tcp items.
1948  *
1949  * @param pattern Pointer to the flow pattern table.
1950  * @param flow Pointer to the flow.
1951  * @param error Pointer to the flow error.
1952  * @returns 0 in case of success, negative value otherwise.
1953  */
1954 static inline int
1955 mrvl_parse_pattern_ip4_tcp(const struct rte_flow_item pattern[],
1956                            struct rte_flow *flow,
1957                            struct rte_flow_error *error)
1958 {
1959         return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 0);
1960 }
1961
1962 /**
1963  * Parse flow pattern composed of the ipv6 and tcp items.
1964  *
1965  * @param pattern Pointer to the flow pattern table.
1966  * @param flow Pointer to the flow.
1967  * @param error Pointer to the flow error.
1968  * @returns 0 in case of success, negative value otherwise.
1969  */
1970 static inline int
1971 mrvl_parse_pattern_ip6_tcp(const struct rte_flow_item pattern[],
1972                            struct rte_flow *flow,
1973                            struct rte_flow_error *error)
1974 {
1975         return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 1);
1976 }
1977
1978 /**
1979  * Parse flow pattern composed of the ipv4/ipv6 and udp items.
1980  *
1981  * @param pattern Pointer to the flow pattern table.
1982  * @param flow Pointer to the flow.
1983  * @param error Pointer to the flow error.
1984  * @returns 0 in case of success, negative value otherwise.
1985  */
1986 static int
1987 mrvl_parse_pattern_ip4_ip6_udp(const struct rte_flow_item pattern[],
1988                            struct rte_flow *flow,
1989                            struct rte_flow_error *error, int ip6)
1990 {
1991         const struct rte_flow_item *item = mrvl_next_item(pattern);
1992         int ret;
1993
1994         ret = ip6 ? mrvl_parse_ip6(item, flow, error) :
1995                     mrvl_parse_ip4(item, flow, error);
1996         if (ret)
1997                 return ret;
1998
1999         item = mrvl_next_item(item + 1);
2000
2001         return mrvl_parse_udp(item, flow, error);
2002 }
2003
2004 /**
2005  * Parse flow pattern composed of the ipv4 and udp items.
2006  *
2007  * @param pattern Pointer to the flow pattern table.
2008  * @param flow Pointer to the flow.
2009  * @param error Pointer to the flow error.
2010  * @returns 0 in case of success, negative value otherwise.
2011  */
2012 static inline int
2013 mrvl_parse_pattern_ip4_udp(const struct rte_flow_item pattern[],
2014                            struct rte_flow *flow,
2015                            struct rte_flow_error *error)
2016 {
2017         return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 0);
2018 }
2019
2020 /**
2021  * Parse flow pattern composed of the ipv6 and udp items.
2022  *
2023  * @param pattern Pointer to the flow pattern table.
2024  * @param flow Pointer to the flow.
2025  * @param error Pointer to the flow error.
2026  * @returns 0 in case of success, negative value otherwise.
2027  */
2028 static inline int
2029 mrvl_parse_pattern_ip6_udp(const struct rte_flow_item pattern[],
2030                            struct rte_flow *flow,
2031                            struct rte_flow_error *error)
2032 {
2033         return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 1);
2034 }
2035
2036 /**
2037  * Parse flow pattern composed of the tcp item.
2038  *
2039  * @param pattern Pointer to the flow pattern table.
2040  * @param flow Pointer to the flow.
2041  * @param error Pointer to the flow error.
2042  * @returns 0 in case of success, negative value otherwise.
2043  */
2044 static int
2045 mrvl_parse_pattern_tcp(const struct rte_flow_item pattern[],
2046                        struct rte_flow *flow,
2047                        struct rte_flow_error *error)
2048 {
2049         const struct rte_flow_item *item = mrvl_next_item(pattern);
2050
2051         return mrvl_parse_tcp(item, flow, error);
2052 }
2053
2054 /**
2055  * Parse flow pattern composed of the udp item.
2056  *
2057  * @param pattern Pointer to the flow pattern table.
2058  * @param flow Pointer to the flow.
2059  * @param error Pointer to the flow error.
2060  * @returns 0 in case of success, negative value otherwise.
2061  */
2062 static int
2063 mrvl_parse_pattern_udp(const struct rte_flow_item pattern[],
2064                        struct rte_flow *flow,
2065                        struct rte_flow_error *error)
2066 {
2067         const struct rte_flow_item *item = mrvl_next_item(pattern);
2068
2069         return mrvl_parse_udp(item, flow, error);
2070 }
2071
2072 /**
2073  * Structure used to map specific flow pattern to the pattern parse callback
2074  * which will iterate over each pattern item and extract relevant data.
2075  */
2076 static const struct {
2077         const enum rte_flow_item_type *pattern;
2078         int (*parse)(const struct rte_flow_item pattern[],
2079                 struct rte_flow *flow,
2080                 struct rte_flow_error *error);
2081 } mrvl_patterns[] = {
2082         { pattern_eth, mrvl_parse_pattern_eth },
2083         { pattern_eth_vlan, mrvl_parse_pattern_eth_vlan },
2084         { pattern_eth_vlan_ip, mrvl_parse_pattern_eth_vlan_ip4 },
2085         { pattern_eth_vlan_ip6, mrvl_parse_pattern_eth_vlan_ip6 },
2086         { pattern_eth_ip4, mrvl_parse_pattern_eth_ip4 },
2087         { pattern_eth_ip4_tcp, mrvl_parse_pattern_eth_ip4_tcp },
2088         { pattern_eth_ip4_udp, mrvl_parse_pattern_eth_ip4_udp },
2089         { pattern_eth_ip6, mrvl_parse_pattern_eth_ip6 },
2090         { pattern_eth_ip6_tcp, mrvl_parse_pattern_eth_ip6_tcp },
2091         { pattern_eth_ip6_udp, mrvl_parse_pattern_eth_ip6_udp },
2092         { pattern_vlan, mrvl_parse_pattern_vlan },
2093         { pattern_vlan_ip, mrvl_parse_pattern_vlan_ip4 },
2094         { pattern_vlan_ip_tcp, mrvl_parse_pattern_vlan_ip_tcp },
2095         { pattern_vlan_ip_udp, mrvl_parse_pattern_vlan_ip_udp },
2096         { pattern_vlan_ip6, mrvl_parse_pattern_vlan_ip6 },
2097         { pattern_vlan_ip6_tcp, mrvl_parse_pattern_vlan_ip6_tcp },
2098         { pattern_vlan_ip6_udp, mrvl_parse_pattern_vlan_ip6_udp },
2099         { pattern_ip, mrvl_parse_pattern_ip4 },
2100         { pattern_ip_tcp, mrvl_parse_pattern_ip4_tcp },
2101         { pattern_ip_udp, mrvl_parse_pattern_ip4_udp },
2102         { pattern_ip6, mrvl_parse_pattern_ip6 },
2103         { pattern_ip6_tcp, mrvl_parse_pattern_ip6_tcp },
2104         { pattern_ip6_udp, mrvl_parse_pattern_ip6_udp },
2105         { pattern_tcp, mrvl_parse_pattern_tcp },
2106         { pattern_udp, mrvl_parse_pattern_udp }
2107 };
2108
2109 /**
2110  * Check whether provided pattern matches any of the supported ones.
2111  *
2112  * @param type_pattern Pointer to the pattern type.
2113  * @param item_pattern Pointer to the flow pattern.
2114  * @returns 1 in case of success, 0 value otherwise.
2115  */
2116 static int
2117 mrvl_patterns_match(const enum rte_flow_item_type *type_pattern,
2118                     const struct rte_flow_item *item_pattern)
2119 {
2120         const enum rte_flow_item_type *type = type_pattern;
2121         const struct rte_flow_item *item = item_pattern;
2122
2123         for (;;) {
2124                 if (item->type == RTE_FLOW_ITEM_TYPE_VOID) {
2125                         item++;
2126                         continue;
2127                 }
2128
2129                 if (*type == RTE_FLOW_ITEM_TYPE_END ||
2130                     item->type == RTE_FLOW_ITEM_TYPE_END)
2131                         break;
2132
2133                 if (*type != item->type)
2134                         break;
2135
2136                 item++;
2137                 type++;
2138         }
2139
2140         return *type == item->type;
2141 }
2142
2143 /**
2144  * Parse flow attribute.
2145  *
2146  * This will check whether the provided attribute's flags are supported.
2147  *
2148  * @param priv Unused
2149  * @param attr Pointer to the flow attribute.
2150  * @param flow Unused
2151  * @param error Pointer to the flow error.
2152  * @returns 0 in case of success, negative value otherwise.
2153  */
2154 static int
2155 mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused,
2156                      const struct rte_flow_attr *attr,
2157                      struct rte_flow *flow __rte_unused,
2158                      struct rte_flow_error *error)
2159 {
2160         if (!attr) {
2161                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR,
2162                                    NULL, "NULL attribute");
2163                 return -rte_errno;
2164         }
2165
2166         if (attr->group) {
2167                 rte_flow_error_set(error, ENOTSUP,
2168                                    RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL,
2169                                    "Groups are not supported");
2170                 return -rte_errno;
2171         }
2172         if (attr->priority) {
2173                 rte_flow_error_set(error, ENOTSUP,
2174                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL,
2175                                    "Priorities are not supported");
2176                 return -rte_errno;
2177         }
2178         if (!attr->ingress) {
2179                 rte_flow_error_set(error, ENOTSUP,
2180                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL,
2181                                    "Only ingress is supported");
2182                 return -rte_errno;
2183         }
2184         if (attr->egress) {
2185                 rte_flow_error_set(error, ENOTSUP,
2186                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL,
2187                                    "Egress is not supported");
2188                 return -rte_errno;
2189         }
2190         if (attr->transfer) {
2191                 rte_flow_error_set(error, ENOTSUP,
2192                                    RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL,
2193                                    "Transfer is not supported");
2194                 return -rte_errno;
2195         }
2196
2197         return 0;
2198 }
2199
2200 /**
2201  * Parse flow pattern.
2202  *
2203  * Specific classifier rule will be created as well.
2204  *
2205  * @param priv Unused
2206  * @param pattern Pointer to the flow pattern.
2207  * @param flow Pointer to the flow.
2208  * @param error Pointer to the flow error.
2209  * @returns 0 in case of success, negative value otherwise.
2210  */
2211 static int
2212 mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused,
2213                         const struct rte_flow_item pattern[],
2214                         struct rte_flow *flow,
2215                         struct rte_flow_error *error)
2216 {
2217         unsigned int i;
2218         int ret;
2219
2220         for (i = 0; i < RTE_DIM(mrvl_patterns); i++) {
2221                 if (!mrvl_patterns_match(mrvl_patterns[i].pattern, pattern))
2222                         continue;
2223
2224                 ret = mrvl_patterns[i].parse(pattern, flow, error);
2225                 if (ret)
2226                         mrvl_free_all_key_mask(&flow->rule);
2227
2228                 return ret;
2229         }
2230
2231         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, NULL,
2232                            "Unsupported pattern");
2233
2234         return -rte_errno;
2235 }
2236
2237 /**
2238  * Parse flow actions.
2239  *
2240  * @param priv Pointer to the port's private data.
2241  * @param actions Pointer the action table.
2242  * @param flow Pointer to the flow.
2243  * @param error Pointer to the flow error.
2244  * @returns 0 in case of success, negative value otherwise.
2245  */
2246 static int
2247 mrvl_flow_parse_actions(struct mrvl_priv *priv,
2248                         const struct rte_flow_action actions[],
2249                         struct rte_flow *flow,
2250                         struct rte_flow_error *error)
2251 {
2252         const struct rte_flow_action *action = actions;
2253         int specified = 0;
2254
2255         for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
2256                 if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
2257                         continue;
2258
2259                 if (action->type == RTE_FLOW_ACTION_TYPE_DROP) {
2260                         flow->cos.ppio = priv->ppio;
2261                         flow->cos.tc = 0;
2262                         flow->action.type = PP2_CLS_TBL_ACT_DROP;
2263                         flow->action.cos = &flow->cos;
2264                         specified++;
2265                 } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
2266                         const struct rte_flow_action_queue *q =
2267                                 (const struct rte_flow_action_queue *)
2268                                 action->conf;
2269
2270                         if (q->index > priv->nb_rx_queues) {
2271                                 rte_flow_error_set(error, EINVAL,
2272                                                 RTE_FLOW_ERROR_TYPE_ACTION,
2273                                                 NULL,
2274                                                 "Queue index out of range");
2275                                 return -rte_errno;
2276                         }
2277
2278                         if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) {
2279                                 /*
2280                                  * Unknown TC mapping, mapping will not have
2281                                  * a correct queue.
2282                                  */
2283                                 MRVL_LOG(ERR,
2284                                         "Unknown TC mapping for queue %hu eth%hhu",
2285                                         q->index, priv->ppio_id);
2286
2287                                 rte_flow_error_set(error, EFAULT,
2288                                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2289                                                 NULL, NULL);
2290                                 return -rte_errno;
2291                         }
2292
2293                         MRVL_LOG(DEBUG,
2294                                 "Action: Assign packets to queue %d, tc:%d, q:%d",
2295                                 q->index, priv->rxq_map[q->index].tc,
2296                                 priv->rxq_map[q->index].inq);
2297
2298                         flow->cos.ppio = priv->ppio;
2299                         flow->cos.tc = priv->rxq_map[q->index].tc;
2300                         flow->action.type = PP2_CLS_TBL_ACT_DONE;
2301                         flow->action.cos = &flow->cos;
2302                         specified++;
2303                 } else {
2304                         rte_flow_error_set(error, ENOTSUP,
2305                                            RTE_FLOW_ERROR_TYPE_ACTION, NULL,
2306                                            "Action not supported");
2307                         return -rte_errno;
2308                 }
2309
2310         }
2311
2312         if (!specified) {
2313                 rte_flow_error_set(error, EINVAL,
2314                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2315                                    NULL, "Action not specified");
2316                 return -rte_errno;
2317         }
2318
2319         return 0;
2320 }
2321
2322 /**
2323  * Parse flow attribute, pattern and actions.
2324  *
2325  * @param priv Pointer to the port's private data.
2326  * @param attr Pointer to the flow attribute.
2327  * @param pattern Pointer to the flow pattern.
2328  * @param actions Pointer to the flow actions.
2329  * @param flow Pointer to the flow.
2330  * @param error Pointer to the flow error.
2331  * @returns 0 on success, negative value otherwise.
2332  */
2333 static int
2334 mrvl_flow_parse(struct mrvl_priv *priv, const struct rte_flow_attr *attr,
2335                 const struct rte_flow_item pattern[],
2336                 const struct rte_flow_action actions[],
2337                 struct rte_flow *flow,
2338                 struct rte_flow_error *error)
2339 {
2340         int ret;
2341
2342         ret = mrvl_flow_parse_attr(priv, attr, flow, error);
2343         if (ret)
2344                 return ret;
2345
2346         ret = mrvl_flow_parse_pattern(priv, pattern, flow, error);
2347         if (ret)
2348                 return ret;
2349
2350         return mrvl_flow_parse_actions(priv, actions, flow, error);
2351 }
2352
2353 static inline enum pp2_cls_tbl_type
2354 mrvl_engine_type(const struct rte_flow *flow)
2355 {
2356         int i, size = 0;
2357
2358         for (i = 0; i < flow->rule.num_fields; i++)
2359                 size += flow->rule.fields[i].size;
2360
2361         /*
2362          * For maskable engine type the key size must be up to 8 bytes.
2363          * For keys with size bigger than 8 bytes, engine type must
2364          * be set to exact match.
2365          */
2366         if (size > 8)
2367                 return PP2_CLS_TBL_EXACT_MATCH;
2368
2369         return PP2_CLS_TBL_MASKABLE;
2370 }
2371
2372 static int
2373 mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow)
2374 {
2375         struct mrvl_priv *priv = dev->data->dev_private;
2376         struct pp2_cls_tbl_key *key = &priv->cls_tbl_params.key;
2377         int ret;
2378
2379         if (priv->cls_tbl) {
2380                 pp2_cls_tbl_deinit(priv->cls_tbl);
2381                 priv->cls_tbl = NULL;
2382         }
2383
2384         memset(&priv->cls_tbl_params, 0, sizeof(priv->cls_tbl_params));
2385
2386         priv->cls_tbl_params.type = mrvl_engine_type(first_flow);
2387         MRVL_LOG(INFO, "Setting cls search engine type to %s",
2388                         priv->cls_tbl_params.type == PP2_CLS_TBL_EXACT_MATCH ?
2389                         "exact" : "maskable");
2390         priv->cls_tbl_params.max_num_rules = MRVL_CLS_MAX_NUM_RULES;
2391         priv->cls_tbl_params.default_act.type = PP2_CLS_TBL_ACT_DONE;
2392         priv->cls_tbl_params.default_act.cos = &first_flow->cos;
2393
2394         if (first_flow->pattern & F_DMAC) {
2395                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2396                 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_DA;
2397                 key->key_size += 6;
2398                 key->num_fields += 1;
2399         }
2400
2401         if (first_flow->pattern & F_SMAC) {
2402                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2403                 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_SA;
2404                 key->key_size += 6;
2405                 key->num_fields += 1;
2406         }
2407
2408         if (first_flow->pattern & F_TYPE) {
2409                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2410                 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_TYPE;
2411                 key->key_size += 2;
2412                 key->num_fields += 1;
2413         }
2414
2415         if (first_flow->pattern & F_VLAN_ID) {
2416                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN;
2417                 key->proto_field[key->num_fields].field.vlan = MV_NET_VLAN_F_ID;
2418                 key->key_size += 2;
2419                 key->num_fields += 1;
2420         }
2421
2422         if (first_flow->pattern & F_VLAN_PRI) {
2423                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN;
2424                 key->proto_field[key->num_fields].field.vlan =
2425                         MV_NET_VLAN_F_PRI;
2426                 key->key_size += 1;
2427                 key->num_fields += 1;
2428         }
2429
2430         if (first_flow->pattern & F_IP4_TOS) {
2431                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2432                 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_TOS;
2433                 key->key_size += 1;
2434                 key->num_fields += 1;
2435         }
2436
2437         if (first_flow->pattern & F_IP4_SIP) {
2438                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2439                 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_SA;
2440                 key->key_size += 4;
2441                 key->num_fields += 1;
2442         }
2443
2444         if (first_flow->pattern & F_IP4_DIP) {
2445                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2446                 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_DA;
2447                 key->key_size += 4;
2448                 key->num_fields += 1;
2449         }
2450
2451         if (first_flow->pattern & F_IP4_PROTO) {
2452                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2453                 key->proto_field[key->num_fields].field.ipv4 =
2454                         MV_NET_IP4_F_PROTO;
2455                 key->key_size += 1;
2456                 key->num_fields += 1;
2457         }
2458
2459         if (first_flow->pattern & F_IP6_SIP) {
2460                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2461                 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_SA;
2462                 key->key_size += 16;
2463                 key->num_fields += 1;
2464         }
2465
2466         if (first_flow->pattern & F_IP6_DIP) {
2467                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2468                 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_DA;
2469                 key->key_size += 16;
2470                 key->num_fields += 1;
2471         }
2472
2473         if (first_flow->pattern & F_IP6_FLOW) {
2474                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2475                 key->proto_field[key->num_fields].field.ipv6 =
2476                         MV_NET_IP6_F_FLOW;
2477                 key->key_size += 3;
2478                 key->num_fields += 1;
2479         }
2480
2481         if (first_flow->pattern & F_IP6_NEXT_HDR) {
2482                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2483                 key->proto_field[key->num_fields].field.ipv6 =
2484                         MV_NET_IP6_F_NEXT_HDR;
2485                 key->key_size += 1;
2486                 key->num_fields += 1;
2487         }
2488
2489         if (first_flow->pattern & F_TCP_SPORT) {
2490                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP;
2491                 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP;
2492                 key->key_size += 2;
2493                 key->num_fields += 1;
2494         }
2495
2496         if (first_flow->pattern & F_TCP_DPORT) {
2497                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP;
2498                 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_DP;
2499                 key->key_size += 2;
2500                 key->num_fields += 1;
2501         }
2502
2503         if (first_flow->pattern & F_UDP_SPORT) {
2504                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP;
2505                 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP;
2506                 key->key_size += 2;
2507                 key->num_fields += 1;
2508         }
2509
2510         if (first_flow->pattern & F_UDP_DPORT) {
2511                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP;
2512                 key->proto_field[key->num_fields].field.udp = MV_NET_TCP_F_DP;
2513                 key->key_size += 2;
2514                 key->num_fields += 1;
2515         }
2516
2517         ret = pp2_cls_tbl_init(&priv->cls_tbl_params, &priv->cls_tbl);
2518         if (!ret)
2519                 priv->cls_tbl_pattern = first_flow->pattern;
2520
2521         return ret;
2522 }
2523
2524 /**
2525  * Check whether new flow can be added to the table
2526  *
2527  * @param priv Pointer to the port's private data.
2528  * @param flow Pointer to the new flow.
2529  * @return 1 in case flow can be added, 0 otherwise.
2530  */
2531 static inline int
2532 mrvl_flow_can_be_added(struct mrvl_priv *priv, const struct rte_flow *flow)
2533 {
2534         return flow->pattern == priv->cls_tbl_pattern &&
2535                mrvl_engine_type(flow) == priv->cls_tbl_params.type;
2536 }
2537
2538 /**
2539  * DPDK flow create callback called when flow is to be created.
2540  *
2541  * @param dev Pointer to the device.
2542  * @param attr Pointer to the flow attribute.
2543  * @param pattern Pointer to the flow pattern.
2544  * @param actions Pointer to the flow actions.
2545  * @param error Pointer to the flow error.
2546  * @returns Pointer to the created flow in case of success, NULL otherwise.
2547  */
2548 static struct rte_flow *
2549 mrvl_flow_create(struct rte_eth_dev *dev,
2550                  const struct rte_flow_attr *attr,
2551                  const struct rte_flow_item pattern[],
2552                  const struct rte_flow_action actions[],
2553                  struct rte_flow_error *error)
2554 {
2555         struct mrvl_priv *priv = dev->data->dev_private;
2556         struct rte_flow *flow, *first;
2557         int ret;
2558
2559         if (!dev->data->dev_started) {
2560                 rte_flow_error_set(error, EINVAL,
2561                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2562                                    "Port must be started first\n");
2563                 return NULL;
2564         }
2565
2566         flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id());
2567         if (!flow)
2568                 return NULL;
2569
2570         ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error);
2571         if (ret)
2572                 goto out;
2573
2574         /*
2575          * Four cases here:
2576          *
2577          * 1. In case table does not exist - create one.
2578          * 2. In case table exists, is empty and new flow cannot be added
2579          *    recreate table.
2580          * 3. In case table is not empty and new flow matches table format
2581          *    add it.
2582          * 4. Otherwise flow cannot be added.
2583          */
2584         first = LIST_FIRST(&priv->flows);
2585         if (!priv->cls_tbl) {
2586                 ret = mrvl_create_cls_table(dev, flow);
2587         } else if (!first && !mrvl_flow_can_be_added(priv, flow)) {
2588                 ret = mrvl_create_cls_table(dev, flow);
2589         } else if (mrvl_flow_can_be_added(priv, flow)) {
2590                 ret = 0;
2591         } else {
2592                 rte_flow_error_set(error, EINVAL,
2593                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2594                                    "Pattern does not match cls table format\n");
2595                 goto out;
2596         }
2597
2598         if (ret) {
2599                 rte_flow_error_set(error, EINVAL,
2600                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2601                                    "Failed to create cls table\n");
2602                 goto out;
2603         }
2604
2605         ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action);
2606         if (ret) {
2607                 rte_flow_error_set(error, EINVAL,
2608                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2609                                    "Failed to add rule\n");
2610                 goto out;
2611         }
2612
2613         LIST_INSERT_HEAD(&priv->flows, flow, next);
2614
2615         return flow;
2616 out:
2617         rte_free(flow);
2618         return NULL;
2619 }
2620
2621 /**
2622  * Remove classifier rule associated with given flow.
2623  *
2624  * @param priv Pointer to the port's private data.
2625  * @param flow Pointer to the flow.
2626  * @param error Pointer to the flow error.
2627  * @returns 0 in case of success, negative value otherwise.
2628  */
2629 static int
2630 mrvl_flow_remove(struct mrvl_priv *priv, struct rte_flow *flow,
2631                  struct rte_flow_error *error)
2632 {
2633         int ret;
2634
2635         if (!priv->cls_tbl) {
2636                 rte_flow_error_set(error, EINVAL,
2637                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2638                                    "Classifier table not initialized");
2639                 return -rte_errno;
2640         }
2641
2642         ret = pp2_cls_tbl_remove_rule(priv->cls_tbl, &flow->rule);
2643         if (ret) {
2644                 rte_flow_error_set(error, EINVAL,
2645                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2646                                    "Failed to remove rule");
2647                 return -rte_errno;
2648         }
2649
2650         mrvl_free_all_key_mask(&flow->rule);
2651
2652         return 0;
2653 }
2654
2655 /**
2656  * DPDK flow destroy callback called when flow is to be removed.
2657  *
2658  * @param priv Pointer to the port's private data.
2659  * @param flow Pointer to the flow.
2660  * @param error Pointer to the flow error.
2661  * @returns 0 in case of success, negative value otherwise.
2662  */
2663 static int
2664 mrvl_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
2665                   struct rte_flow_error *error)
2666 {
2667         struct mrvl_priv *priv = dev->data->dev_private;
2668         struct rte_flow *f;
2669         int ret;
2670
2671         LIST_FOREACH(f, &priv->flows, next) {
2672                 if (f == flow)
2673                         break;
2674         }
2675
2676         if (!flow) {
2677                 rte_flow_error_set(error, EINVAL,
2678                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2679                                    "Rule was not found");
2680                 return -rte_errno;
2681         }
2682
2683         LIST_REMOVE(f, next);
2684
2685         ret = mrvl_flow_remove(priv, flow, error);
2686         if (ret)
2687                 return ret;
2688
2689         rte_free(flow);
2690
2691         return 0;
2692 }
2693
2694 /**
2695  * DPDK flow callback called to verify given attribute, pattern and actions.
2696  *
2697  * @param dev Pointer to the device.
2698  * @param attr Pointer to the flow attribute.
2699  * @param pattern Pointer to the flow pattern.
2700  * @param actions Pointer to the flow actions.
2701  * @param error Pointer to the flow error.
2702  * @returns 0 on success, negative value otherwise.
2703  */
2704 static int
2705 mrvl_flow_validate(struct rte_eth_dev *dev,
2706                    const struct rte_flow_attr *attr,
2707                    const struct rte_flow_item pattern[],
2708                    const struct rte_flow_action actions[],
2709                    struct rte_flow_error *error)
2710 {
2711         static struct rte_flow *flow;
2712
2713         flow = mrvl_flow_create(dev, attr, pattern, actions, error);
2714         if (!flow)
2715                 return -rte_errno;
2716
2717         mrvl_flow_destroy(dev, flow, error);
2718
2719         return 0;
2720 }
2721
2722 /**
2723  * DPDK flow flush callback called when flows are to be flushed.
2724  *
2725  * @param dev Pointer to the device.
2726  * @param error Pointer to the flow error.
2727  * @returns 0 in case of success, negative value otherwise.
2728  */
2729 static int
2730 mrvl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
2731 {
2732         struct mrvl_priv *priv = dev->data->dev_private;
2733
2734         while (!LIST_EMPTY(&priv->flows)) {
2735                 struct rte_flow *flow = LIST_FIRST(&priv->flows);
2736                 int ret = mrvl_flow_remove(priv, flow, error);
2737                 if (ret)
2738                         return ret;
2739
2740                 LIST_REMOVE(flow, next);
2741                 rte_free(flow);
2742         }
2743
2744         return 0;
2745 }
2746
2747 /**
2748  * DPDK flow isolate callback called to isolate port.
2749  *
2750  * @param dev Pointer to the device.
2751  * @param enable Pass 0/1 to disable/enable port isolation.
2752  * @param error Pointer to the flow error.
2753  * @returns 0 in case of success, negative value otherwise.
2754  */
2755 static int
2756 mrvl_flow_isolate(struct rte_eth_dev *dev, int enable,
2757                   struct rte_flow_error *error)
2758 {
2759         struct mrvl_priv *priv = dev->data->dev_private;
2760
2761         if (dev->data->dev_started) {
2762                 rte_flow_error_set(error, EBUSY,
2763                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2764                                    NULL, "Port must be stopped first\n");
2765                 return -rte_errno;
2766         }
2767
2768         priv->isolated = enable;
2769
2770         return 0;
2771 }
2772
2773 const struct rte_flow_ops mrvl_flow_ops = {
2774         .validate = mrvl_flow_validate,
2775         .create = mrvl_flow_create,
2776         .destroy = mrvl_flow_destroy,
2777         .flush = mrvl_flow_flush,
2778         .isolate = mrvl_flow_isolate
2779 };