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 26EB3A0546; Tue, 6 Apr 2021 16:49:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A10A8141178; Tue, 6 Apr 2021 16:44:05 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 0EFA1141175 for ; Tue, 6 Apr 2021 16:44:02 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 136Ee7Qm000971 for ; Tue, 6 Apr 2021 07:44:02 -0700 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=dmmaZWVUSDayGwvoYN8LIFgWfwZjTID8C0CFFK4DbtY=; b=K+37ca7KyPiwIPqu0PbYdCHZN/M7Rg3y1Po/c1GfSG6o6lu925/SBe+duxuCNxy68EIa wQaboznhPaNX8odkGt+o2m35HeUcxF8wfITPnww1eKqjWN0f/9Ai9h80Vjf27Er5ffXx vx80xu8ieCmRORS51g3Z05UwsV3j3Q6V351ui5OGfNyUl781flLOHx3K7hUPDvKZ8NJ4 ANhiKDh6FGhcge6i5CxFyfzqrwoKknUgYRaiiQGtnFyOB9oCU13mT0LsQM4NfVwYT4Es hxgeSH4VwJ9pjQDlxK1yI+NklmmdcgULTCtQgqT70huJ1/ayUf4HfRYKcx8Lo+WrtYyh cg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com with ESMTP id 37r72p30nr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Tue, 06 Apr 2021 07:44:01 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 6 Apr 2021 07:44:00 -0700 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; Tue, 6 Apr 2021 07:44:00 -0700 Received: from hyd1588t430.marvell.com (unknown [10.29.52.204]) by maili.marvell.com (Postfix) with ESMTP id 14EE13F7040; Tue, 6 Apr 2021 07:43:57 -0700 (PDT) From: Nithin Dabilpuram To: CC: , , , , , , Date: Tue, 6 Apr 2021 20:11:35 +0530 Message-ID: <20210406144144.19925-44-ndabilpuram@marvell.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20210406144144.19925-1-ndabilpuram@marvell.com> References: <20210305133918.8005-1-ndabilpuram@marvell.com> <20210406144144.19925-1-ndabilpuram@marvell.com> MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-GUID: 7Z5NGUCgzsGKjyJVGkuyU2AfpoteK8Ny X-Proofpoint-ORIG-GUID: 7Z5NGUCgzsGKjyJVGkuyU2AfpoteK8Ny X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369, 18.0.761 definitions=2021-04-06_03:2021-04-01, 2021-04-06 signatures=0 Subject: [dpdk-dev] [PATCH v5 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 7c83050..9dd4c23 100644 --- a/drivers/common/cnxk/meson.build +++ b/drivers/common/cnxk/meson.build @@ -35,6 +35,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..d07f91d --- /dev/null +++ b/drivers/common/cnxk/roc_npc_parse.c @@ -0,0 +1,703 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 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 13768f9..dcf26c0 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