net/octeontx2: add flow parsing for inner layers
[dpdk.git] / drivers / net / octeontx2 / otx2_flow_parse.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_ethdev.h"
6 #include "otx2_flow.h"
7
8 const struct rte_flow_item *
9 otx2_flow_skip_void_and_any_items(const struct rte_flow_item *pattern)
10 {
11         while ((pattern->type == RTE_FLOW_ITEM_TYPE_VOID) ||
12                (pattern->type == RTE_FLOW_ITEM_TYPE_ANY))
13                 pattern++;
14
15         return pattern;
16 }
17
18 /*
19  * Tunnel+ESP, Tunnel+ICMP4/6, Tunnel+TCP, Tunnel+UDP,
20  * Tunnel+SCTP
21  */
22 int
23 otx2_flow_parse_lh(struct otx2_parse_state *pst)
24 {
25         struct otx2_flow_item_info info;
26         char hw_mask[64];
27         int lid, lt;
28         int rc;
29
30         if (!pst->tunnel)
31                 return 0;
32
33         info.hw_mask = &hw_mask;
34         info.spec = NULL;
35         info.mask = NULL;
36         info.hw_hdr_len = 0;
37         lid = NPC_LID_LH;
38
39         switch (pst->pattern->type) {
40         case RTE_FLOW_ITEM_TYPE_UDP:
41                 lt = NPC_LT_LH_TU_UDP;
42                 info.def_mask = &rte_flow_item_udp_mask;
43                 info.len = sizeof(struct rte_flow_item_udp);
44                 break;
45         case RTE_FLOW_ITEM_TYPE_TCP:
46                 lt = NPC_LT_LH_TU_TCP;
47                 info.def_mask = &rte_flow_item_tcp_mask;
48                 info.len = sizeof(struct rte_flow_item_tcp);
49                 break;
50         case RTE_FLOW_ITEM_TYPE_SCTP:
51                 lt = NPC_LT_LH_TU_SCTP;
52                 info.def_mask = &rte_flow_item_sctp_mask;
53                 info.len = sizeof(struct rte_flow_item_sctp);
54                 break;
55         case RTE_FLOW_ITEM_TYPE_ESP:
56                 lt = NPC_LT_LH_TU_ESP;
57                 info.def_mask = &rte_flow_item_esp_mask;
58                 info.len = sizeof(struct rte_flow_item_esp);
59                 break;
60         default:
61                 return 0;
62         }
63
64         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
65         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
66         if (rc != 0)
67                 return rc;
68
69         return otx2_flow_update_parse_state(pst, &info, lid, lt, 0);
70 }
71
72 /* Tunnel+IPv4, Tunnel+IPv6 */
73 int
74 otx2_flow_parse_lg(struct otx2_parse_state *pst)
75 {
76         struct otx2_flow_item_info info;
77         char hw_mask[64];
78         int lid, lt;
79         int rc;
80
81         if (!pst->tunnel)
82                 return 0;
83
84         info.hw_mask = &hw_mask;
85         info.spec = NULL;
86         info.mask = NULL;
87         info.hw_hdr_len = 0;
88         lid = NPC_LID_LG;
89
90         if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_IPV4) {
91                 lt = NPC_LT_LG_TU_IP;
92                 info.def_mask = &rte_flow_item_ipv4_mask;
93                 info.len = sizeof(struct rte_flow_item_ipv4);
94         } else if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_IPV6) {
95                 lt = NPC_LT_LG_TU_IP6;
96                 info.def_mask = &rte_flow_item_ipv6_mask;
97                 info.len = sizeof(struct rte_flow_item_ipv6);
98         } else {
99                 /* There is no tunneled IP header */
100                 return 0;
101         }
102
103         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
104         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
105         if (rc != 0)
106                 return rc;
107
108         return otx2_flow_update_parse_state(pst, &info, lid, lt, 0);
109 }
110
111 /* Tunnel+Ether */
112 int
113 otx2_flow_parse_lf(struct otx2_parse_state *pst)
114 {
115         const struct rte_flow_item *pattern, *last_pattern;
116         struct rte_flow_item_eth hw_mask;
117         struct otx2_flow_item_info info;
118         int lid, lt, lflags;
119         int nr_vlans = 0;
120         int rc;
121
122         /* We hit this layer if there is a tunneling protocol */
123         if (!pst->tunnel)
124                 return 0;
125
126         if (pst->pattern->type != RTE_FLOW_ITEM_TYPE_ETH)
127                 return 0;
128
129         lid = NPC_LID_LF;
130         lt = NPC_LT_LF_TU_ETHER;
131         lflags = 0;
132
133         info.def_mask = &rte_flow_item_vlan_mask;
134         /* No match support for vlan tags */
135         info.hw_mask = NULL;
136         info.len = sizeof(struct rte_flow_item_vlan);
137         info.spec = NULL;
138         info.mask = NULL;
139         info.hw_hdr_len = 0;
140
141         /* Look ahead and find out any VLAN tags. These can be
142          * detected but no data matching is available.
143          */
144         last_pattern = pst->pattern;
145         pattern = pst->pattern + 1;
146         pattern = otx2_flow_skip_void_and_any_items(pattern);
147         while (pattern->type == RTE_FLOW_ITEM_TYPE_VLAN) {
148                 nr_vlans++;
149                 rc = otx2_flow_parse_item_basic(pattern, &info, pst->error);
150                 if (rc != 0)
151                         return rc;
152                 last_pattern = pattern;
153                 pattern++;
154                 pattern = otx2_flow_skip_void_and_any_items(pattern);
155         }
156         otx2_npc_dbg("Nr_vlans = %d", nr_vlans);
157         switch (nr_vlans) {
158         case 0:
159                 break;
160         case 1:
161                 lflags = NPC_F_TU_ETHER_CTAG;
162                 break;
163         case 2:
164                 lflags = NPC_F_TU_ETHER_STAG_CTAG;
165                 break;
166         default:
167                 rte_flow_error_set(pst->error, ENOTSUP,
168                                    RTE_FLOW_ERROR_TYPE_ITEM,
169                                    last_pattern,
170                                    "more than 2 vlans with tunneled Ethernet "
171                                    "not supported");
172                 return -rte_errno;
173         }
174
175         info.def_mask = &rte_flow_item_eth_mask;
176         info.hw_mask = &hw_mask;
177         info.len = sizeof(struct rte_flow_item_eth);
178         info.hw_hdr_len = 0;
179         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
180         info.spec = NULL;
181         info.mask = NULL;
182
183         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
184         if (rc != 0)
185                 return rc;
186
187         pst->pattern = last_pattern;
188
189         return otx2_flow_update_parse_state(pst, &info, lid, lt, lflags);
190 }
191
192 int
193 otx2_flow_parse_le(struct otx2_parse_state *pst)
194 {
195         /*
196          * We are positioned at UDP. Scan ahead and look for
197          * UDP encapsulated tunnel protocols. If available,
198          * parse them. In that case handle this:
199          *      - RTE spec assumes we point to tunnel header.
200          *      - NPC parser provides offset from UDP header.
201          */
202
203         /*
204          * Note: Add support to GENEVE, VXLAN_GPE when we
205          * upgrade DPDK
206          *
207          * Note: Better to split flags into two nibbles:
208          *      - Higher nibble can have flags
209          *      - Lower nibble to further enumerate protocols
210          *        and have flags based extraction
211          */
212         const struct rte_flow_item *pattern = pst->pattern;
213         struct otx2_flow_item_info info;
214         int lid, lt, lflags;
215         char hw_mask[64];
216         int rc;
217
218         if (pst->tunnel)
219                 return 0;
220
221         if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_MPLS)
222                 return otx2_flow_parse_mpls(pst, NPC_LID_LE);
223
224         info.spec = NULL;
225         info.mask = NULL;
226         info.hw_mask = NULL;
227         info.def_mask = NULL;
228         info.len = 0;
229         info.hw_hdr_len = 0;
230         lid = NPC_LID_LE;
231         lflags = 0;
232
233         /* Ensure we are not matching anything in UDP */
234         rc = otx2_flow_parse_item_basic(pattern, &info, pst->error);
235         if (rc)
236                 return rc;
237
238         info.hw_mask = &hw_mask;
239         pattern = otx2_flow_skip_void_and_any_items(pattern);
240         otx2_npc_dbg("Pattern->type = %d", pattern->type);
241         switch (pattern->type) {
242         case RTE_FLOW_ITEM_TYPE_VXLAN:
243                 lflags = NPC_F_UDP_VXLAN;
244                 info.def_mask = &rte_flow_item_vxlan_mask;
245                 info.len = sizeof(struct rte_flow_item_vxlan);
246                 lt = NPC_LT_LE_VXLAN;
247                 break;
248         case RTE_FLOW_ITEM_TYPE_GTPC:
249                 lflags = NPC_F_UDP_GTP_GTPC;
250                 info.def_mask = &rte_flow_item_gtp_mask;
251                 info.len = sizeof(struct rte_flow_item_gtp);
252                 lt = NPC_LT_LE_GTPC;
253                 break;
254         case RTE_FLOW_ITEM_TYPE_GTPU:
255                 lflags = NPC_F_UDP_GTP_GTPU_G_PDU;
256                 info.def_mask = &rte_flow_item_gtp_mask;
257                 info.len = sizeof(struct rte_flow_item_gtp);
258                 lt = NPC_LT_LE_GTPU;
259                 break;
260         case RTE_FLOW_ITEM_TYPE_GENEVE:
261                 lflags = NPC_F_UDP_GENEVE;
262                 info.def_mask = &rte_flow_item_geneve_mask;
263                 info.len = sizeof(struct rte_flow_item_geneve);
264                 lt = NPC_LT_LE_GENEVE;
265                 break;
266         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
267                 lflags = NPC_F_UDP_VXLANGPE;
268                 info.def_mask = &rte_flow_item_vxlan_gpe_mask;
269                 info.len = sizeof(struct rte_flow_item_vxlan_gpe);
270                 lt = NPC_LT_LE_VXLANGPE;
271                 break;
272         default:
273                 return 0;
274         }
275
276         pst->tunnel = 1;
277
278         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
279         rc = otx2_flow_parse_item_basic(pattern, &info, pst->error);
280         if (rc != 0)
281                 return rc;
282
283         return otx2_flow_update_parse_state(pst, &info, lid, lt, lflags);
284 }
285
286 static int
287 flow_parse_mpls_label_stack(struct otx2_parse_state *pst, int *flag)
288 {
289         int nr_labels = 0;
290         const struct rte_flow_item *pattern = pst->pattern;
291         struct otx2_flow_item_info info;
292         int rc;
293         uint8_t flag_list[] = {0, NPC_F_MPLS_2_LABELS,
294                 NPC_F_MPLS_3_LABELS, NPC_F_MPLS_4_LABELS};
295
296         /*
297          * pst->pattern points to first MPLS label. We only check
298          * that subsequent labels do not have anything to match.
299          */
300         info.def_mask = &rte_flow_item_mpls_mask;
301         info.hw_mask = NULL;
302         info.len = sizeof(struct rte_flow_item_mpls);
303         info.spec = NULL;
304         info.mask = NULL;
305         info.hw_hdr_len = 0;
306
307         while (pattern->type == RTE_FLOW_ITEM_TYPE_MPLS) {
308                 nr_labels++;
309
310                 /* Basic validation of 2nd/3rd/4th mpls item */
311                 if (nr_labels > 1) {
312                         rc = otx2_flow_parse_item_basic(pattern, &info,
313                                                         pst->error);
314                         if (rc != 0)
315                                 return rc;
316                 }
317                 pst->last_pattern = pattern;
318                 pattern++;
319                 pattern = otx2_flow_skip_void_and_any_items(pattern);
320         }
321
322         if (nr_labels > 4) {
323                 rte_flow_error_set(pst->error, ENOTSUP,
324                                    RTE_FLOW_ERROR_TYPE_ITEM,
325                                    pst->last_pattern,
326                                    "more than 4 mpls labels not supported");
327                 return -rte_errno;
328         }
329
330         *flag = flag_list[nr_labels - 1];
331         return 0;
332 }
333
334 int
335 otx2_flow_parse_mpls(struct otx2_parse_state *pst, int lid)
336 {
337         /* Find number of MPLS labels */
338         struct rte_flow_item_mpls hw_mask;
339         struct otx2_flow_item_info info;
340         int lt, lflags;
341         int rc;
342
343         lflags = 0;
344
345         if (lid == NPC_LID_LC)
346                 lt = NPC_LT_LC_MPLS;
347         else if (lid == NPC_LID_LD)
348                 lt = NPC_LT_LD_TU_MPLS_IN_IP;
349         else
350                 lt = NPC_LT_LE_TU_MPLS_IN_UDP;
351
352         /* Prepare for parsing the first item */
353         info.def_mask = &rte_flow_item_mpls_mask;
354         info.hw_mask = &hw_mask;
355         info.len = sizeof(struct rte_flow_item_mpls);
356         info.spec = NULL;
357         info.mask = NULL;
358         info.hw_hdr_len = 0;
359
360         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
361         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
362         if (rc != 0)
363                 return rc;
364
365         /*
366          * Parse for more labels.
367          * This sets lflags and pst->last_pattern correctly.
368          */
369         rc = flow_parse_mpls_label_stack(pst, &lflags);
370         if (rc != 0)
371                 return rc;
372
373         pst->tunnel = 1;
374         pst->pattern = pst->last_pattern;
375
376         return otx2_flow_update_parse_state(pst, &info, lid, lt, lflags);
377 }
378
379 /*
380  * ICMP, ICMP6, UDP, TCP, SCTP, VXLAN, GRE, NVGRE,
381  * GTP, GTPC, GTPU, ESP
382  *
383  * Note: UDP tunnel protocols are identified by flags.
384  *       LPTR for these protocol still points to UDP
385  *       header. Need flag based extraction to support
386  *       this.
387  */
388 int
389 otx2_flow_parse_ld(struct otx2_parse_state *pst)
390 {
391         char hw_mask[NPC_MAX_EXTRACT_DATA_LEN];
392         struct otx2_flow_item_info info;
393         int lid, lt, lflags;
394         int rc;
395
396         if (pst->tunnel) {
397                 /* We have already parsed MPLS or IPv4/v6 followed
398                  * by MPLS or IPv4/v6. Subsequent TCP/UDP etc
399                  * would be parsed as tunneled versions. Skip
400                  * this layer, except for tunneled MPLS. If LC is
401                  * MPLS, we have anyway skipped all stacked MPLS
402                  * labels.
403                  */
404                 if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_MPLS)
405                         return otx2_flow_parse_mpls(pst, NPC_LID_LD);
406                 return 0;
407         }
408         info.hw_mask = &hw_mask;
409         info.spec = NULL;
410         info.mask = NULL;
411         info.def_mask = NULL;
412         info.len = 0;
413         info.hw_hdr_len = 0;
414
415         lid = NPC_LID_LD;
416         lflags = 0;
417
418         otx2_npc_dbg("Pst->pattern->type = %d", pst->pattern->type);
419         switch (pst->pattern->type) {
420         case RTE_FLOW_ITEM_TYPE_ICMP:
421                 if (pst->lt[NPC_LID_LC] == NPC_LT_LC_IP6)
422                         lt = NPC_LT_LD_ICMP6;
423                 else
424                         lt = NPC_LT_LD_ICMP;
425                 info.def_mask = &rte_flow_item_icmp_mask;
426                 info.len = sizeof(struct rte_flow_item_icmp);
427                 break;
428         case RTE_FLOW_ITEM_TYPE_UDP:
429                 lt = NPC_LT_LD_UDP;
430                 info.def_mask = &rte_flow_item_udp_mask;
431                 info.len = sizeof(struct rte_flow_item_udp);
432                 break;
433         case RTE_FLOW_ITEM_TYPE_TCP:
434                 lt = NPC_LT_LD_TCP;
435                 info.def_mask = &rte_flow_item_tcp_mask;
436                 info.len = sizeof(struct rte_flow_item_tcp);
437                 break;
438         case RTE_FLOW_ITEM_TYPE_SCTP:
439                 lt = NPC_LT_LD_SCTP;
440                 info.def_mask = &rte_flow_item_sctp_mask;
441                 info.len = sizeof(struct rte_flow_item_sctp);
442                 break;
443         case RTE_FLOW_ITEM_TYPE_ESP:
444                 lt = NPC_LT_LD_ESP;
445                 info.def_mask = &rte_flow_item_esp_mask;
446                 info.len = sizeof(struct rte_flow_item_esp);
447                 break;
448         case RTE_FLOW_ITEM_TYPE_GRE:
449                 lt = NPC_LT_LD_GRE;
450                 info.def_mask = &rte_flow_item_gre_mask;
451                 info.len = sizeof(struct rte_flow_item_gre);
452                 break;
453         case RTE_FLOW_ITEM_TYPE_NVGRE:
454                 lt = NPC_LT_LD_GRE;
455                 lflags = NPC_F_GRE_NVGRE;
456                 info.def_mask = &rte_flow_item_nvgre_mask;
457                 info.len = sizeof(struct rte_flow_item_nvgre);
458                 /* Further IP/Ethernet are parsed as tunneled */
459                 pst->tunnel = 1;
460                 break;
461         default:
462                 return 0;
463         }
464
465         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
466         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
467         if (rc != 0)
468                 return rc;
469
470         return otx2_flow_update_parse_state(pst, &info, lid, lt, lflags);
471 }
472
473 static inline void
474 flow_check_lc_ip_tunnel(struct otx2_parse_state *pst)
475 {
476         const struct rte_flow_item *pattern = pst->pattern + 1;
477
478         pattern = otx2_flow_skip_void_and_any_items(pattern);
479         if (pattern->type == RTE_FLOW_ITEM_TYPE_MPLS ||
480             pattern->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
481             pattern->type == RTE_FLOW_ITEM_TYPE_IPV6)
482                 pst->tunnel = 1;
483 }
484
485 /* Outer IPv4, Outer IPv6, MPLS, ARP */
486 int
487 otx2_flow_parse_lc(struct otx2_parse_state *pst)
488 {
489         uint8_t hw_mask[NPC_MAX_EXTRACT_DATA_LEN];
490         struct otx2_flow_item_info info;
491         int lid, lt;
492         int rc;
493
494         if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_MPLS)
495                 return otx2_flow_parse_mpls(pst, NPC_LID_LC);
496
497         info.hw_mask = &hw_mask;
498         info.spec = NULL;
499         info.mask = NULL;
500         info.hw_hdr_len = 0;
501         lid = NPC_LID_LC;
502
503         switch (pst->pattern->type) {
504         case RTE_FLOW_ITEM_TYPE_IPV4:
505                 lt = NPC_LT_LC_IP;
506                 info.def_mask = &rte_flow_item_ipv4_mask;
507                 info.len = sizeof(struct rte_flow_item_ipv4);
508                 break;
509         case RTE_FLOW_ITEM_TYPE_IPV6:
510                 lid = NPC_LID_LC;
511                 lt = NPC_LT_LC_IP6;
512                 info.def_mask = &rte_flow_item_ipv6_mask;
513                 info.len = sizeof(struct rte_flow_item_ipv6);
514                 break;
515         case RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4:
516                 lt = NPC_LT_LC_ARP;
517                 info.def_mask = &rte_flow_item_arp_eth_ipv4_mask;
518                 info.len = sizeof(struct rte_flow_item_arp_eth_ipv4);
519                 break;
520         default:
521                 /* No match at this layer */
522                 return 0;
523         }
524
525         /* Identify if IP tunnels MPLS or IPv4/v6 */
526         flow_check_lc_ip_tunnel(pst);
527
528         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
529         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
530         if (rc != 0)
531                 return rc;
532
533         return otx2_flow_update_parse_state(pst, &info, lid, lt, 0);
534 }
535
536 /* VLAN, ETAG */
537 int
538 otx2_flow_parse_lb(struct otx2_parse_state *pst)
539 {
540         const struct rte_flow_item *pattern = pst->pattern;
541         const struct rte_flow_item *last_pattern;
542         char hw_mask[NPC_MAX_EXTRACT_DATA_LEN];
543         struct otx2_flow_item_info info;
544         int lid, lt, lflags;
545         int nr_vlans = 0;
546         int rc;
547
548         info.spec = NULL;
549         info.mask = NULL;
550         info.hw_hdr_len = NPC_TPID_LENGTH;
551
552         lid = NPC_LID_LB;
553         lflags = 0;
554         last_pattern = pattern;
555
556         if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_VLAN) {
557                 /* RTE vlan is either 802.1q or 802.1ad,
558                  * this maps to either CTAG/STAG. We need to decide
559                  * based on number of VLANS present. Matching is
560                  * supported on first tag only.
561                  */
562                 info.def_mask = &rte_flow_item_vlan_mask;
563                 info.hw_mask = NULL;
564                 info.len = sizeof(struct rte_flow_item_vlan);
565
566                 pattern = pst->pattern;
567                 while (pattern->type == RTE_FLOW_ITEM_TYPE_VLAN) {
568                         nr_vlans++;
569
570                         /* Basic validation of 2nd/3rd vlan item */
571                         if (nr_vlans > 1) {
572                                 otx2_npc_dbg("Vlans  = %d", nr_vlans);
573                                 rc = otx2_flow_parse_item_basic(pattern, &info,
574                                                                 pst->error);
575                                 if (rc != 0)
576                                         return rc;
577                         }
578                         last_pattern = pattern;
579                         pattern++;
580                         pattern = otx2_flow_skip_void_and_any_items(pattern);
581                 }
582
583                 switch (nr_vlans) {
584                 case 1:
585                         lt = NPC_LT_LB_CTAG;
586                         break;
587                 case 2:
588                         lt = NPC_LT_LB_STAG;
589                         lflags = NPC_F_STAG_CTAG;
590                         break;
591                 case 3:
592                         lt = NPC_LT_LB_STAG;
593                         lflags = NPC_F_STAG_STAG_CTAG;
594                         break;
595                 default:
596                         rte_flow_error_set(pst->error, ENOTSUP,
597                                            RTE_FLOW_ERROR_TYPE_ITEM,
598                                            last_pattern,
599                                            "more than 3 vlans not supported");
600                         return -rte_errno;
601                 }
602         } else if (pst->pattern->type == RTE_FLOW_ITEM_TYPE_E_TAG) {
603                 /* we can support ETAG and match a subsequent CTAG
604                  * without any matching support.
605                  */
606                 lt = NPC_LT_LB_ETAG;
607                 lflags = 0;
608
609                 last_pattern = pst->pattern;
610                 pattern = otx2_flow_skip_void_and_any_items(pst->pattern + 1);
611                 if (pattern->type == RTE_FLOW_ITEM_TYPE_VLAN) {
612                         info.def_mask = &rte_flow_item_vlan_mask;
613                         /* set supported mask to NULL for vlan tag */
614                         info.hw_mask = NULL;
615                         info.len = sizeof(struct rte_flow_item_vlan);
616                         rc = otx2_flow_parse_item_basic(pattern, &info,
617                                                         pst->error);
618                         if (rc != 0)
619                                 return rc;
620
621                         lflags = NPC_F_ETAG_CTAG;
622                         last_pattern = pattern;
623                 }
624
625                 info.def_mask = &rte_flow_item_e_tag_mask;
626                 info.len = sizeof(struct rte_flow_item_e_tag);
627         } else {
628                 return 0;
629         }
630
631         info.hw_mask = &hw_mask;
632         info.spec = NULL;
633         info.mask = NULL;
634         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
635
636         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
637         if (rc != 0)
638                 return rc;
639
640         /* Point pattern to last item consumed */
641         pst->pattern = last_pattern;
642         return otx2_flow_update_parse_state(pst, &info, lid, lt, lflags);
643 }
644
645 int
646 otx2_flow_parse_la(struct otx2_parse_state *pst)
647 {
648         struct rte_flow_item_eth hw_mask;
649         struct otx2_flow_item_info info;
650         int lid, lt;
651         int rc;
652
653         /* Identify the pattern type into lid, lt */
654         if (pst->pattern->type != RTE_FLOW_ITEM_TYPE_ETH)
655                 return 0;
656
657         lid = NPC_LID_LA;
658         lt = NPC_LT_LA_ETHER;
659         info.hw_hdr_len = 0;
660
661         if (pst->flow->nix_intf == NIX_INTF_TX) {
662                 lt = NPC_LT_LA_IH_NIX_ETHER;
663                 info.hw_hdr_len = NPC_IH_LENGTH;
664         }
665
666         /* Prepare for parsing the item */
667         info.def_mask = &rte_flow_item_eth_mask;
668         info.hw_mask = &hw_mask;
669         info.len = sizeof(struct rte_flow_item_eth);
670         otx2_flow_get_hw_supp_mask(pst, &info, lid, lt);
671         info.spec = NULL;
672         info.mask = NULL;
673
674         /* Basic validation of item parameters */
675         rc = otx2_flow_parse_item_basic(pst->pattern, &info, pst->error);
676         if (rc)
677                 return rc;
678
679         /* Update pst if not validate only? clash check? */
680         return otx2_flow_update_parse_state(pst, &info, lid, lt, 0);
681 }