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 52BE8A0350; Mon, 3 Jan 2022 07:19:35 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 95F7A4114F; Mon, 3 Jan 2022 07:19:30 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id CECD94003C for ; Mon, 3 Jan 2022 07:19:28 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 202MqlMA009981 for ; Sun, 2 Jan 2022 22:19:28 -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-transfer-encoding : content-type; s=pfpt0220; bh=e2vEVhcPrmLO2kLtjLLVtrOU3yZDCwpYTSSbYjnwio0=; b=dxwzXaN4h1tZoc7disUWqt34xYJ3BZvjQxSsOkctYYCD4T6xVGCjA09grmHMw+Y1SF0o d3jmov/2LgYhsyHDmZ2bn+T3aSDNggSSgXHJUmmRJPHjP8rsDjic7aGsMCuEV6ohNbYe mQH6A3nPiR0rdCxcGtd6HlxEns5A0p2FID+xaMPtGhOkhu9MqzGiP5KIdGz7AFTjE2rl 44SCoZ/2NpAtFlGLYmxias6USrBmOmmoA7gtsjTFOJ3upZUiec1jWv2wG2N/cuVkU8Nq 89gEo9/0hIPyNM09f2DU4uMyjBp2nskKa2pSzcfQQDFikiyx3uUPVKXFJdqMt+UtGynu Rw== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3daqbrmayx-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Sun, 02 Jan 2022 22:19:28 -0800 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Sun, 2 Jan 2022 22:19:22 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sun, 2 Jan 2022 22:19:22 -0800 Received: from localhost.localdomain (unknown [10.28.34.33]) by maili.marvell.com (Postfix) with ESMTP id 867F93F7095; Sun, 2 Jan 2022 22:19:20 -0800 (PST) From: To: Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao CC: , Satheesh Paul Subject: [dpdk-dev] [PATCH v2 3/4] common/cnxk: support matching VLAN existence in RTE Flow Date: Mon, 3 Jan 2022 11:49:08 +0530 Message-ID: <20220103061909.83319-3-psatheesh@marvell.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20220103061909.83319-1-psatheesh@marvell.com> References: <20220103055709.82768-1-psatheesh@marvell.com> <20220103061909.83319-1-psatheesh@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-GUID: fb6McvlTRhzaT_OaJmLWLnC9fqLvKQIf X-Proofpoint-ORIG-GUID: fb6McvlTRhzaT_OaJmLWLnC9fqLvKQIf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-03_02,2022-01-01_01,2021-12-02_01 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 From: Satheesh Paul Support matching existence of VLAN after RTE_FLOW_ITEM_TYPE_ETH and RTE_FLOW_ITEM_TYPE_VLAN items. Signed-off-by: Satheesh Paul Reviewed-by: Kiran Kumar Kokkilagadda --- drivers/common/cnxk/roc_npc.h | 56 ++++++++++++++++++++++++++++- drivers/common/cnxk/roc_npc_mcam.c | 37 ++++++++++++++++--- drivers/common/cnxk/roc_npc_parse.c | 56 +++++++++++++++++++++++++---- drivers/common/cnxk/roc_npc_priv.h | 7 ++++ drivers/common/cnxk/roc_platform.h | 6 +++- 5 files changed, 150 insertions(+), 12 deletions(-) diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h index 8b57678863..6ab185e188 100644 --- a/drivers/common/cnxk/roc_npc.h +++ b/drivers/common/cnxk/roc_npc.h @@ -58,6 +58,60 @@ struct roc_npc_flow_item_raw { const uint8_t *pattern; /**< Byte string to look for. */ }; +struct roc_ether_addr { + uint8_t addr_bytes[PLT_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */ +} plt_aligned(2); + +struct roc_ether_hdr { + struct roc_ether_addr d_addr; /**< Destination address. */ + PLT_STD_C11 + union { + struct roc_ether_addr s_addr; /**< Source address. */ + struct { + struct roc_ether_addr S_addr; + } S_un; /**< Do not use directly; use s_addr instead.*/ + }; + uint16_t ether_type; /**< Frame type. */ +} plt_aligned(2); + +PLT_STD_C11 +struct roc_npc_flow_item_eth { + union { + struct { + /* + * These fields are retained + * for compatibility. + * Please switch to the new header field below. + */ + struct roc_ether_addr dst; /**< Destination MAC. */ + struct roc_ether_addr src; /**< Source MAC. */ + uint16_t type; /**< EtherType or TPID. */ + }; + struct roc_ether_hdr hdr; + }; + uint32_t has_vlan : 1; /**< Packet header contains at least one VLAN. */ + uint32_t reserved : 31; /**< Reserved, must be zero. */ +}; + +struct roc_vlan_hdr { + uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */ + uint16_t eth_proto; /**< Ethernet type of encapsulated frame. */ +} __plt_packed; + +PLT_STD_C11 +struct roc_npc_flow_item_vlan { + union { + struct { + uint16_t tci; /**< Tag control information. */ + uint16_t inner_type; /**< Inner EtherType or TPID. */ + }; + struct roc_vlan_hdr hdr; + }; + uint32_t has_more_vlan : 1; + /**< Packet header contains at least one more VLAN, after this VLAN. */ + uint32_t reserved : 31; /**< Reserved, must be zero. */ +}; + #define ROC_NPC_MAX_ACTION_COUNT 19 enum roc_npc_action_type { @@ -97,7 +151,7 @@ struct roc_npc_action_vf { }; struct roc_npc_action_port_id { - uint32_t original : 1; /**< Use original DPDK port ID if possible. */ + uint32_t original : 1; /**< Use original port ID if possible. */ uint32_t reserved : 31; /**< Reserved, must be zero. */ uint32_t id; /**< port ID. */ }; diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c index 80851d6f9f..2349317c5c 100644 --- a/drivers/common/cnxk/roc_npc_mcam.c +++ b/drivers/common/cnxk/roc_npc_mcam.c @@ -613,6 +613,28 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, return 0; } +static void +npc_set_vlan_ltype(struct npc_parse_state *pst) +{ + uint64_t val, mask; + uint8_t lb_offset; + + lb_offset = + __builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] & + ((1ULL << NPC_LTYPE_LB_OFFSET) - 1)); + lb_offset *= 4; + + mask = ~((0xfULL << lb_offset)); + pst->flow->mcam_data[0] &= mask; + pst->flow->mcam_mask[0] &= mask; + /* NPC_LT_LB_CTAG: 0b0010, NPC_LT_LB_STAG_QINQ: 0b0011 + * Set LB layertype/mask as 0b0010/0b1110 to match both. + */ + val = ((uint64_t)(NPC_LT_LB_CTAG & NPC_LT_LB_STAG_QINQ)) << lb_offset; + pst->flow->mcam_data[0] |= val; + pst->flow->mcam_mask[0] |= (0xeULL << lb_offset); +} + int npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc) { @@ -651,12 +673,16 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc) if (layer_info) { for (idx = 0; idx <= 2; idx++) { if (layer_info & (1 << idx)) { - if (idx == 2) + if (idx == 2) { data = lt; - else if (idx == 1) + mask = 0xf; + } else if (idx == 1) { data = ((flags >> 4) & 0xf); - else + mask = ((flags >> 4) & 0xf); + } else { data = (flags & 0xf); + mask = (flags & 0xf); + } if (data_off >= 64) { data_off = 0; @@ -664,7 +690,7 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc) } key_data[index] |= ((uint64_t)data << data_off); - mask = 0xf; + if (lt == 0) mask = 0; key_mask[index] |= @@ -680,6 +706,9 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc) memcpy(pst->flow->mcam_data, key_data, key_len); memcpy(pst->flow->mcam_mask, key_mask, key_len); + if (pst->set_vlan_ltype_mask) + npc_set_vlan_ltype(pst); + if (pst->is_vf) { (void)mbox_alloc_msg_npc_read_base_steer_rule(npc->mbox); rc = mbox_process_msg(npc->mbox, (void *)&base_rule_rsp); diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c index c9ab9aef28..75724661da 100644 --- a/drivers/common/cnxk/roc_npc_parse.c +++ b/drivers/common/cnxk/roc_npc_parse.c @@ -167,6 +167,7 @@ npc_parse_higig2_hdr(struct npc_parse_state *pst) int npc_parse_la(struct npc_parse_state *pst) { + const struct roc_npc_flow_item_eth *eth_item; uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; struct npc_parse_item_info info; int lid, lt; @@ -176,6 +177,8 @@ npc_parse_la(struct npc_parse_state *pst) if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH) return 0; + eth_item = pst->pattern->spec; + lid = NPC_LID_LA; lt = NPC_LT_LA_ETHER; info.hw_hdr_len = 0; @@ -196,7 +199,7 @@ npc_parse_la(struct npc_parse_state *pst) /* Prepare for parsing the item */ info.hw_mask = &hw_mask; - info.len = pst->pattern->size; + info.len = sizeof(eth_item->hdr); npc_get_hw_supp_mask(pst, &info, lid, lt); info.spec = NULL; info.mask = NULL; @@ -206,13 +209,22 @@ npc_parse_la(struct npc_parse_state *pst) if (rc) return rc; - /* Update pst if not validate only? clash check? */ - return npc_update_parse_state(pst, &info, lid, lt, 0); + rc = npc_update_parse_state(pst, &info, lid, lt, 0); + if (rc) + return rc; + + if (eth_item && eth_item->has_vlan) + pst->set_vlan_ltype_mask = true; + + return 0; } +#define NPC_MAX_SUPPORTED_VLANS 3 + int npc_parse_lb(struct npc_parse_state *pst) { + const struct roc_npc_flow_item_vlan *vlan_item[NPC_MAX_SUPPORTED_VLANS]; const struct roc_npc_item_info *pattern = pst->pattern; const struct roc_npc_item_info *last_pattern; const struct roc_npc_flow_item_raw *raw_spec; @@ -240,10 +252,14 @@ npc_parse_lb(struct npc_parse_state *pst) * supported on first tag only. */ info.hw_mask = NULL; - info.len = pst->pattern->size; + info.len = sizeof(vlan_item[0]->hdr); pattern = pst->pattern; while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { + if (nr_vlans > NPC_MAX_SUPPORTED_VLANS - 1) + return NPC_ERR_PATTERN_NOTSUP; + + vlan_item[nr_vlans] = pattern->spec; nr_vlans++; /* Basic validation of Second/Third vlan item */ @@ -260,12 +276,35 @@ npc_parse_lb(struct npc_parse_state *pst) switch (nr_vlans) { case 1: lt = NPC_LT_LB_CTAG; + if (vlan_item[0] && vlan_item[0]->has_more_vlan) + lt = NPC_LT_LB_STAG_QINQ; break; case 2: + if (vlan_item[1] && vlan_item[1]->has_more_vlan) { + if (!(pst->npc->keyx_supp_nmask[pst->nix_intf] & + 0x3ULL << NPC_LFLAG_LB_OFFSET)) + return NPC_ERR_PATTERN_NOTSUP; + + /* This lflag value will match either one of + * NPC_F_LB_L_WITH_STAG_STAG, + * NPC_F_LB_L_WITH_QINQ_CTAG, + * NPC_F_LB_L_WITH_QINQ_QINQ and + * NPC_F_LB_L_WITH_ITAG (0b0100 to 0b0111). For + * NPC_F_LB_L_WITH_ITAG, ltype is NPC_LT_LB_ETAG + * hence will not match. + */ + + lflags = NPC_F_LB_L_WITH_QINQ_CTAG & + NPC_F_LB_L_WITH_QINQ_QINQ & + NPC_F_LB_L_WITH_STAG_STAG; + } else { + lflags = NPC_F_LB_L_WITH_CTAG; + } lt = NPC_LT_LB_STAG_QINQ; - lflags = NPC_F_STAG_CTAG; break; case 3: + if (vlan_item[2] && vlan_item[2]->has_more_vlan) + return NPC_ERR_PATTERN_NOTSUP; lt = NPC_LT_LB_STAG_QINQ; lflags = NPC_F_STAG_STAG_CTAG; break; @@ -294,10 +333,15 @@ npc_parse_lb(struct npc_parse_state *pst) } info.len = pattern->size; } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_QINQ) { + vlan_item[0] = pst->pattern->spec; info.hw_mask = NULL; - info.len = pst->pattern->size; + info.len = sizeof(vlan_item[0]->hdr); lt = NPC_LT_LB_STAG_QINQ; lflags = NPC_F_STAG_CTAG; + if (vlan_item[0] && vlan_item[0]->has_more_vlan) { + lflags = NPC_F_LB_L_WITH_QINQ_CTAG & + NPC_F_LB_L_WITH_QINQ_QINQ; + } } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_RAW) { raw_spec = pst->pattern->spec; if (raw_spec->relative) diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h index 1a40192599..ef7985f4cf 100644 --- a/drivers/common/cnxk/roc_npc_priv.h +++ b/drivers/common/cnxk/roc_npc_priv.h @@ -67,6 +67,11 @@ #define NPC_ACTION_MAX_VLAN_PARAMS 3 #define NPC_ACTION_MAX_VLANS_STRIPPED 2 +#define NPC_LTYPE_OFFSET_START 7 +/* LB OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags) */ +#define NPC_LTYPE_LB_OFFSET (NPC_LTYPE_OFFSET_START + 5) +#define NPC_LFLAG_LB_OFFSET (NPC_LTYPE_OFFSET_START + 3) + struct npc_action_vtag_info { uint16_t vlan_id; uint16_t vlan_ethtype; @@ -176,6 +181,8 @@ struct npc_parse_state { uint8_t *mcam_data; /* point to flow->mcam_data + key_len */ uint8_t *mcam_mask; /* point to flow->mcam_mask + key_len */ bool is_vf; + /* adjust ltype in MCAM to match at least one vlan */ + bool set_vlan_ltype_mask; }; enum npc_kpu_parser_flag { diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h index 61d4781209..28e67c91a1 100644 --- a/drivers/common/cnxk/roc_platform.h +++ b/drivers/common/cnxk/roc_platform.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,9 @@ #define BITMASK_ULL GENMASK_ULL #define PLT_ALIGN_CEIL RTE_ALIGN_CEIL #define PLT_INIT RTE_INIT - +#ifndef PLT_ETHER_ADDR_LEN +#define PLT_ETHER_ADDR_LEN RTE_ETHER_ADDR_LEN +#endif /** Divide ceil */ #define PLT_DIV_CEIL(x, y) \ ({ \ @@ -82,6 +85,7 @@ #define plt_cpu_to_be_64 rte_cpu_to_be_64 #define plt_be_to_cpu_64 rte_be_to_cpu_64 +#define plt_aligned __rte_aligned #define plt_align32pow2 rte_align32pow2 #define plt_align32prevpow2 rte_align32prevpow2 -- 2.25.4