From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 86D94A0547; Fri, 5 Mar 2021 14:47:20 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 468E022A46A; Fri, 5 Mar 2021 14:41:43 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id E431222A463 for ; Fri, 5 Mar 2021 14:41:41 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 125Ddlu3008309 for ; Fri, 5 Mar 2021 05:41:41 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0220; bh=7YKfx9zWrong6yyG/BZFQ5tCbW4iyvljEOb9GRFtISE=; b=Aru+/jsonQ/eQ52FFkHXdwWcgvlX11KmIE7IM3bYSa1g03gNlGwYKZ9uoiztTWgOrS8m 3awV3KzaKLlMyoQeLW4x46aweo6ERm09IU+aLnEBb0SSPzCIfIET3/YTGemMXUN/qj7A JkIbSV+2/N6b19tgrv4YdDW9BH5/nKvAOzaBE8JFAwR5Hnt6v2G24anFJA7xuxi87QSO rmWLlj8lX5wW9IqElgt9lNQLlLf011RZ3C9JEO3Ycrr3NFi671GWDFjn9lSAdmvmhCqt 40X4xvYn20beNnPOkyIBeWzlStpOwoiBibBAKPsAp4vK47DAfxNlVPYv6v/mlpmQ5J74 8Q== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com with ESMTP id 370p7p0dh1-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Fri, 05 Mar 2021 05:41:41 -0800 Received: from SC-EXCH03.marvell.com (10.93.176.83) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 5 Mar 2021 05:41:39 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 5 Mar 2021 05:41:38 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 5 Mar 2021 05:41:38 -0800 Received: from hyd1588t430.marvell.com (unknown [10.29.52.204]) by maili.marvell.com (Postfix) with ESMTP id C71133F703F; Fri, 5 Mar 2021 05:41:35 -0800 (PST) From: Nithin Dabilpuram To: CC: , , , , , , Date: Fri, 5 Mar 2021 19:09:09 +0530 Message-ID: <20210305133918.8005-44-ndabilpuram@marvell.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20210305133918.8005-1-ndabilpuram@marvell.com> References: <20210305133918.8005-1-ndabilpuram@marvell.com> MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369, 18.0.761 definitions=2021-03-05_08:2021-03-03, 2021-03-05 signatures=0 Subject: [dpdk-dev] [PATCH 43/52] common/cnxk: add npc parsing API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kiran Kumar K Adding npc parsing API support to parse different patterns and actions. Based on the pattern and actions ltype values will be chosen and mcam data will be configured at perticular offsets. Signed-off-by: Kiran Kumar K --- drivers/common/cnxk/meson.build | 1 + drivers/common/cnxk/roc_npc_parse.c | 703 ++++++++++++++++++++++++++++++++++++ drivers/common/cnxk/roc_npc_priv.h | 13 + 3 files changed, 717 insertions(+) create mode 100644 drivers/common/cnxk/roc_npc_parse.c diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build index 35dd3b9..f464a6d 100644 --- a/drivers/common/cnxk/meson.build +++ b/drivers/common/cnxk/meson.build @@ -36,6 +36,7 @@ sources = files('roc_dev.c', 'roc_npa_debug.c', 'roc_npa_irq.c', 'roc_npc_mcam.c', + 'roc_npc_parse.c', 'roc_npc_utils.c', 'roc_platform.c', 'roc_utils.c') diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c new file mode 100644 index 0000000..483d21e --- /dev/null +++ b/drivers/common/cnxk/roc_npc_parse.c @@ -0,0 +1,703 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2020 Marvell. + */ +#include "roc_api.h" +#include "roc_priv.h" + +const struct roc_npc_item_info * +npc_parse_skip_void_and_any_items(const struct roc_npc_item_info *pattern) +{ + while ((pattern->type == ROC_NPC_ITEM_TYPE_VOID) || + (pattern->type == ROC_NPC_ITEM_TYPE_ANY)) + pattern++; + + return pattern; +} + +int +npc_parse_meta_items(struct npc_parse_state *pst) +{ + PLT_SET_USED(pst); + return 0; +} + +int +npc_parse_cpt_hdr(struct npc_parse_state *pst) +{ + uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt; + int rc; + + /* Identify the pattern type into lid, lt */ + if (pst->pattern->type != ROC_NPC_ITEM_TYPE_CPT_HDR) + return 0; + + lid = NPC_LID_LA; + lt = NPC_LT_LA_CPT_HDR; + info.hw_hdr_len = 0; + + /* Prepare for parsing the item */ + info.hw_mask = &hw_mask; + info.len = pst->pattern->size; + npc_get_hw_supp_mask(pst, &info, lid, lt); + info.spec = NULL; + info.mask = NULL; + + /* Basic validation of item parameters */ + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc) + return rc; + + /* Update pst if not validate only? clash check? */ + return npc_update_parse_state(pst, &info, lid, lt, 0); +} + +int +npc_parse_higig2_hdr(struct npc_parse_state *pst) +{ + uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt; + int rc; + + /* Identify the pattern type into lid, lt */ + if (pst->pattern->type != ROC_NPC_ITEM_TYPE_HIGIG2) + return 0; + + lid = NPC_LID_LA; + lt = NPC_LT_LA_HIGIG2_ETHER; + info.hw_hdr_len = 0; + + if (pst->flow->nix_intf == NIX_INTF_TX) { + lt = NPC_LT_LA_IH_NIX_HIGIG2_ETHER; + info.hw_hdr_len = NPC_IH_LENGTH; + } + + /* Prepare for parsing the item */ + info.hw_mask = &hw_mask; + info.len = pst->pattern->size; + npc_get_hw_supp_mask(pst, &info, lid, lt); + info.spec = NULL; + info.mask = NULL; + + /* Basic validation of item parameters */ + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc) + return rc; + + /* Update pst if not validate only? clash check? */ + return npc_update_parse_state(pst, &info, lid, lt, 0); +} + +int +npc_parse_la(struct npc_parse_state *pst) +{ + uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt; + int rc; + + /* Identify the pattern type into lid, lt */ + if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH) + return 0; + + lid = NPC_LID_LA; + lt = NPC_LT_LA_ETHER; + info.hw_hdr_len = 0; + + if (pst->flow->nix_intf == NIX_INTF_TX) { + lt = NPC_LT_LA_IH_NIX_ETHER; + info.hw_hdr_len = NPC_IH_LENGTH; + if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_HIGIG) { + lt = NPC_LT_LA_IH_NIX_HIGIG2_ETHER; + info.hw_hdr_len += NPC_HIGIG2_LENGTH; + } + } else { + if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_HIGIG) { + lt = NPC_LT_LA_HIGIG2_ETHER; + info.hw_hdr_len = NPC_HIGIG2_LENGTH; + } + } + + /* Prepare for parsing the item */ + info.hw_mask = &hw_mask; + info.len = pst->pattern->size; + npc_get_hw_supp_mask(pst, &info, lid, lt); + info.spec = NULL; + info.mask = NULL; + + /* Basic validation of item parameters */ + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc) + return rc; + + /* Update pst if not validate only? clash check? */ + return npc_update_parse_state(pst, &info, lid, lt, 0); +} + +int +npc_parse_lb(struct npc_parse_state *pst) +{ + const struct roc_npc_item_info *pattern = pst->pattern; + const struct roc_npc_item_info *last_pattern; + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt, lflags; + int nr_vlans = 0; + int rc; + + info.spec = NULL; + info.mask = NULL; + info.def_mask = NULL; + info.hw_hdr_len = NPC_TPID_LENGTH; + + lid = NPC_LID_LB; + lflags = 0; + last_pattern = pattern; + + if (pst->pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { + /* RTE vlan is either 802.1q or 802.1ad, + * this maps to either CTAG/STAG. We need to decide + * based on number of VLANS present. Matching is + * supported on first tag only. + */ + info.hw_mask = NULL; + info.len = pst->pattern->size; + + pattern = pst->pattern; + while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { + nr_vlans++; + + /* Basic validation of Second/Third vlan item */ + if (nr_vlans > 1) { + rc = npc_parse_item_basic(pattern, &info); + if (rc != 0) + return rc; + } + last_pattern = pattern; + pattern++; + pattern = npc_parse_skip_void_and_any_items(pattern); + } + + switch (nr_vlans) { + case 1: + lt = NPC_LT_LB_CTAG; + break; + case 2: + lt = NPC_LT_LB_STAG_QINQ; + lflags = NPC_F_STAG_CTAG; + break; + case 3: + lt = NPC_LT_LB_STAG_QINQ; + lflags = NPC_F_STAG_STAG_CTAG; + break; + default: + return NPC_ERR_PATTERN_NOTSUP; + } + } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_E_TAG) { + /* we can support ETAG and match a subsequent CTAG + * without any matching support. + */ + lt = NPC_LT_LB_ETAG; + lflags = 0; + + last_pattern = pst->pattern; + pattern = npc_parse_skip_void_and_any_items(pst->pattern + 1); + if (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { + /* set supported mask to NULL for vlan tag */ + info.hw_mask = NULL; + info.len = pattern->size; + rc = npc_parse_item_basic(pattern, &info); + if (rc != 0) + return rc; + + lflags = NPC_F_ETAG_CTAG; + last_pattern = pattern; + } + info.len = pattern->size; + } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_QINQ) { + info.hw_mask = NULL; + info.len = pst->pattern->size; + lt = NPC_LT_LB_STAG_QINQ; + lflags = NPC_F_STAG_CTAG; + } else { + return 0; + } + + info.hw_mask = &hw_mask; + info.spec = NULL; + info.mask = NULL; + npc_get_hw_supp_mask(pst, &info, lid, lt); + + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + /* Point pattern to last item consumed */ + pst->pattern = last_pattern; + return npc_update_parse_state(pst, &info, lid, lt, lflags); +} + +static int +npc_parse_mpls_label_stack(struct npc_parse_state *pst, int *flag) +{ + uint8_t flag_list[] = {0, NPC_F_MPLS_2_LABELS, NPC_F_MPLS_3_LABELS, + NPC_F_MPLS_4_LABELS}; + const struct roc_npc_item_info *pattern = pst->pattern; + struct npc_parse_item_info info; + int nr_labels = 0; + int rc; + + /* + * pst->pattern points to first MPLS label. We only check + * that subsequent labels do not have anything to match. + */ + info.hw_mask = NULL; + info.len = pattern->size; + info.spec = NULL; + info.mask = NULL; + info.hw_hdr_len = 0; + info.def_mask = NULL; + + while (pattern->type == ROC_NPC_ITEM_TYPE_MPLS) { + nr_labels++; + + /* Basic validation of Second/Third/Fourth mpls item */ + if (nr_labels > 1) { + rc = npc_parse_item_basic(pattern, &info); + if (rc != 0) + return rc; + } + pst->last_pattern = pattern; + pattern++; + pattern = npc_parse_skip_void_and_any_items(pattern); + } + + if (nr_labels < 1 || nr_labels > 4) + return NPC_ERR_PATTERN_NOTSUP; + + *flag = flag_list[nr_labels - 1]; + return 0; +} + +static int +npc_parse_mpls(struct npc_parse_state *pst, int lid) +{ + /* Find number of MPLS labels */ + uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lt, lflags; + int rc; + + lflags = 0; + + if (lid == NPC_LID_LC) + lt = NPC_LT_LC_MPLS; + else if (lid == NPC_LID_LD) + lt = NPC_LT_LD_TU_MPLS_IN_IP; + else + lt = NPC_LT_LE_TU_MPLS_IN_UDP; + + /* Prepare for parsing the first item */ + info.hw_mask = &hw_mask; + info.len = pst->pattern->size; + info.spec = NULL; + info.mask = NULL; + info.hw_hdr_len = 0; + + npc_get_hw_supp_mask(pst, &info, lid, lt); + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + /* + * Parse for more labels. + * This sets lflags and pst->last_pattern correctly. + */ + rc = npc_parse_mpls_label_stack(pst, &lflags); + if (rc != 0) + return rc; + + pst->tunnel = 1; + pst->pattern = pst->last_pattern; + + return npc_update_parse_state(pst, &info, lid, lt, lflags); +} + +static inline void +npc_check_lc_ip_tunnel(struct npc_parse_state *pst) +{ + const struct roc_npc_item_info *pattern = pst->pattern + 1; + + pattern = npc_parse_skip_void_and_any_items(pattern); + if (pattern->type == ROC_NPC_ITEM_TYPE_MPLS || + pattern->type == ROC_NPC_ITEM_TYPE_IPV4 || + pattern->type == ROC_NPC_ITEM_TYPE_IPV6) + pst->tunnel = 1; +} + +int +npc_parse_lc(struct npc_parse_state *pst) +{ + uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt; + int rc; + + if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS) + return npc_parse_mpls(pst, NPC_LID_LC); + + info.hw_mask = &hw_mask; + info.spec = NULL; + info.mask = NULL; + info.hw_hdr_len = 0; + lid = NPC_LID_LC; + + switch (pst->pattern->type) { + case ROC_NPC_ITEM_TYPE_IPV4: + lt = NPC_LT_LC_IP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_IPV6: + lid = NPC_LID_LC; + lt = NPC_LT_LC_IP6; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4: + lt = NPC_LT_LC_ARP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_IPV6_EXT: + lid = NPC_LID_LC; + lt = NPC_LT_LC_IP6_EXT; + info.len = pst->pattern->size; + info.hw_hdr_len = 40; + break; + case ROC_NPC_ITEM_TYPE_L3_CUSTOM: + lt = NPC_LT_LC_CUSTOM0; + info.len = pst->pattern->size; + break; + default: + /* No match at this layer */ + return 0; + } + + /* Identify if IP tunnels MPLS or IPv4/v6 */ + npc_check_lc_ip_tunnel(pst); + + npc_get_hw_supp_mask(pst, &info, lid, lt); + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + return npc_update_parse_state(pst, &info, lid, lt, 0); +} + +int +npc_parse_ld(struct npc_parse_state *pst) +{ + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt, lflags; + int rc; + + if (pst->tunnel) { + /* We have already parsed MPLS or IPv4/v6 followed + * by MPLS or IPv4/v6. Subsequent TCP/UDP etc + * would be parsed as tunneled versions. Skip + * this layer, except for tunneled MPLS. If LC is + * MPLS, we have anyway skipped all stacked MPLS + * labels. + */ + if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS) + return npc_parse_mpls(pst, NPC_LID_LD); + return 0; + } + info.hw_mask = &hw_mask; + info.spec = NULL; + info.mask = NULL; + info.def_mask = NULL; + info.len = 0; + info.hw_hdr_len = 0; + + lid = NPC_LID_LD; + lflags = 0; + + switch (pst->pattern->type) { + case ROC_NPC_ITEM_TYPE_ICMP: + if (pst->lt[NPC_LID_LC] == NPC_LT_LC_IP6) + lt = NPC_LT_LD_ICMP6; + else + lt = NPC_LT_LD_ICMP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_UDP: + lt = NPC_LT_LD_UDP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_IGMP: + lt = NPC_LT_LD_IGMP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_TCP: + lt = NPC_LT_LD_TCP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_SCTP: + lt = NPC_LT_LD_SCTP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_GRE: + lt = NPC_LT_LD_GRE; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_GRE_KEY: + lt = NPC_LT_LD_GRE; + info.len = pst->pattern->size; + info.hw_hdr_len = 4; + break; + case ROC_NPC_ITEM_TYPE_NVGRE: + lt = NPC_LT_LD_NVGRE; + lflags = NPC_F_GRE_NVGRE; + info.len = pst->pattern->size; + /* Further IP/Ethernet are parsed as tunneled */ + pst->tunnel = 1; + break; + default: + return 0; + } + + npc_get_hw_supp_mask(pst, &info, lid, lt); + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + return npc_update_parse_state(pst, &info, lid, lt, lflags); +} + +int +npc_parse_le(struct npc_parse_state *pst) +{ + const struct roc_npc_item_info *pattern = pst->pattern; + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt, lflags; + int rc; + + if (pst->tunnel) + return 0; + + if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS) + return npc_parse_mpls(pst, NPC_LID_LE); + + info.spec = NULL; + info.mask = NULL; + info.hw_mask = NULL; + info.def_mask = NULL; + info.len = 0; + info.hw_hdr_len = 0; + lid = NPC_LID_LE; + lflags = 0; + + /* Ensure we are not matching anything in UDP */ + rc = npc_parse_item_basic(pattern, &info); + if (rc) + return rc; + + info.hw_mask = &hw_mask; + pattern = npc_parse_skip_void_and_any_items(pattern); + switch (pattern->type) { + case ROC_NPC_ITEM_TYPE_VXLAN: + lflags = NPC_F_UDP_VXLAN; + info.len = pattern->size; + lt = NPC_LT_LE_VXLAN; + break; + case ROC_NPC_ITEM_TYPE_GTPC: + lflags = NPC_F_UDP_GTP_GTPC; + info.len = pattern->size; + lt = NPC_LT_LE_GTPC; + break; + case ROC_NPC_ITEM_TYPE_GTPU: + lflags = NPC_F_UDP_GTP_GTPU_G_PDU; + info.len = pattern->size; + lt = NPC_LT_LE_GTPU; + break; + case ROC_NPC_ITEM_TYPE_GENEVE: + lflags = NPC_F_UDP_GENEVE; + info.len = pattern->size; + lt = NPC_LT_LE_GENEVE; + break; + case ROC_NPC_ITEM_TYPE_VXLAN_GPE: + lflags = NPC_F_UDP_VXLANGPE; + info.len = pattern->size; + lt = NPC_LT_LE_VXLANGPE; + break; + case ROC_NPC_ITEM_TYPE_ESP: + lt = NPC_LT_LE_ESP; + info.len = pst->pattern->size; + break; + default: + return 0; + } + + pst->tunnel = 1; + + npc_get_hw_supp_mask(pst, &info, lid, lt); + rc = npc_parse_item_basic(pattern, &info); + if (rc != 0) + return rc; + + return npc_update_parse_state(pst, &info, lid, lt, lflags); +} + +int +npc_parse_lf(struct npc_parse_state *pst) +{ + const struct roc_npc_item_info *pattern, *last_pattern; + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt, lflags; + int nr_vlans = 0; + int rc; + + /* We hit this layer if there is a tunneling protocol */ + if (!pst->tunnel) + return 0; + + if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH) + return 0; + + lid = NPC_LID_LF; + lt = NPC_LT_LF_TU_ETHER; + lflags = 0; + + /* No match support for vlan tags */ + info.hw_mask = NULL; + info.len = pst->pattern->size; + info.spec = NULL; + info.mask = NULL; + info.hw_hdr_len = 0; + + /* Look ahead and find out any VLAN tags. These can be + * detected but no data matching is available. + */ + last_pattern = pst->pattern; + pattern = pst->pattern + 1; + pattern = npc_parse_skip_void_and_any_items(pattern); + while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { + nr_vlans++; + last_pattern = pattern; + pattern++; + pattern = npc_parse_skip_void_and_any_items(pattern); + } + switch (nr_vlans) { + case 0: + break; + case 1: + lflags = NPC_F_TU_ETHER_CTAG; + break; + case 2: + lflags = NPC_F_TU_ETHER_STAG_CTAG; + break; + default: + return NPC_ERR_PATTERN_NOTSUP; + } + + info.hw_mask = &hw_mask; + info.len = pst->pattern->size; + info.hw_hdr_len = 0; + npc_get_hw_supp_mask(pst, &info, lid, lt); + info.spec = NULL; + info.mask = NULL; + + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + pst->pattern = last_pattern; + + return npc_update_parse_state(pst, &info, lid, lt, lflags); +} + +int +npc_parse_lg(struct npc_parse_state *pst) +{ + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt; + int rc; + + if (!pst->tunnel) + return 0; + + info.hw_mask = &hw_mask; + info.spec = NULL; + info.mask = NULL; + info.hw_hdr_len = 0; + lid = NPC_LID_LG; + + if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV4) { + lt = NPC_LT_LG_TU_IP; + info.len = pst->pattern->size; + } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV6) { + lt = NPC_LT_LG_TU_IP6; + info.len = pst->pattern->size; + } else { + /* There is no tunneled IP header */ + return 0; + } + + npc_get_hw_supp_mask(pst, &info, lid, lt); + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + return npc_update_parse_state(pst, &info, lid, lt, 0); +} + +int +npc_parse_lh(struct npc_parse_state *pst) +{ + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; + struct npc_parse_item_info info; + int lid, lt; + int rc; + + if (!pst->tunnel) + return 0; + + info.hw_mask = &hw_mask; + info.spec = NULL; + info.mask = NULL; + info.hw_hdr_len = 0; + lid = NPC_LID_LH; + + switch (pst->pattern->type) { + case ROC_NPC_ITEM_TYPE_UDP: + lt = NPC_LT_LH_TU_UDP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_TCP: + lt = NPC_LT_LH_TU_TCP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_SCTP: + lt = NPC_LT_LH_TU_SCTP; + info.len = pst->pattern->size; + break; + case ROC_NPC_ITEM_TYPE_ESP: + lt = NPC_LT_LH_TU_ESP; + info.len = pst->pattern->size; + break; + default: + return 0; + } + + npc_get_hw_supp_mask(pst, &info, lid, lt); + rc = npc_parse_item_basic(pst->pattern, &info); + if (rc != 0) + return rc; + + return npc_update_parse_state(pst, &info, lid, lt, 0); +} diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h index ef1e991..23250fa 100644 --- a/drivers/common/cnxk/roc_npc_priv.h +++ b/drivers/common/cnxk/roc_npc_priv.h @@ -402,11 +402,24 @@ void npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, int lt); int npc_parse_item_basic(const struct roc_npc_item_info *item, struct npc_parse_item_info *info); +int npc_parse_meta_items(struct npc_parse_state *pst); +int npc_parse_higig2_hdr(struct npc_parse_state *pst); +int npc_parse_cpt_hdr(struct npc_parse_state *pst); +int npc_parse_la(struct npc_parse_state *pst); +int npc_parse_lb(struct npc_parse_state *pst); +int npc_parse_lc(struct npc_parse_state *pst); +int npc_parse_ld(struct npc_parse_state *pst); +int npc_parse_le(struct npc_parse_state *pst); +int npc_parse_lf(struct npc_parse_state *pst); +int npc_parse_lg(struct npc_parse_state *pst); +int npc_parse_lh(struct npc_parse_state *pst); int npc_mcam_fetch_kex_cfg(struct npc *npc); int npc_check_preallocated_entry_cache(struct mbox *mbox, struct roc_npc_flow *flow, struct npc *npc); int npc_flow_free_all_resources(struct npc *npc); +const struct roc_npc_item_info * +npc_parse_skip_void_and_any_items(const struct roc_npc_item_info *pattern); int npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc); uint64_t npc_get_kex_capability(struct npc *npc); -- 2.8.4