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