From patchwork Thu Apr 1 12:38:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nithin Dabilpuram X-Patchwork-Id: 90416 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 102CCA0548; Thu, 1 Apr 2021 14:45:02 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0CD841412CD; Thu, 1 Apr 2021 14:40:49 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 6EF851412CB for ; Thu, 1 Apr 2021 14:40:47 +0200 (CEST) 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 131CPLcs019084 for ; Thu, 1 Apr 2021 05:40:46 -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=Irgnhl1KqUy2dgB/xWZg9TC71utv5WE8x45LYBDmtwDtjohHgDhE2YOoxzj9EPp/NjEU 6DB4lg6M6MQf1D4wDprZX4iHB8qj3uR8lcGSUp4vj4ucbVnie5ToN3DXJRVSSni+12iv s4yE9Lxe00fppWvdXPK5Z5bIKXAyJ5Wa/MWyHqIkiszMt1lNsIJs8Rnmj/vPU8/CMDGI Tq0egcLk23HiNU77nODggeyGrTcpbsuvuIrQR3h2hJJXjKjaByvSshbgOeRbeD3xXyxg vjFUa0Q/g9BWJWQ3Z6/Y/fbQSTCgvVc5PPD/NUkMiJLPMZw+dEgn6yebitO6+EBAXFqO Hw== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com with ESMTP id 37n28jje6j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 01 Apr 2021 05:40:46 -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; Thu, 1 Apr 2021 05:40:44 -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; Thu, 1 Apr 2021 05:40:44 -0700 Received: from hyd1588t430.marvell.com (unknown [10.29.52.204]) by maili.marvell.com (Postfix) with ESMTP id 3B7703F7044; Thu, 1 Apr 2021 05:40:42 -0700 (PDT) From: Nithin Dabilpuram To: CC: , , , , , , Date: Thu, 1 Apr 2021 18:08:08 +0530 Message-ID: <20210401123817.14348-44-ndabilpuram@marvell.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20210401123817.14348-1-ndabilpuram@marvell.com> References: <20210305133918.8005-1-ndabilpuram@marvell.com> <20210401123817.14348-1-ndabilpuram@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: HEmiy4YTsha9lk3kwuCegK_YEsww5D47 X-Proofpoint-ORIG-GUID: HEmiy4YTsha9lk3kwuCegK_YEsww5D47 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369, 18.0.761 definitions=2021-04-01_05:2021-03-31, 2021-04-01 signatures=0 Subject: [dpdk-dev] [PATCH v3 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);