net/mrvl: rename PMD as mvpp2
[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                 RTE_LOG(WARNING, PMD, "eth type mask is ignored\n");
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         if (mask->tpid) {
1095                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1096                                    NULL, "Not supported by classifier\n");
1097                 return -rte_errno;
1098         }
1099
1100         m = rte_be_to_cpu_16(mask->tci);
1101         if (m & MRVL_VLAN_ID_MASK) {
1102                 RTE_LOG(WARNING, PMD, "vlan id mask is ignored\n");
1103                 ret = mrvl_parse_vlan_id(spec, mask, flow);
1104                 if (ret)
1105                         goto out;
1106         }
1107
1108         if (m & MRVL_VLAN_PRI_MASK) {
1109                 RTE_LOG(WARNING, PMD, "vlan pri mask is ignored\n");
1110                 ret = mrvl_parse_vlan_pri(spec, mask, flow);
1111                 if (ret)
1112                         goto out;
1113         }
1114
1115         return 0;
1116 out:
1117         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1118                            "Reached maximum number of fields in cls tbl key\n");
1119         return -rte_errno;
1120 }
1121
1122 /**
1123  * Parse ipv4 flow item.
1124  *
1125  * @param item Pointer to the flow item.
1126  * @param flow Pointer to the flow.
1127  * @param error Pointer to the flow error.
1128  * @param fields Pointer to the parsed parsed fields enum.
1129  * @returns 0 on success, negative value otherwise.
1130  */
1131 static int
1132 mrvl_parse_ip4(const struct rte_flow_item *item,
1133                struct rte_flow *flow,
1134                struct rte_flow_error *error)
1135 {
1136         const struct rte_flow_item_ipv4 *spec = NULL, *mask = NULL;
1137         int ret;
1138
1139         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1140                               &rte_flow_item_ipv4_mask,
1141                               sizeof(struct rte_flow_item_ipv4), error);
1142         if (ret)
1143                 return ret;
1144
1145         if (mask->hdr.version_ihl ||
1146             mask->hdr.total_length ||
1147             mask->hdr.packet_id ||
1148             mask->hdr.fragment_offset ||
1149             mask->hdr.time_to_live ||
1150             mask->hdr.hdr_checksum) {
1151                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1152                                    NULL, "Not supported by classifier\n");
1153                 return -rte_errno;
1154         }
1155
1156         if (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) {
1157                 ret = mrvl_parse_ip4_dscp(spec, mask, flow);
1158                 if (ret)
1159                         goto out;
1160         }
1161
1162         if (mask->hdr.src_addr) {
1163                 ret = mrvl_parse_ip4_sip(spec, mask, flow);
1164                 if (ret)
1165                         goto out;
1166         }
1167
1168         if (mask->hdr.dst_addr) {
1169                 ret = mrvl_parse_ip4_dip(spec, mask, flow);
1170                 if (ret)
1171                         goto out;
1172         }
1173
1174         if (mask->hdr.next_proto_id) {
1175                 RTE_LOG(WARNING, PMD, "next proto id mask is ignored\n");
1176                 ret = mrvl_parse_ip4_proto(spec, mask, flow);
1177                 if (ret)
1178                         goto out;
1179         }
1180
1181         return 0;
1182 out:
1183         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1184                            "Reached maximum number of fields in cls tbl key\n");
1185         return -rte_errno;
1186 }
1187
1188 /**
1189  * Parse ipv6 flow item.
1190  *
1191  * @param item Pointer to the flow item.
1192  * @param flow Pointer to the flow.
1193  * @param error Pointer to the flow error.
1194  * @param fields Pointer to the parsed parsed fields enum.
1195  * @returns 0 on success, negative value otherwise.
1196  */
1197 static int
1198 mrvl_parse_ip6(const struct rte_flow_item *item,
1199                struct rte_flow *flow,
1200                struct rte_flow_error *error)
1201 {
1202         const struct rte_flow_item_ipv6 *spec = NULL, *mask = NULL;
1203         struct ipv6_hdr zero;
1204         uint32_t flow_mask;
1205         int ret;
1206
1207         ret = mrvl_parse_init(item, (const void **)&spec,
1208                               (const void **)&mask,
1209                               &rte_flow_item_ipv6_mask,
1210                               sizeof(struct rte_flow_item_ipv6),
1211                               error);
1212         if (ret)
1213                 return ret;
1214
1215         memset(&zero, 0, sizeof(zero));
1216
1217         if (mask->hdr.payload_len ||
1218             mask->hdr.hop_limits) {
1219                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1220                                    NULL, "Not supported by classifier\n");
1221                 return -rte_errno;
1222         }
1223
1224         if (memcmp(mask->hdr.src_addr,
1225                    zero.src_addr, sizeof(mask->hdr.src_addr))) {
1226                 ret = mrvl_parse_ip6_sip(spec, mask, flow);
1227                 if (ret)
1228                         goto out;
1229         }
1230
1231         if (memcmp(mask->hdr.dst_addr,
1232                    zero.dst_addr, sizeof(mask->hdr.dst_addr))) {
1233                 ret = mrvl_parse_ip6_dip(spec, mask, flow);
1234                 if (ret)
1235                         goto out;
1236         }
1237
1238         flow_mask = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK;
1239         if (flow_mask) {
1240                 ret = mrvl_parse_ip6_flow(spec, mask, flow);
1241                 if (ret)
1242                         goto out;
1243         }
1244
1245         if (mask->hdr.proto) {
1246                 RTE_LOG(WARNING, PMD, "next header mask is ignored\n");
1247                 ret = mrvl_parse_ip6_next_hdr(spec, mask, flow);
1248                 if (ret)
1249                         goto out;
1250         }
1251
1252         return 0;
1253 out:
1254         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1255                            "Reached maximum number of fields in cls tbl key\n");
1256         return -rte_errno;
1257 }
1258
1259 /**
1260  * Parse tcp flow item.
1261  *
1262  * @param item Pointer to the flow item.
1263  * @param flow Pointer to the flow.
1264  * @param error Pointer to the flow error.
1265  * @param fields Pointer to the parsed parsed fields enum.
1266  * @returns 0 on success, negative value otherwise.
1267  */
1268 static int
1269 mrvl_parse_tcp(const struct rte_flow_item *item,
1270                struct rte_flow *flow,
1271                struct rte_flow_error *error)
1272 {
1273         const struct rte_flow_item_tcp *spec = NULL, *mask = NULL;
1274         int ret;
1275
1276         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1277                               &rte_flow_item_ipv4_mask,
1278                               sizeof(struct rte_flow_item_ipv4), error);
1279         if (ret)
1280                 return ret;
1281
1282         if (mask->hdr.sent_seq ||
1283             mask->hdr.recv_ack ||
1284             mask->hdr.data_off ||
1285             mask->hdr.tcp_flags ||
1286             mask->hdr.rx_win ||
1287             mask->hdr.cksum ||
1288             mask->hdr.tcp_urp) {
1289                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1290                                    NULL, "Not supported by classifier\n");
1291                 return -rte_errno;
1292         }
1293
1294         if (mask->hdr.src_port) {
1295                 RTE_LOG(WARNING, PMD, "tcp sport mask is ignored\n");
1296                 ret = mrvl_parse_tcp_sport(spec, mask, flow);
1297                 if (ret)
1298                         goto out;
1299         }
1300
1301         if (mask->hdr.dst_port) {
1302                 RTE_LOG(WARNING, PMD, "tcp dport mask is ignored\n");
1303                 ret = mrvl_parse_tcp_dport(spec, mask, flow);
1304                 if (ret)
1305                         goto out;
1306         }
1307
1308         return 0;
1309 out:
1310         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1311                            "Reached maximum number of fields in cls tbl key\n");
1312         return -rte_errno;
1313 }
1314
1315 /**
1316  * Parse udp flow item.
1317  *
1318  * @param item Pointer to the flow item.
1319  * @param flow Pointer to the flow.
1320  * @param error Pointer to the flow error.
1321  * @param fields Pointer to the parsed parsed fields enum.
1322  * @returns 0 on success, negative value otherwise.
1323  */
1324 static int
1325 mrvl_parse_udp(const struct rte_flow_item *item,
1326                struct rte_flow *flow,
1327                struct rte_flow_error *error)
1328 {
1329         const struct rte_flow_item_udp *spec = NULL, *mask = NULL;
1330         int ret;
1331
1332         ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1333                               &rte_flow_item_ipv4_mask,
1334                               sizeof(struct rte_flow_item_ipv4), error);
1335         if (ret)
1336                 return ret;
1337
1338         if (mask->hdr.dgram_len ||
1339             mask->hdr.dgram_cksum) {
1340                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1341                                    NULL, "Not supported by classifier\n");
1342                 return -rte_errno;
1343         }
1344
1345         if (mask->hdr.src_port) {
1346                 RTE_LOG(WARNING, PMD, "udp sport mask is ignored\n");
1347                 ret = mrvl_parse_udp_sport(spec, mask, flow);
1348                 if (ret)
1349                         goto out;
1350         }
1351
1352         if (mask->hdr.dst_port) {
1353                 RTE_LOG(WARNING, PMD, "udp dport mask is ignored\n");
1354                 ret = mrvl_parse_udp_dport(spec, mask, flow);
1355                 if (ret)
1356                         goto out;
1357         }
1358
1359         return 0;
1360 out:
1361         rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1362                            "Reached maximum number of fields in cls tbl key\n");
1363         return -rte_errno;
1364 }
1365
1366 /**
1367  * Parse flow pattern composed of the the eth item.
1368  *
1369  * @param pattern Pointer to the flow pattern table.
1370  * @param flow Pointer to the flow.
1371  * @param error Pointer to the flow error.
1372  * @returns 0 in case of success, negative value otherwise.
1373  */
1374 static int
1375 mrvl_parse_pattern_eth(const struct rte_flow_item pattern[],
1376                        struct rte_flow *flow,
1377                        struct rte_flow_error *error)
1378 {
1379         return mrvl_parse_eth(pattern, flow, error);
1380 }
1381
1382 /**
1383  * Parse flow pattern composed of the eth and vlan items.
1384  *
1385  * @param pattern Pointer to the flow pattern table.
1386  * @param flow Pointer to the flow.
1387  * @param error Pointer to the flow error.
1388  * @returns 0 in case of success, negative value otherwise.
1389  */
1390 static int
1391 mrvl_parse_pattern_eth_vlan(const struct rte_flow_item pattern[],
1392                             struct rte_flow *flow,
1393                             struct rte_flow_error *error)
1394 {
1395         const struct rte_flow_item *item = mrvl_next_item(pattern);
1396         int ret;
1397
1398         ret = mrvl_parse_eth(item, flow, error);
1399         if (ret)
1400                 return ret;
1401
1402         item = mrvl_next_item(item + 1);
1403
1404         return mrvl_parse_vlan(item, flow, error);
1405 }
1406
1407 /**
1408  * Parse flow pattern composed of the eth, vlan and ip4/ip6 items.
1409  *
1410  * @param pattern Pointer to the flow pattern table.
1411  * @param flow Pointer to the flow.
1412  * @param error Pointer to the flow error.
1413  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1414  * @returns 0 in case of success, negative value otherwise.
1415  */
1416 static int
1417 mrvl_parse_pattern_eth_vlan_ip4_ip6(const struct rte_flow_item pattern[],
1418                                     struct rte_flow *flow,
1419                                     struct rte_flow_error *error, int ip6)
1420 {
1421         const struct rte_flow_item *item = mrvl_next_item(pattern);
1422         int ret;
1423
1424         ret = mrvl_parse_eth(item, flow, error);
1425         if (ret)
1426                 return ret;
1427
1428         item = mrvl_next_item(item + 1);
1429         ret = mrvl_parse_vlan(item, flow, error);
1430         if (ret)
1431                 return ret;
1432
1433         item = mrvl_next_item(item + 1);
1434
1435         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1436                      mrvl_parse_ip4(item, flow, error);
1437 }
1438
1439 /**
1440  * Parse flow pattern composed of the eth, vlan and ipv4 items.
1441  *
1442  * @param pattern Pointer to the flow pattern table.
1443  * @param flow Pointer to the flow.
1444  * @param error Pointer to the flow error.
1445  * @returns 0 in case of success, negative value otherwise.
1446  */
1447 static int
1448 mrvl_parse_pattern_eth_vlan_ip4(const struct rte_flow_item pattern[],
1449                                 struct rte_flow *flow,
1450                                 struct rte_flow_error *error)
1451 {
1452         return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 0);
1453 }
1454
1455 /**
1456  * Parse flow pattern composed of the eth, vlan and ipv6 items.
1457  *
1458  * @param pattern Pointer to the flow pattern table.
1459  * @param flow Pointer to the flow.
1460  * @param error Pointer to the flow error.
1461  * @returns 0 in case of success, negative value otherwise.
1462  */
1463 static int
1464 mrvl_parse_pattern_eth_vlan_ip6(const struct rte_flow_item pattern[],
1465                                 struct rte_flow *flow,
1466                                 struct rte_flow_error *error)
1467 {
1468         return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 1);
1469 }
1470
1471 /**
1472  * Parse flow pattern composed of the eth and ip4/ip6 items.
1473  *
1474  * @param pattern Pointer to the flow pattern table.
1475  * @param flow Pointer to the flow.
1476  * @param error Pointer to the flow error.
1477  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1478  * @returns 0 in case of success, negative value otherwise.
1479  */
1480 static int
1481 mrvl_parse_pattern_eth_ip4_ip6(const struct rte_flow_item pattern[],
1482                                struct rte_flow *flow,
1483                                struct rte_flow_error *error, int ip6)
1484 {
1485         const struct rte_flow_item *item = mrvl_next_item(pattern);
1486         int ret;
1487
1488         ret = mrvl_parse_eth(item, flow, error);
1489         if (ret)
1490                 return ret;
1491
1492         item = mrvl_next_item(item + 1);
1493
1494         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1495                      mrvl_parse_ip4(item, flow, error);
1496 }
1497
1498 /**
1499  * Parse flow pattern composed of the eth and ipv4 items.
1500  *
1501  * @param pattern Pointer to the flow pattern table.
1502  * @param flow Pointer to the flow.
1503  * @param error Pointer to the flow error.
1504  * @returns 0 in case of success, negative value otherwise.
1505  */
1506 static inline int
1507 mrvl_parse_pattern_eth_ip4(const struct rte_flow_item pattern[],
1508                            struct rte_flow *flow,
1509                            struct rte_flow_error *error)
1510 {
1511         return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0);
1512 }
1513
1514 /**
1515  * Parse flow pattern composed of the eth and ipv6 items.
1516  *
1517  * @param pattern Pointer to the flow pattern table.
1518  * @param flow Pointer to the flow.
1519  * @param error Pointer to the flow error.
1520  * @returns 0 in case of success, negative value otherwise.
1521  */
1522 static inline int
1523 mrvl_parse_pattern_eth_ip6(const struct rte_flow_item pattern[],
1524                            struct rte_flow *flow,
1525                            struct rte_flow_error *error)
1526 {
1527         return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1);
1528 }
1529
1530 /**
1531  * Parse flow pattern composed of the eth, ip4 and tcp/udp items.
1532  *
1533  * @param pattern Pointer to the flow pattern table.
1534  * @param flow Pointer to the flow.
1535  * @param error Pointer to the flow error.
1536  * @param tcp 1 to parse tcp item, 0 to parse udp item.
1537  * @returns 0 in case of success, negative value otherwise.
1538  */
1539 static int
1540 mrvl_parse_pattern_eth_ip4_tcp_udp(const struct rte_flow_item pattern[],
1541                                    struct rte_flow *flow,
1542                                    struct rte_flow_error *error, int tcp)
1543 {
1544         const struct rte_flow_item *item = mrvl_next_item(pattern);
1545         int ret;
1546
1547         ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0);
1548         if (ret)
1549                 return ret;
1550
1551         item = mrvl_next_item(item + 1);
1552         item = mrvl_next_item(item + 1);
1553
1554         if (tcp)
1555                 return mrvl_parse_tcp(item, flow, error);
1556
1557         return mrvl_parse_udp(item, flow, error);
1558 }
1559
1560 /**
1561  * Parse flow pattern composed of the eth, ipv4 and tcp items.
1562  *
1563  * @param pattern Pointer to the flow pattern table.
1564  * @param flow Pointer to the flow.
1565  * @param error Pointer to the flow error.
1566  * @returns 0 in case of success, negative value otherwise.
1567  */
1568 static inline int
1569 mrvl_parse_pattern_eth_ip4_tcp(const struct rte_flow_item pattern[],
1570                                struct rte_flow *flow,
1571                                struct rte_flow_error *error)
1572 {
1573         return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 1);
1574 }
1575
1576 /**
1577  * Parse flow pattern composed of the eth, ipv4 and udp items.
1578  *
1579  * @param pattern Pointer to the flow pattern table.
1580  * @param flow Pointer to the flow.
1581  * @param error Pointer to the flow error.
1582  * @returns 0 in case of success, negative value otherwise.
1583  */
1584 static inline int
1585 mrvl_parse_pattern_eth_ip4_udp(const struct rte_flow_item pattern[],
1586                                struct rte_flow *flow,
1587                                struct rte_flow_error *error)
1588 {
1589         return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 0);
1590 }
1591
1592 /**
1593  * Parse flow pattern composed of the eth, ipv6 and tcp/udp items.
1594  *
1595  * @param pattern Pointer to the flow pattern table.
1596  * @param flow Pointer to the flow.
1597  * @param error Pointer to the flow error.
1598  * @param tcp 1 to parse tcp item, 0 to parse udp item.
1599  * @returns 0 in case of success, negative value otherwise.
1600  */
1601 static int
1602 mrvl_parse_pattern_eth_ip6_tcp_udp(const struct rte_flow_item pattern[],
1603                                    struct rte_flow *flow,
1604                                    struct rte_flow_error *error, int tcp)
1605 {
1606         const struct rte_flow_item *item = mrvl_next_item(pattern);
1607         int ret;
1608
1609         ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1);
1610         if (ret)
1611                 return ret;
1612
1613         item = mrvl_next_item(item + 1);
1614         item = mrvl_next_item(item + 1);
1615
1616         if (tcp)
1617                 return mrvl_parse_tcp(item, flow, error);
1618
1619         return mrvl_parse_udp(item, flow, error);
1620 }
1621
1622 /**
1623  * Parse flow pattern composed of the eth, ipv6 and tcp items.
1624  *
1625  * @param pattern Pointer to the flow pattern table.
1626  * @param flow Pointer to the flow.
1627  * @param error Pointer to the flow error.
1628  * @returns 0 in case of success, negative value otherwise.
1629  */
1630 static inline int
1631 mrvl_parse_pattern_eth_ip6_tcp(const struct rte_flow_item pattern[],
1632                                struct rte_flow *flow,
1633                                struct rte_flow_error *error)
1634 {
1635         return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 1);
1636 }
1637
1638 /**
1639  * Parse flow pattern composed of the eth, ipv6 and udp items.
1640  *
1641  * @param pattern Pointer to the flow pattern table.
1642  * @param flow Pointer to the flow.
1643  * @param error Pointer to the flow error.
1644  * @returns 0 in case of success, negative value otherwise.
1645  */
1646 static inline int
1647 mrvl_parse_pattern_eth_ip6_udp(const struct rte_flow_item pattern[],
1648                                struct rte_flow *flow,
1649                                struct rte_flow_error *error)
1650 {
1651         return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 0);
1652 }
1653
1654 /**
1655  * Parse flow pattern composed of the vlan item.
1656  *
1657  * @param pattern Pointer to the flow pattern table.
1658  * @param flow Pointer to the flow.
1659  * @param error Pointer to the flow error.
1660  * @returns 0 in case of success, negative value otherwise.
1661  */
1662 static int
1663 mrvl_parse_pattern_vlan(const struct rte_flow_item pattern[],
1664                             struct rte_flow *flow,
1665                             struct rte_flow_error *error)
1666 {
1667         const struct rte_flow_item *item = mrvl_next_item(pattern);
1668
1669         return mrvl_parse_vlan(item, flow, error);
1670 }
1671
1672 /**
1673  * Parse flow pattern composed of the vlan and ip4/ip6 items.
1674  *
1675  * @param pattern Pointer to the flow pattern table.
1676  * @param flow Pointer to the flow.
1677  * @param error Pointer to the flow error.
1678  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1679  * @returns 0 in case of success, negative value otherwise.
1680  */
1681 static int
1682 mrvl_parse_pattern_vlan_ip4_ip6(const struct rte_flow_item pattern[],
1683                                 struct rte_flow *flow,
1684                                 struct rte_flow_error *error, int ip6)
1685 {
1686         const struct rte_flow_item *item = mrvl_next_item(pattern);
1687         int ret;
1688
1689         ret = mrvl_parse_vlan(item, flow, error);
1690         if (ret)
1691                 return ret;
1692
1693         item = mrvl_next_item(item + 1);
1694
1695         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1696                      mrvl_parse_ip4(item, flow, error);
1697 }
1698
1699 /**
1700  * Parse flow pattern composed of the vlan and ipv4 items.
1701  *
1702  * @param pattern Pointer to the flow pattern table.
1703  * @param flow Pointer to the flow.
1704  * @param error Pointer to the flow error.
1705  * @returns 0 in case of success, negative value otherwise.
1706  */
1707 static inline int
1708 mrvl_parse_pattern_vlan_ip4(const struct rte_flow_item pattern[],
1709                             struct rte_flow *flow,
1710                             struct rte_flow_error *error)
1711 {
1712         return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0);
1713 }
1714
1715 /**
1716  * Parse flow pattern composed of the vlan, ipv4 and tcp/udp items.
1717  *
1718  * @param pattern Pointer to the flow pattern table.
1719  * @param flow Pointer to the flow.
1720  * @param error Pointer to the flow error.
1721  * @returns 0 in case of success, negative value otherwise.
1722  */
1723 static int
1724 mrvl_parse_pattern_vlan_ip_tcp_udp(const struct rte_flow_item pattern[],
1725                                    struct rte_flow *flow,
1726                                    struct rte_flow_error *error, int tcp)
1727 {
1728         const struct rte_flow_item *item = mrvl_next_item(pattern);
1729         int ret;
1730
1731         ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0);
1732         if (ret)
1733                 return ret;
1734
1735         item = mrvl_next_item(item + 1);
1736         item = mrvl_next_item(item + 1);
1737
1738         if (tcp)
1739                 return mrvl_parse_tcp(item, flow, error);
1740
1741         return mrvl_parse_udp(item, flow, error);
1742 }
1743
1744 /**
1745  * Parse flow pattern composed of the vlan, ipv4 and tcp items.
1746  *
1747  * @param pattern Pointer to the flow pattern table.
1748  * @param flow Pointer to the flow.
1749  * @param error Pointer to the flow error.
1750  * @returns 0 in case of success, negative value otherwise.
1751  */
1752 static inline int
1753 mrvl_parse_pattern_vlan_ip_tcp(const struct rte_flow_item pattern[],
1754                                struct rte_flow *flow,
1755                                struct rte_flow_error *error)
1756 {
1757         return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 1);
1758 }
1759
1760 /**
1761  * Parse flow pattern composed of the vlan, ipv4 and udp items.
1762  *
1763  * @param pattern Pointer to the flow pattern table.
1764  * @param flow Pointer to the flow.
1765  * @param error Pointer to the flow error.
1766  * @returns 0 in case of success, negative value otherwise.
1767  */
1768 static inline int
1769 mrvl_parse_pattern_vlan_ip_udp(const struct rte_flow_item pattern[],
1770                                struct rte_flow *flow,
1771                                struct rte_flow_error *error)
1772 {
1773         return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 0);
1774 }
1775
1776 /**
1777  * Parse flow pattern composed of the vlan and ipv6 items.
1778  *
1779  * @param pattern Pointer to the flow pattern table.
1780  * @param flow Pointer to the flow.
1781  * @param error Pointer to the flow error.
1782  * @returns 0 in case of success, negative value otherwise.
1783  */
1784 static inline int
1785 mrvl_parse_pattern_vlan_ip6(const struct rte_flow_item pattern[],
1786                             struct rte_flow *flow,
1787                             struct rte_flow_error *error)
1788 {
1789         return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1);
1790 }
1791
1792 /**
1793  * Parse flow pattern composed of the vlan, ipv6 and tcp/udp items.
1794  *
1795  * @param pattern Pointer to the flow pattern table.
1796  * @param flow Pointer to the flow.
1797  * @param error Pointer to the flow error.
1798  * @returns 0 in case of success, negative value otherwise.
1799  */
1800 static int
1801 mrvl_parse_pattern_vlan_ip6_tcp_udp(const struct rte_flow_item pattern[],
1802                                     struct rte_flow *flow,
1803                                     struct rte_flow_error *error, int tcp)
1804 {
1805         const struct rte_flow_item *item = mrvl_next_item(pattern);
1806         int ret;
1807
1808         ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1);
1809         if (ret)
1810                 return ret;
1811
1812         item = mrvl_next_item(item + 1);
1813         item = mrvl_next_item(item + 1);
1814
1815         if (tcp)
1816                 return mrvl_parse_tcp(item, flow, error);
1817
1818         return mrvl_parse_udp(item, flow, error);
1819 }
1820
1821 /**
1822  * Parse flow pattern composed of the vlan, ipv6 and tcp items.
1823  *
1824  * @param pattern Pointer to the flow pattern table.
1825  * @param flow Pointer to the flow.
1826  * @param error Pointer to the flow error.
1827  * @returns 0 in case of success, negative value otherwise.
1828  */
1829 static inline int
1830 mrvl_parse_pattern_vlan_ip6_tcp(const struct rte_flow_item pattern[],
1831                                 struct rte_flow *flow,
1832                                 struct rte_flow_error *error)
1833 {
1834         return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 1);
1835 }
1836
1837 /**
1838  * Parse flow pattern composed of the vlan, ipv6 and udp items.
1839  *
1840  * @param pattern Pointer to the flow pattern table.
1841  * @param flow Pointer to the flow.
1842  * @param error Pointer to the flow error.
1843  * @returns 0 in case of success, negative value otherwise.
1844  */
1845 static inline int
1846 mrvl_parse_pattern_vlan_ip6_udp(const struct rte_flow_item pattern[],
1847                                 struct rte_flow *flow,
1848                                 struct rte_flow_error *error)
1849 {
1850         return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 0);
1851 }
1852
1853 /**
1854  * Parse flow pattern composed of the ip4/ip6 item.
1855  *
1856  * @param pattern Pointer to the flow pattern table.
1857  * @param flow Pointer to the flow.
1858  * @param error Pointer to the flow error.
1859  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1860  * @returns 0 in case of success, negative value otherwise.
1861  */
1862 static int
1863 mrvl_parse_pattern_ip4_ip6(const struct rte_flow_item pattern[],
1864                        struct rte_flow *flow,
1865                        struct rte_flow_error *error, int ip6)
1866 {
1867         const struct rte_flow_item *item = mrvl_next_item(pattern);
1868
1869         return ip6 ? mrvl_parse_ip6(item, flow, error) :
1870                      mrvl_parse_ip4(item, flow, error);
1871 }
1872
1873 /**
1874  * Parse flow pattern composed of the ipv4 item.
1875  *
1876  * @param pattern Pointer to the flow pattern table.
1877  * @param flow Pointer to the flow.
1878  * @param error Pointer to the flow error.
1879  * @returns 0 in case of success, negative value otherwise.
1880  */
1881 static inline int
1882 mrvl_parse_pattern_ip4(const struct rte_flow_item pattern[],
1883                        struct rte_flow *flow,
1884                        struct rte_flow_error *error)
1885 {
1886         return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 0);
1887 }
1888
1889 /**
1890  * Parse flow pattern composed of the ipv6 item.
1891  *
1892  * @param pattern Pointer to the flow pattern table.
1893  * @param flow Pointer to the flow.
1894  * @param error Pointer to the flow error.
1895  * @returns 0 in case of success, negative value otherwise.
1896  */
1897 static inline int
1898 mrvl_parse_pattern_ip6(const struct rte_flow_item pattern[],
1899                        struct rte_flow *flow,
1900                        struct rte_flow_error *error)
1901 {
1902         return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 1);
1903 }
1904
1905 /**
1906  * Parse flow pattern composed of the ip4/ip6 and tcp items.
1907  *
1908  * @param pattern Pointer to the flow pattern table.
1909  * @param flow Pointer to the flow.
1910  * @param error Pointer to the flow error.
1911  * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1912  * @returns 0 in case of success, negative value otherwise.
1913  */
1914 static int
1915 mrvl_parse_pattern_ip4_ip6_tcp(const struct rte_flow_item pattern[],
1916                            struct rte_flow *flow,
1917                            struct rte_flow_error *error, int ip6)
1918 {
1919         const struct rte_flow_item *item = mrvl_next_item(pattern);
1920         int ret;
1921
1922         ret = ip6 ? mrvl_parse_ip6(item, flow, error) :
1923                     mrvl_parse_ip4(item, flow, error);
1924         if (ret)
1925                 return ret;
1926
1927         item = mrvl_next_item(item + 1);
1928
1929         return mrvl_parse_tcp(item, flow, error);
1930 }
1931
1932 /**
1933  * Parse flow pattern composed of the ipv4 and tcp items.
1934  *
1935  * @param pattern Pointer to the flow pattern table.
1936  * @param flow Pointer to the flow.
1937  * @param error Pointer to the flow error.
1938  * @returns 0 in case of success, negative value otherwise.
1939  */
1940 static inline int
1941 mrvl_parse_pattern_ip4_tcp(const struct rte_flow_item pattern[],
1942                            struct rte_flow *flow,
1943                            struct rte_flow_error *error)
1944 {
1945         return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 0);
1946 }
1947
1948 /**
1949  * Parse flow pattern composed of the ipv6 and tcp items.
1950  *
1951  * @param pattern Pointer to the flow pattern table.
1952  * @param flow Pointer to the flow.
1953  * @param error Pointer to the flow error.
1954  * @returns 0 in case of success, negative value otherwise.
1955  */
1956 static inline int
1957 mrvl_parse_pattern_ip6_tcp(const struct rte_flow_item pattern[],
1958                            struct rte_flow *flow,
1959                            struct rte_flow_error *error)
1960 {
1961         return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 1);
1962 }
1963
1964 /**
1965  * Parse flow pattern composed of the ipv4/ipv6 and udp items.
1966  *
1967  * @param pattern Pointer to the flow pattern table.
1968  * @param flow Pointer to the flow.
1969  * @param error Pointer to the flow error.
1970  * @returns 0 in case of success, negative value otherwise.
1971  */
1972 static int
1973 mrvl_parse_pattern_ip4_ip6_udp(const struct rte_flow_item pattern[],
1974                            struct rte_flow *flow,
1975                            struct rte_flow_error *error, int ip6)
1976 {
1977         const struct rte_flow_item *item = mrvl_next_item(pattern);
1978         int ret;
1979
1980         ret = ip6 ? mrvl_parse_ip6(item, flow, error) :
1981                     mrvl_parse_ip4(item, flow, error);
1982         if (ret)
1983                 return ret;
1984
1985         item = mrvl_next_item(item + 1);
1986
1987         return mrvl_parse_udp(item, flow, error);
1988 }
1989
1990 /**
1991  * Parse flow pattern composed of the ipv4 and udp items.
1992  *
1993  * @param pattern Pointer to the flow pattern table.
1994  * @param flow Pointer to the flow.
1995  * @param error Pointer to the flow error.
1996  * @returns 0 in case of success, negative value otherwise.
1997  */
1998 static inline int
1999 mrvl_parse_pattern_ip4_udp(const struct rte_flow_item pattern[],
2000                            struct rte_flow *flow,
2001                            struct rte_flow_error *error)
2002 {
2003         return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 0);
2004 }
2005
2006 /**
2007  * Parse flow pattern composed of the ipv6 and udp items.
2008  *
2009  * @param pattern Pointer to the flow pattern table.
2010  * @param flow Pointer to the flow.
2011  * @param error Pointer to the flow error.
2012  * @returns 0 in case of success, negative value otherwise.
2013  */
2014 static inline int
2015 mrvl_parse_pattern_ip6_udp(const struct rte_flow_item pattern[],
2016                            struct rte_flow *flow,
2017                            struct rte_flow_error *error)
2018 {
2019         return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 1);
2020 }
2021
2022 /**
2023  * Parse flow pattern composed of the tcp item.
2024  *
2025  * @param pattern Pointer to the flow pattern table.
2026  * @param flow Pointer to the flow.
2027  * @param error Pointer to the flow error.
2028  * @returns 0 in case of success, negative value otherwise.
2029  */
2030 static int
2031 mrvl_parse_pattern_tcp(const struct rte_flow_item pattern[],
2032                        struct rte_flow *flow,
2033                        struct rte_flow_error *error)
2034 {
2035         const struct rte_flow_item *item = mrvl_next_item(pattern);
2036
2037         return mrvl_parse_tcp(item, flow, error);
2038 }
2039
2040 /**
2041  * Parse flow pattern composed of the udp item.
2042  *
2043  * @param pattern Pointer to the flow pattern table.
2044  * @param flow Pointer to the flow.
2045  * @param error Pointer to the flow error.
2046  * @returns 0 in case of success, negative value otherwise.
2047  */
2048 static int
2049 mrvl_parse_pattern_udp(const struct rte_flow_item pattern[],
2050                        struct rte_flow *flow,
2051                        struct rte_flow_error *error)
2052 {
2053         const struct rte_flow_item *item = mrvl_next_item(pattern);
2054
2055         return mrvl_parse_udp(item, flow, error);
2056 }
2057
2058 /**
2059  * Structure used to map specific flow pattern to the pattern parse callback
2060  * which will iterate over each pattern item and extract relevant data.
2061  */
2062 static const struct {
2063         const enum rte_flow_item_type *pattern;
2064         int (*parse)(const struct rte_flow_item pattern[],
2065                 struct rte_flow *flow,
2066                 struct rte_flow_error *error);
2067 } mrvl_patterns[] = {
2068         { pattern_eth, mrvl_parse_pattern_eth },
2069         { pattern_eth_vlan, mrvl_parse_pattern_eth_vlan },
2070         { pattern_eth_vlan_ip, mrvl_parse_pattern_eth_vlan_ip4 },
2071         { pattern_eth_vlan_ip6, mrvl_parse_pattern_eth_vlan_ip6 },
2072         { pattern_eth_ip4, mrvl_parse_pattern_eth_ip4 },
2073         { pattern_eth_ip4_tcp, mrvl_parse_pattern_eth_ip4_tcp },
2074         { pattern_eth_ip4_udp, mrvl_parse_pattern_eth_ip4_udp },
2075         { pattern_eth_ip6, mrvl_parse_pattern_eth_ip6 },
2076         { pattern_eth_ip6_tcp, mrvl_parse_pattern_eth_ip6_tcp },
2077         { pattern_eth_ip6_udp, mrvl_parse_pattern_eth_ip6_udp },
2078         { pattern_vlan, mrvl_parse_pattern_vlan },
2079         { pattern_vlan_ip, mrvl_parse_pattern_vlan_ip4 },
2080         { pattern_vlan_ip_tcp, mrvl_parse_pattern_vlan_ip_tcp },
2081         { pattern_vlan_ip_udp, mrvl_parse_pattern_vlan_ip_udp },
2082         { pattern_vlan_ip6, mrvl_parse_pattern_vlan_ip6 },
2083         { pattern_vlan_ip6_tcp, mrvl_parse_pattern_vlan_ip6_tcp },
2084         { pattern_vlan_ip6_udp, mrvl_parse_pattern_vlan_ip6_udp },
2085         { pattern_ip, mrvl_parse_pattern_ip4 },
2086         { pattern_ip_tcp, mrvl_parse_pattern_ip4_tcp },
2087         { pattern_ip_udp, mrvl_parse_pattern_ip4_udp },
2088         { pattern_ip6, mrvl_parse_pattern_ip6 },
2089         { pattern_ip6_tcp, mrvl_parse_pattern_ip6_tcp },
2090         { pattern_ip6_udp, mrvl_parse_pattern_ip6_udp },
2091         { pattern_tcp, mrvl_parse_pattern_tcp },
2092         { pattern_udp, mrvl_parse_pattern_udp }
2093 };
2094
2095 /**
2096  * Check whether provided pattern matches any of the supported ones.
2097  *
2098  * @param type_pattern Pointer to the pattern type.
2099  * @param item_pattern Pointer to the flow pattern.
2100  * @returns 1 in case of success, 0 value otherwise.
2101  */
2102 static int
2103 mrvl_patterns_match(const enum rte_flow_item_type *type_pattern,
2104                     const struct rte_flow_item *item_pattern)
2105 {
2106         const enum rte_flow_item_type *type = type_pattern;
2107         const struct rte_flow_item *item = item_pattern;
2108
2109         for (;;) {
2110                 if (item->type == RTE_FLOW_ITEM_TYPE_VOID) {
2111                         item++;
2112                         continue;
2113                 }
2114
2115                 if (*type == RTE_FLOW_ITEM_TYPE_END ||
2116                     item->type == RTE_FLOW_ITEM_TYPE_END)
2117                         break;
2118
2119                 if (*type != item->type)
2120                         break;
2121
2122                 item++;
2123                 type++;
2124         }
2125
2126         return *type == item->type;
2127 }
2128
2129 /**
2130  * Parse flow attribute.
2131  *
2132  * This will check whether the provided attribute's flags are supported.
2133  *
2134  * @param priv Unused
2135  * @param attr Pointer to the flow attribute.
2136  * @param flow Unused
2137  * @param error Pointer to the flow error.
2138  * @returns 0 in case of success, negative value otherwise.
2139  */
2140 static int
2141 mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused,
2142                      const struct rte_flow_attr *attr,
2143                      struct rte_flow *flow __rte_unused,
2144                      struct rte_flow_error *error)
2145 {
2146         if (!attr) {
2147                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR,
2148                                    NULL, "NULL attribute");
2149                 return -rte_errno;
2150         }
2151
2152         if (attr->group) {
2153                 rte_flow_error_set(error, ENOTSUP,
2154                                    RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL,
2155                                    "Groups are not supported");
2156                 return -rte_errno;
2157         }
2158         if (attr->priority) {
2159                 rte_flow_error_set(error, ENOTSUP,
2160                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL,
2161                                    "Priorities are not supported");
2162                 return -rte_errno;
2163         }
2164         if (!attr->ingress) {
2165                 rte_flow_error_set(error, ENOTSUP,
2166                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL,
2167                                    "Only ingress is supported");
2168                 return -rte_errno;
2169         }
2170         if (attr->egress) {
2171                 rte_flow_error_set(error, ENOTSUP,
2172                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL,
2173                                    "Egress is not supported");
2174                 return -rte_errno;
2175         }
2176
2177         return 0;
2178 }
2179
2180 /**
2181  * Parse flow pattern.
2182  *
2183  * Specific classifier rule will be created as well.
2184  *
2185  * @param priv Unused
2186  * @param pattern Pointer to the flow pattern.
2187  * @param flow Pointer to the flow.
2188  * @param error Pointer to the flow error.
2189  * @returns 0 in case of success, negative value otherwise.
2190  */
2191 static int
2192 mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused,
2193                         const struct rte_flow_item pattern[],
2194                         struct rte_flow *flow,
2195                         struct rte_flow_error *error)
2196 {
2197         unsigned int i;
2198         int ret;
2199
2200         for (i = 0; i < RTE_DIM(mrvl_patterns); i++) {
2201                 if (!mrvl_patterns_match(mrvl_patterns[i].pattern, pattern))
2202                         continue;
2203
2204                 ret = mrvl_patterns[i].parse(pattern, flow, error);
2205                 if (ret)
2206                         mrvl_free_all_key_mask(&flow->rule);
2207
2208                 return ret;
2209         }
2210
2211         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, NULL,
2212                            "Unsupported pattern");
2213
2214         return -rte_errno;
2215 }
2216
2217 /**
2218  * Parse flow actions.
2219  *
2220  * @param priv Pointer to the port's private data.
2221  * @param actions Pointer the action table.
2222  * @param flow Pointer to the flow.
2223  * @param error Pointer to the flow error.
2224  * @returns 0 in case of success, negative value otherwise.
2225  */
2226 static int
2227 mrvl_flow_parse_actions(struct mrvl_priv *priv,
2228                         const struct rte_flow_action actions[],
2229                         struct rte_flow *flow,
2230                         struct rte_flow_error *error)
2231 {
2232         const struct rte_flow_action *action = actions;
2233         int specified = 0;
2234
2235         for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
2236                 if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
2237                         continue;
2238
2239                 if (action->type == RTE_FLOW_ACTION_TYPE_DROP) {
2240                         flow->cos.ppio = priv->ppio;
2241                         flow->cos.tc = 0;
2242                         flow->action.type = PP2_CLS_TBL_ACT_DROP;
2243                         flow->action.cos = &flow->cos;
2244                         specified++;
2245                 } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
2246                         const struct rte_flow_action_queue *q =
2247                                 (const struct rte_flow_action_queue *)
2248                                 action->conf;
2249
2250                         if (q->index > priv->nb_rx_queues) {
2251                                 rte_flow_error_set(error, EINVAL,
2252                                                 RTE_FLOW_ERROR_TYPE_ACTION,
2253                                                 NULL,
2254                                                 "Queue index out of range");
2255                                 return -rte_errno;
2256                         }
2257
2258                         if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) {
2259                                 /*
2260                                  * Unknown TC mapping, mapping will not have
2261                                  * a correct queue.
2262                                  */
2263                                 RTE_LOG(ERR, PMD,
2264                                         "Unknown TC mapping for queue %hu eth%hhu\n",
2265                                         q->index, priv->ppio_id);
2266
2267                                 rte_flow_error_set(error, EFAULT,
2268                                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2269                                                 NULL, NULL);
2270                                 return -rte_errno;
2271                         }
2272
2273                         RTE_LOG(DEBUG, PMD,
2274                                 "Action: Assign packets to queue %d, tc:%d, q:%d\n",
2275                                 q->index, priv->rxq_map[q->index].tc,
2276                                 priv->rxq_map[q->index].inq);
2277
2278                         flow->cos.ppio = priv->ppio;
2279                         flow->cos.tc = priv->rxq_map[q->index].tc;
2280                         flow->action.type = PP2_CLS_TBL_ACT_DONE;
2281                         flow->action.cos = &flow->cos;
2282                         specified++;
2283                 } else {
2284                         rte_flow_error_set(error, ENOTSUP,
2285                                            RTE_FLOW_ERROR_TYPE_ACTION, NULL,
2286                                            "Action not supported");
2287                         return -rte_errno;
2288                 }
2289
2290         }
2291
2292         if (!specified) {
2293                 rte_flow_error_set(error, EINVAL,
2294                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2295                                    NULL, "Action not specified");
2296                 return -rte_errno;
2297         }
2298
2299         return 0;
2300 }
2301
2302 /**
2303  * Parse flow attribute, pattern and actions.
2304  *
2305  * @param priv Pointer to the port's private data.
2306  * @param attr Pointer to the flow attribute.
2307  * @param pattern Pointer to the flow pattern.
2308  * @param actions Pointer to the flow actions.
2309  * @param flow Pointer to the flow.
2310  * @param error Pointer to the flow error.
2311  * @returns 0 on success, negative value otherwise.
2312  */
2313 static int
2314 mrvl_flow_parse(struct mrvl_priv *priv, const struct rte_flow_attr *attr,
2315                 const struct rte_flow_item pattern[],
2316                 const struct rte_flow_action actions[],
2317                 struct rte_flow *flow,
2318                 struct rte_flow_error *error)
2319 {
2320         int ret;
2321
2322         ret = mrvl_flow_parse_attr(priv, attr, flow, error);
2323         if (ret)
2324                 return ret;
2325
2326         ret = mrvl_flow_parse_pattern(priv, pattern, flow, error);
2327         if (ret)
2328                 return ret;
2329
2330         return mrvl_flow_parse_actions(priv, actions, flow, error);
2331 }
2332
2333 static inline enum pp2_cls_tbl_type
2334 mrvl_engine_type(const struct rte_flow *flow)
2335 {
2336         int i, size = 0;
2337
2338         for (i = 0; i < flow->rule.num_fields; i++)
2339                 size += flow->rule.fields[i].size;
2340
2341         /*
2342          * For maskable engine type the key size must be up to 8 bytes.
2343          * For keys with size bigger than 8 bytes, engine type must
2344          * be set to exact match.
2345          */
2346         if (size > 8)
2347                 return PP2_CLS_TBL_EXACT_MATCH;
2348
2349         return PP2_CLS_TBL_MASKABLE;
2350 }
2351
2352 static int
2353 mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow)
2354 {
2355         struct mrvl_priv *priv = dev->data->dev_private;
2356         struct pp2_cls_tbl_key *key = &priv->cls_tbl_params.key;
2357         int ret;
2358
2359         if (priv->cls_tbl) {
2360                 pp2_cls_tbl_deinit(priv->cls_tbl);
2361                 priv->cls_tbl = NULL;
2362         }
2363
2364         memset(&priv->cls_tbl_params, 0, sizeof(priv->cls_tbl_params));
2365
2366         priv->cls_tbl_params.type = mrvl_engine_type(first_flow);
2367         RTE_LOG(INFO, PMD, "Setting cls search engine type to %s\n",
2368                         priv->cls_tbl_params.type == PP2_CLS_TBL_EXACT_MATCH ?
2369                         "exact" : "maskable");
2370         priv->cls_tbl_params.max_num_rules = MRVL_CLS_MAX_NUM_RULES;
2371         priv->cls_tbl_params.default_act.type = PP2_CLS_TBL_ACT_DONE;
2372         priv->cls_tbl_params.default_act.cos = &first_flow->cos;
2373
2374         if (first_flow->pattern & F_DMAC) {
2375                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2376                 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_DA;
2377                 key->key_size += 6;
2378                 key->num_fields += 1;
2379         }
2380
2381         if (first_flow->pattern & F_SMAC) {
2382                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2383                 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_SA;
2384                 key->key_size += 6;
2385                 key->num_fields += 1;
2386         }
2387
2388         if (first_flow->pattern & F_TYPE) {
2389                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2390                 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_TYPE;
2391                 key->key_size += 2;
2392                 key->num_fields += 1;
2393         }
2394
2395         if (first_flow->pattern & F_VLAN_ID) {
2396                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN;
2397                 key->proto_field[key->num_fields].field.vlan = MV_NET_VLAN_F_ID;
2398                 key->key_size += 2;
2399                 key->num_fields += 1;
2400         }
2401
2402         if (first_flow->pattern & F_VLAN_PRI) {
2403                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN;
2404                 key->proto_field[key->num_fields].field.vlan =
2405                         MV_NET_VLAN_F_PRI;
2406                 key->key_size += 1;
2407                 key->num_fields += 1;
2408         }
2409
2410         if (first_flow->pattern & F_IP4_TOS) {
2411                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2412                 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_TOS;
2413                 key->key_size += 1;
2414                 key->num_fields += 1;
2415         }
2416
2417         if (first_flow->pattern & F_IP4_SIP) {
2418                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2419                 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_SA;
2420                 key->key_size += 4;
2421                 key->num_fields += 1;
2422         }
2423
2424         if (first_flow->pattern & F_IP4_DIP) {
2425                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2426                 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_DA;
2427                 key->key_size += 4;
2428                 key->num_fields += 1;
2429         }
2430
2431         if (first_flow->pattern & F_IP4_PROTO) {
2432                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2433                 key->proto_field[key->num_fields].field.ipv4 =
2434                         MV_NET_IP4_F_PROTO;
2435                 key->key_size += 1;
2436                 key->num_fields += 1;
2437         }
2438
2439         if (first_flow->pattern & F_IP6_SIP) {
2440                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2441                 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_SA;
2442                 key->key_size += 16;
2443                 key->num_fields += 1;
2444         }
2445
2446         if (first_flow->pattern & F_IP6_DIP) {
2447                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2448                 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_DA;
2449                 key->key_size += 16;
2450                 key->num_fields += 1;
2451         }
2452
2453         if (first_flow->pattern & F_IP6_FLOW) {
2454                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2455                 key->proto_field[key->num_fields].field.ipv6 =
2456                         MV_NET_IP6_F_FLOW;
2457                 key->key_size += 3;
2458                 key->num_fields += 1;
2459         }
2460
2461         if (first_flow->pattern & F_IP6_NEXT_HDR) {
2462                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2463                 key->proto_field[key->num_fields].field.ipv6 =
2464                         MV_NET_IP6_F_NEXT_HDR;
2465                 key->key_size += 1;
2466                 key->num_fields += 1;
2467         }
2468
2469         if (first_flow->pattern & F_TCP_SPORT) {
2470                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP;
2471                 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP;
2472                 key->key_size += 2;
2473                 key->num_fields += 1;
2474         }
2475
2476         if (first_flow->pattern & F_TCP_DPORT) {
2477                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP;
2478                 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_DP;
2479                 key->key_size += 2;
2480                 key->num_fields += 1;
2481         }
2482
2483         if (first_flow->pattern & F_UDP_SPORT) {
2484                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP;
2485                 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP;
2486                 key->key_size += 2;
2487                 key->num_fields += 1;
2488         }
2489
2490         if (first_flow->pattern & F_UDP_DPORT) {
2491                 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP;
2492                 key->proto_field[key->num_fields].field.udp = MV_NET_TCP_F_DP;
2493                 key->key_size += 2;
2494                 key->num_fields += 1;
2495         }
2496
2497         ret = pp2_cls_tbl_init(&priv->cls_tbl_params, &priv->cls_tbl);
2498         if (!ret)
2499                 priv->cls_tbl_pattern = first_flow->pattern;
2500
2501         return ret;
2502 }
2503
2504 /**
2505  * Check whether new flow can be added to the table
2506  *
2507  * @param priv Pointer to the port's private data.
2508  * @param flow Pointer to the new flow.
2509  * @return 1 in case flow can be added, 0 otherwise.
2510  */
2511 static inline int
2512 mrvl_flow_can_be_added(struct mrvl_priv *priv, const struct rte_flow *flow)
2513 {
2514         return flow->pattern == priv->cls_tbl_pattern &&
2515                mrvl_engine_type(flow) == priv->cls_tbl_params.type;
2516 }
2517
2518 /**
2519  * DPDK flow create callback called when flow is to be created.
2520  *
2521  * @param dev Pointer to the device.
2522  * @param attr Pointer to the flow attribute.
2523  * @param pattern Pointer to the flow pattern.
2524  * @param actions Pointer to the flow actions.
2525  * @param error Pointer to the flow error.
2526  * @returns Pointer to the created flow in case of success, NULL otherwise.
2527  */
2528 static struct rte_flow *
2529 mrvl_flow_create(struct rte_eth_dev *dev,
2530                  const struct rte_flow_attr *attr,
2531                  const struct rte_flow_item pattern[],
2532                  const struct rte_flow_action actions[],
2533                  struct rte_flow_error *error)
2534 {
2535         struct mrvl_priv *priv = dev->data->dev_private;
2536         struct rte_flow *flow, *first;
2537         int ret;
2538
2539         if (!dev->data->dev_started) {
2540                 rte_flow_error_set(error, EINVAL,
2541                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2542                                    "Port must be started first\n");
2543                 return NULL;
2544         }
2545
2546         flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id());
2547         if (!flow)
2548                 return NULL;
2549
2550         ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error);
2551         if (ret)
2552                 goto out;
2553
2554         /*
2555          * Four cases here:
2556          *
2557          * 1. In case table does not exist - create one.
2558          * 2. In case table exists, is empty and new flow cannot be added
2559          *    recreate table.
2560          * 3. In case table is not empty and new flow matches table format
2561          *    add it.
2562          * 4. Otherwise flow cannot be added.
2563          */
2564         first = LIST_FIRST(&priv->flows);
2565         if (!priv->cls_tbl) {
2566                 ret = mrvl_create_cls_table(dev, flow);
2567         } else if (!first && !mrvl_flow_can_be_added(priv, flow)) {
2568                 ret = mrvl_create_cls_table(dev, flow);
2569         } else if (mrvl_flow_can_be_added(priv, flow)) {
2570                 ret = 0;
2571         } else {
2572                 rte_flow_error_set(error, EINVAL,
2573                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2574                                    "Pattern does not match cls table format\n");
2575                 goto out;
2576         }
2577
2578         if (ret) {
2579                 rte_flow_error_set(error, EINVAL,
2580                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2581                                    "Failed to create cls table\n");
2582                 goto out;
2583         }
2584
2585         ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action);
2586         if (ret) {
2587                 rte_flow_error_set(error, EINVAL,
2588                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2589                                    "Failed to add rule\n");
2590                 goto out;
2591         }
2592
2593         LIST_INSERT_HEAD(&priv->flows, flow, next);
2594
2595         return flow;
2596 out:
2597         rte_free(flow);
2598         return NULL;
2599 }
2600
2601 /**
2602  * Remove classifier rule associated with given flow.
2603  *
2604  * @param priv Pointer to the port's private data.
2605  * @param flow Pointer to the flow.
2606  * @param error Pointer to the flow error.
2607  * @returns 0 in case of success, negative value otherwise.
2608  */
2609 static int
2610 mrvl_flow_remove(struct mrvl_priv *priv, struct rte_flow *flow,
2611                  struct rte_flow_error *error)
2612 {
2613         int ret;
2614
2615         if (!priv->cls_tbl) {
2616                 rte_flow_error_set(error, EINVAL,
2617                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2618                                    "Classifier table not initialized");
2619                 return -rte_errno;
2620         }
2621
2622         ret = pp2_cls_tbl_remove_rule(priv->cls_tbl, &flow->rule);
2623         if (ret) {
2624                 rte_flow_error_set(error, EINVAL,
2625                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2626                                    "Failed to remove rule");
2627                 return -rte_errno;
2628         }
2629
2630         mrvl_free_all_key_mask(&flow->rule);
2631
2632         return 0;
2633 }
2634
2635 /**
2636  * DPDK flow destroy callback called when flow is to be removed.
2637  *
2638  * @param priv Pointer to the port's private data.
2639  * @param flow Pointer to the flow.
2640  * @param error Pointer to the flow error.
2641  * @returns 0 in case of success, negative value otherwise.
2642  */
2643 static int
2644 mrvl_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
2645                   struct rte_flow_error *error)
2646 {
2647         struct mrvl_priv *priv = dev->data->dev_private;
2648         struct rte_flow *f;
2649         int ret;
2650
2651         LIST_FOREACH(f, &priv->flows, next) {
2652                 if (f == flow)
2653                         break;
2654         }
2655
2656         if (!flow) {
2657                 rte_flow_error_set(error, EINVAL,
2658                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2659                                    "Rule was not found");
2660                 return -rte_errno;
2661         }
2662
2663         LIST_REMOVE(f, next);
2664
2665         ret = mrvl_flow_remove(priv, flow, error);
2666         if (ret)
2667                 return ret;
2668
2669         rte_free(flow);
2670
2671         return 0;
2672 }
2673
2674 /**
2675  * DPDK flow callback called to verify given attribute, pattern and actions.
2676  *
2677  * @param dev Pointer to the device.
2678  * @param attr Pointer to the flow attribute.
2679  * @param pattern Pointer to the flow pattern.
2680  * @param actions Pointer to the flow actions.
2681  * @param error Pointer to the flow error.
2682  * @returns 0 on success, negative value otherwise.
2683  */
2684 static int
2685 mrvl_flow_validate(struct rte_eth_dev *dev,
2686                    const struct rte_flow_attr *attr,
2687                    const struct rte_flow_item pattern[],
2688                    const struct rte_flow_action actions[],
2689                    struct rte_flow_error *error)
2690 {
2691         static struct rte_flow *flow;
2692
2693         flow = mrvl_flow_create(dev, attr, pattern, actions, error);
2694         if (!flow)
2695                 return -rte_errno;
2696
2697         mrvl_flow_destroy(dev, flow, error);
2698
2699         return 0;
2700 }
2701
2702 /**
2703  * DPDK flow flush callback called when flows are to be flushed.
2704  *
2705  * @param dev Pointer to the device.
2706  * @param error Pointer to the flow error.
2707  * @returns 0 in case of success, negative value otherwise.
2708  */
2709 static int
2710 mrvl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
2711 {
2712         struct mrvl_priv *priv = dev->data->dev_private;
2713
2714         while (!LIST_EMPTY(&priv->flows)) {
2715                 struct rte_flow *flow = LIST_FIRST(&priv->flows);
2716                 int ret = mrvl_flow_remove(priv, flow, error);
2717                 if (ret)
2718                         return ret;
2719
2720                 LIST_REMOVE(flow, next);
2721                 rte_free(flow);
2722         }
2723
2724         return 0;
2725 }
2726
2727 /**
2728  * DPDK flow isolate callback called to isolate port.
2729  *
2730  * @param dev Pointer to the device.
2731  * @param enable Pass 0/1 to disable/enable port isolation.
2732  * @param error Pointer to the flow error.
2733  * @returns 0 in case of success, negative value otherwise.
2734  */
2735 static int
2736 mrvl_flow_isolate(struct rte_eth_dev *dev, int enable,
2737                   struct rte_flow_error *error)
2738 {
2739         struct mrvl_priv *priv = dev->data->dev_private;
2740
2741         if (dev->data->dev_started) {
2742                 rte_flow_error_set(error, EBUSY,
2743                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2744                                    NULL, "Port must be stopped first\n");
2745                 return -rte_errno;
2746         }
2747
2748         priv->isolated = enable;
2749
2750         return 0;
2751 }
2752
2753 const struct rte_flow_ops mrvl_flow_ops = {
2754         .validate = mrvl_flow_validate,
2755         .create = mrvl_flow_create,
2756         .destroy = mrvl_flow_destroy,
2757         .flush = mrvl_flow_flush,
2758         .isolate = mrvl_flow_isolate
2759 };