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