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 0FB65A0C46; Fri, 18 Jun 2021 12:40:15 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3346B41125; Fri, 18 Jun 2021 12:39:43 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 8370E4111C for ; Fri, 18 Jun 2021 12:39:40 +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 15IAZZJe000323 for ; Fri, 18 Jun 2021 03:39:39 -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=W4kAjZiiXUkx8tT2fuIdJCHPkUrnN7sPNqnTf5MqMCs=; b=Ol6MleTR4+3fXWbnPEz7Pp83I+hdkqmF2a0JEWXYjKatLfMzL2/PyzXQ/NgUf7nhHr59 hTzZQc99LxnUc+5zOe2mvmAvmxRViz/ATqnRdY/jgV27u/OBgYzr2O/mAGghfYnBqB4A 09QPXPof5vRm8WsccV3KbrCPyAaCh306B+ZgWlA3fJmaowiFCHVT8C/IGpS8BbFsMMBI S/eqTIBfeHvPPm4cwyC318Ckg2/EkZ2F5qzatcElW0aGQbXAVF1Lo9pq2CQB1eEup+EE w+8SMbmYFvSSgeFIt4D/lLOzp1Gqc+/jl+PXciqTFrqc8S9Pwlqm1kOLuRdlSrab1ceV 0Q== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com with ESMTP id 398r750cyp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Fri, 18 Jun 2021 03:39:39 -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.18; Fri, 18 Jun 2021 03:39:38 -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.18 via Frontend Transport; Fri, 18 Jun 2021 03:39:38 -0700 Received: from hyd1588t430.marvell.com (unknown [10.29.52.204]) by maili.marvell.com (Postfix) with ESMTP id 2AC645B695A; Fri, 18 Jun 2021 03:38:49 -0700 (PDT) From: Nithin Dabilpuram To: CC: , , , , , , , Date: Fri, 18 Jun 2021 16:06:46 +0530 Message-ID: <20210618103741.26526-8-ndabilpuram@marvell.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20210618103741.26526-1-ndabilpuram@marvell.com> References: <20210306153404.10781-1-ndabilpuram@marvell.com> <20210618103741.26526-1-ndabilpuram@marvell.com> MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-ORIG-GUID: GRhszc_2R0PCyMouUrXMvf_5-oWn95p1 X-Proofpoint-GUID: GRhszc_2R0PCyMouUrXMvf_5-oWn95p1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.790 definitions=2021-06-18_04:2021-06-18, 2021-06-18 signatures=0 Subject: [dpdk-dev] [PATCH v3 07/62] common/cnxk: support for VLAN push and pop flow actions 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: Satheesh Paul Add roc API to configure VLAN tag addition and removal. Signed-off-by: Satheesh Paul --- drivers/common/cnxk/roc_npc.c | 255 +++++++++++++++++++++++++++++++++++-- drivers/common/cnxk/roc_npc.h | 24 ++++ drivers/common/cnxk/roc_npc_mcam.c | 2 +- drivers/common/cnxk/roc_npc_priv.h | 1 + drivers/common/cnxk/version.map | 2 + 5 files changed, 269 insertions(+), 15 deletions(-) diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c index e6a5036..bb55f3d 100644 --- a/drivers/common/cnxk/roc_npc.c +++ b/drivers/common/cnxk/roc_npc.c @@ -6,6 +6,23 @@ #include "roc_priv.h" int +roc_npc_vtag_actions_get(struct roc_npc *roc_npc) +{ + struct npc *npc = roc_npc_to_npc_priv(roc_npc); + + return npc->vtag_actions; +} + +int +roc_npc_vtag_actions_sub_return(struct roc_npc *roc_npc, uint32_t count) +{ + struct npc *npc = roc_npc_to_npc_priv(roc_npc); + + npc->vtag_actions -= count; + return npc->vtag_actions; +} + +int roc_npc_mcam_free_counter(struct roc_npc *roc_npc, uint16_t ctr_id) { struct npc *npc = roc_npc_to_npc_priv(roc_npc); @@ -330,6 +347,7 @@ npc_parse_actions(struct npc *npc, const struct roc_npc_attr *attr, const struct roc_npc_action_mark *act_mark; const struct roc_npc_action_queue *act_q; const struct roc_npc_action_vf *vf_act; + bool vlan_insert_action = false; int sel_act, req_act = 0; uint16_t pf_func, vf_id; int errcode = 0; @@ -417,25 +435,69 @@ npc_parse_actions(struct npc *npc, const struct roc_npc_attr *attr, req_act |= ROC_NPC_ACTION_TYPE_SEC; rq = 0; break; + case ROC_NPC_ACTION_TYPE_VLAN_STRIP: + req_act |= ROC_NPC_ACTION_TYPE_VLAN_STRIP; + break; + case ROC_NPC_ACTION_TYPE_VLAN_INSERT: + req_act |= ROC_NPC_ACTION_TYPE_VLAN_INSERT; + break; + case ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT: + req_act |= ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT; + break; + case ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT: + req_act |= ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT; + break; default: errcode = NPC_ERR_ACTION_NOTSUP; goto err_exit; } } + if (req_act & (ROC_NPC_ACTION_TYPE_VLAN_INSERT | + ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT | + ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT)) + vlan_insert_action = true; + + if ((req_act & (ROC_NPC_ACTION_TYPE_VLAN_INSERT | + ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT | + ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT)) == + ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT) { + plt_err("PCP insert action can't be supported alone"); + errcode = NPC_ERR_ACTION_NOTSUP; + goto err_exit; + } + + /* Both STRIP and INSERT actions are not supported */ + if (vlan_insert_action && (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP)) { + errcode = NPC_ERR_ACTION_NOTSUP; + goto err_exit; + } + /* Check if actions specified are compatible */ if (attr->egress) { - /* Only DROP/COUNT is supported */ - if (!(req_act & ROC_NPC_ACTION_TYPE_DROP)) { + if (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP) { + plt_err("VLAN pop action is not supported on Egress"); errcode = NPC_ERR_ACTION_NOTSUP; goto err_exit; - } else if (req_act & ~(ROC_NPC_ACTION_TYPE_DROP | - ROC_NPC_ACTION_TYPE_COUNT)) { + } + + if (req_act & ROC_NPC_ACTION_TYPE_DROP) { + flow->npc_action = NIX_TX_ACTIONOP_DROP; + } else if ((req_act & ROC_NPC_ACTION_TYPE_COUNT) || + vlan_insert_action) { + flow->npc_action = NIX_TX_ACTIONOP_UCAST_DEFAULT; + } else { + plt_err("Unsupported action for egress"); errcode = NPC_ERR_ACTION_NOTSUP; goto err_exit; } - flow->npc_action = NIX_TX_ACTIONOP_DROP; + goto set_pf_func; + } else { + if (vlan_insert_action) { + errcode = NPC_ERR_ACTION_NOTSUP; + goto err_exit; + } } /* We have already verified the attr, this is ingress. @@ -463,6 +525,13 @@ npc_parse_actions(struct npc *npc, const struct roc_npc_attr *attr, goto err_exit; } + if (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP) + npc->vtag_actions++; + + /* Only VLAN action is provided */ + if (req_act == ROC_NPC_ACTION_TYPE_VLAN_STRIP) + flow->npc_action = NIX_RX_ACTIONOP_UCAST; + /* Set NIX_RX_ACTIONOP */ if (req_act & (ROC_NPC_ACTION_TYPE_PF | ROC_NPC_ACTION_TYPE_VF)) { flow->npc_action = NIX_RX_ACTIONOP_UCAST; @@ -774,6 +843,161 @@ roc_npc_mark_actions_sub_return(struct roc_npc *roc_npc, uint32_t count) return npc->mark_actions; } +static int +npc_vtag_cfg_delete(struct roc_npc *roc_npc, struct roc_npc_flow *flow) +{ + struct roc_nix *roc_nix = roc_npc->roc_nix; + struct nix_vtag_config *vtag_cfg; + struct nix_vtag_config_rsp *rsp; + struct mbox *mbox; + struct nix *nix; + int rc = 0; + + union { + uint64_t reg; + struct nix_tx_vtag_action_s act; + } tx_vtag_action; + + nix = roc_nix_to_nix_priv(roc_nix); + mbox = (&nix->dev)->mbox; + + tx_vtag_action.reg = flow->vtag_action; + vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox); + + if (vtag_cfg == NULL) + return -ENOSPC; + + vtag_cfg->cfg_type = VTAG_TX; + vtag_cfg->vtag_size = NIX_VTAGSIZE_T4; + vtag_cfg->tx.vtag0_idx = tx_vtag_action.act.vtag0_def; + vtag_cfg->tx.free_vtag0 = true; + + rc = mbox_process_msg(mbox, (void *)&rsp); + if (rc) + return rc; + + return 0; +} + +static int +npc_vtag_action_program(struct roc_npc *roc_npc, + const struct roc_npc_action actions[], + struct roc_npc_flow *flow) +{ + uint16_t vlan_id = 0, vlan_ethtype = ROC_ETHER_TYPE_VLAN; + struct npc *npc = roc_npc_to_npc_priv(roc_npc); + struct roc_nix *roc_nix = roc_npc->roc_nix; + struct nix_vtag_config *vtag_cfg; + struct nix_vtag_config_rsp *rsp; + uint64_t rx_vtag_action = 0; + uint8_t vlan_pcp = 0; + struct mbox *mbox; + struct nix *nix; + int rc; + + union { + uint64_t reg; + struct nix_tx_vtag_action_s act; + } tx_vtag_action; + + nix = roc_nix_to_nix_priv(roc_nix); + mbox = (&nix->dev)->mbox; + + flow->vtag_insert_enabled = false; + + for (; actions->type != ROC_NPC_ACTION_TYPE_END; actions++) { + if (actions->type == ROC_NPC_ACTION_TYPE_VLAN_STRIP) { + if (npc->vtag_actions == 1) { + vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox); + + if (vtag_cfg == NULL) + return -ENOSPC; + + vtag_cfg->cfg_type = VTAG_RX; + vtag_cfg->rx.strip_vtag = 1; + /* Always capture */ + vtag_cfg->rx.capture_vtag = 1; + vtag_cfg->vtag_size = NIX_VTAGSIZE_T4; + vtag_cfg->rx.vtag_type = 0; + + rc = mbox_process(mbox); + if (rc) + return rc; + } + + rx_vtag_action |= (NIX_RX_VTAGACTION_VTAG_VALID << 15); + rx_vtag_action |= ((uint64_t)NPC_LID_LB << 8); + rx_vtag_action |= NIX_RX_VTAGACTION_VTAG0_RELPTR; + flow->vtag_action = rx_vtag_action; + } else if (actions->type == ROC_NPC_ACTION_TYPE_VLAN_INSERT) { + const struct roc_npc_action_of_set_vlan_vid *vtag = + (const struct roc_npc_action_of_set_vlan_vid *) + actions->conf; + vlan_id = plt_be_to_cpu_16(vtag->vlan_vid); + if (vlan_id > 0xfff) { + plt_err("Invalid vlan_id for set vlan action"); + return -EINVAL; + } + flow->vtag_insert_enabled = true; + } else if (actions->type == + ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT) { + const struct roc_npc_action_of_push_vlan *ethtype = + (const struct roc_npc_action_of_push_vlan *) + actions->conf; + vlan_ethtype = plt_be_to_cpu_16(ethtype->ethertype); + if (vlan_ethtype != ROC_ETHER_TYPE_VLAN && + vlan_ethtype != ROC_ETHER_TYPE_QINQ) { + plt_err("Invalid ethtype specified for push" + " vlan action"); + return -EINVAL; + } + flow->vtag_insert_enabled = true; + } else if (actions->type == + ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT) { + const struct roc_npc_action_of_set_vlan_pcp *pcp = + (const struct roc_npc_action_of_set_vlan_pcp *) + actions->conf; + vlan_pcp = pcp->vlan_pcp; + if (vlan_pcp > 0x7) { + plt_err("Invalid PCP value for pcp action"); + return -EINVAL; + } + flow->vtag_insert_enabled = true; + } + } + + if (flow->vtag_insert_enabled) { + vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox); + + if (vtag_cfg == NULL) + return -ENOSPC; + + vtag_cfg->cfg_type = VTAG_TX; + vtag_cfg->vtag_size = NIX_VTAGSIZE_T4; + vtag_cfg->tx.vtag0 = + ((vlan_ethtype << 16) | (vlan_pcp << 13) | vlan_id); + + vtag_cfg->tx.cfg_vtag0 = 1; + rc = mbox_process_msg(mbox, (void *)&rsp); + if (rc) + return rc; + + if (rsp->vtag0_idx < 0) { + plt_err("Failed to config TX VTAG action"); + return -EINVAL; + } + + tx_vtag_action.reg = 0; + tx_vtag_action.act.vtag0_def = rsp->vtag0_idx; + tx_vtag_action.act.vtag0_lid = NPC_LID_LA; + tx_vtag_action.act.vtag0_op = NIX_TX_VTAGOP_INSERT; + tx_vtag_action.act.vtag0_relptr = + NIX_TX_VTAGACTION_VTAG0_RELPTR; + flow->vtag_action = tx_vtag_action.reg; + } + return 0; +} + struct roc_npc_flow * roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, const struct roc_npc_item_info pattern[], @@ -798,6 +1022,12 @@ roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; } + rc = npc_vtag_action_program(roc_npc, actions, flow); + if (rc != 0) { + *errcode = rc; + goto err_exit; + } + parse_state.is_vf = !roc_nix_is_pf(roc_npc->roc_nix); rc = npc_program_mcam(npc, &parse_state, 1); @@ -858,23 +1088,20 @@ roc_npc_flow_destroy(struct roc_npc *roc_npc, struct roc_npc_flow *flow) { struct npc *npc = roc_npc_to_npc_priv(roc_npc); struct plt_bitmap *bmap; - uint16_t match_id; int rc; - match_id = (flow->npc_action >> NPC_RX_ACT_MATCH_OFFSET) & - NPC_RX_ACT_MATCH_MASK; - - if (match_id && match_id < NPC_ACTION_FLAG_DEFAULT) { - if (npc->mark_actions == 0) - return NPC_ERR_PARAM; - } - rc = npc_rss_group_free(npc, flow); if (rc != 0) { plt_err("Failed to free rss action rc = %d", rc); return rc; } + if (flow->vtag_insert_enabled) { + rc = npc_vtag_cfg_delete(roc_npc, flow); + if (rc != 0) + return rc; + } + rc = npc_mcam_free_entry(npc, flow->mcam_id); if (rc != 0) return rc; diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h index cf6f732..2c0a536 100644 --- a/drivers/common/cnxk/roc_npc.h +++ b/drivers/common/cnxk/roc_npc.h @@ -62,6 +62,10 @@ enum roc_npc_action_type { ROC_NPC_ACTION_TYPE_COUNT = (1 << 9), ROC_NPC_ACTION_TYPE_PF = (1 << 10), ROC_NPC_ACTION_TYPE_VF = (1 << 11), + ROC_NPC_ACTION_TYPE_VLAN_STRIP = (1 << 12), + ROC_NPC_ACTION_TYPE_VLAN_INSERT = (1 << 13), + ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT = (1 << 14), + ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT = (1 << 15), }; struct roc_npc_action { @@ -83,6 +87,18 @@ struct roc_npc_action_queue { uint16_t index; /**< Queue index to use. */ }; +struct roc_npc_action_of_push_vlan { + uint16_t ethertype; /**< EtherType. */ +}; + +struct roc_npc_action_of_set_vlan_vid { + uint16_t vlan_vid; /**< VLAN id. */ +}; + +struct roc_npc_action_of_set_vlan_pcp { + uint8_t vlan_pcp; /**< VLAN priority. */ +}; + struct roc_npc_attr { uint32_t priority; /**< Rule priority level within group. */ uint32_t ingress : 1; /**< Rule applies to ingress traffic. */ @@ -107,6 +123,7 @@ struct roc_npc_flow { uint64_t mcam_mask[ROC_NPC_MAX_MCAM_WIDTH_DWORDS]; uint64_t npc_action; uint64_t vtag_action; + bool vtag_insert_enabled; #define ROC_NPC_MAX_FLOW_PATTERNS 32 struct roc_npc_flow_dump_data dump_data[ROC_NPC_MAX_FLOW_PATTERNS]; uint16_t num_patterns; @@ -138,6 +155,10 @@ enum roc_npc_intf { ROC_NPC_INTF_MAX = 2, }; +enum flow_vtag_cfg_dir { VTAG_TX, VTAG_RX }; +#define ROC_ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */ +#define ROC_ETHER_TYPE_QINQ 0x88A8 /**< IEEE 802.1ad QinQ tagging. */ + struct roc_npc { struct roc_nix *roc_nix; uint8_t switch_header_type; @@ -199,4 +220,7 @@ void __roc_api roc_npc_flow_mcam_dump(FILE *file, struct roc_npc *roc_npc, int __roc_api roc_npc_mark_actions_get(struct roc_npc *roc_npc); int __roc_api roc_npc_mark_actions_sub_return(struct roc_npc *roc_npc, uint32_t count); +int __roc_api roc_npc_vtag_actions_get(struct roc_npc *roc_npc); +int __roc_api roc_npc_vtag_actions_sub_return(struct roc_npc *roc_npc, + uint32_t count); #endif /* _ROC_NPC_H_ */ diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c index ff0676d..8ccaaad 100644 --- a/drivers/common/cnxk/roc_npc_mcam.c +++ b/drivers/common/cnxk/roc_npc_mcam.c @@ -546,7 +546,7 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, * * Second approach is used now. */ - req->entry_data.vtag_action = 0ULL; + req->entry_data.vtag_action = flow->vtag_action; for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) { req->entry_data.kw[idx] = flow->mcam_data[idx]; diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h index 961583b..484c3ae 100644 --- a/drivers/common/cnxk/roc_npc_priv.h +++ b/drivers/common/cnxk/roc_npc_priv.h @@ -350,6 +350,7 @@ struct npc { uint16_t flow_max_priority; /* Max priority for flow */ uint16_t switch_header_type; /* Suppprted switch header type */ uint32_t mark_actions; /* Number of mark actions */ + uint32_t vtag_actions; /* vtag insert/strip actions */ uint16_t pf_func; /* pf_func of device */ npc_dxcfg_t prx_dxcfg; /* intf, lid, lt, extract */ npc_fxcfg_t prx_fxcfg; /* Flag extract */ diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index 554459b..8a5c839 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -167,6 +167,8 @@ INTERNAL { roc_npc_init; roc_npc_mark_actions_get; roc_npc_mark_actions_sub_return; + roc_npc_vtag_actions_get; + roc_npc_vtag_actions_sub_return; roc_npc_mcam_alloc_entries; roc_npc_mcam_alloc_entry; roc_npc_mcam_clear_counter; -- 2.8.4