From patchwork Thu Dec 14 10:58:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Satheesh Paul Antonysamy X-Patchwork-Id: 135194 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 98565436EE; Thu, 14 Dec 2023 11:58:23 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3C15C42FFD; Thu, 14 Dec 2023 11:58:23 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id DB90B40697 for ; Thu, 14 Dec 2023 11:58:21 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 3BE9LPYr002192 for ; Thu, 14 Dec 2023 02:58:21 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:content-type; s=pfpt0220; bh=oISolZ22 6+KCdV4d8WmRfWH6tQEr8gmFY0fVt2w2pVc=; b=JKSABEjdym5ONYhvR83fx6Yp cAphirvB3p8pKbkyOdFZIH6hLc/drTgUwrkW6trMZcCDP4/maTkaVOiwO2p/FgUr qoaicvJ+Vqkr9CDRY3gEUjN2lFXVFbZM/JT/wblW/e6y3WP6PlHcwSPK866imhXk S/+ZE7L7TZV5wopMAoVKXQtiZ5Nni7rkKfEd5eNTIUweGiAFVvbpVsrvy+lpeLcL Um5tO4yt8ZhzSd+bC1tTsKU8bZRXDXaHScxy7TDoPUmVIS9uLsM9Ez997RrcmA9H ixojVYa9oQk2q7S/K4w5APXAqW7W7PkJ1UEepzDsaDOMJGpWfm39sONZvtRRcg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3uyy0m89b1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 14 Dec 2023 02:58:20 -0800 (PST) Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Thu, 14 Dec 2023 02:58:19 -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.48 via Frontend Transport; Thu, 14 Dec 2023 02:58:19 -0800 Received: from satheeshpaullabpc.. (unknown [10.28.34.33]) by maili.marvell.com (Postfix) with ESMTP id B2B2A3F70B8; Thu, 14 Dec 2023 02:58:16 -0800 (PST) From: To: Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao CC: , Satheesh Paul Subject: [dpdk-dev] [PATCH 1/3] common/cnxk: support mirror flow action Date: Thu, 14 Dec 2023 16:28:11 +0530 Message-ID: <20231214105813.570597-1-psatheesh@marvell.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-Proofpoint-GUID: wzft1O3GeuwCiTpZ2MEEyPmZh09FoDUf X-Proofpoint-ORIG-GUID: wzft1O3GeuwCiTpZ2MEEyPmZh09FoDUf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-09_02,2023-12-07_01,2023-05-22_02 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 Add ROC API to support mirror flow action. Signed-off-by: Satheesh Paul Reviewed-by: Kiran Kumar K --- drivers/common/cnxk/roc_mbox.h | 56 +++++++++++++++++ drivers/common/cnxk/roc_nix.h | 8 ++- drivers/common/cnxk/roc_nix_mcast.c | 86 ++++++++++++++++++++++++++ drivers/common/cnxk/roc_npc.c | 94 +++++++++++++++++++++++++---- drivers/common/cnxk/roc_npc.h | 19 +++++- drivers/common/cnxk/roc_npc_mcam.c | 56 +++++++++++++---- drivers/common/cnxk/roc_npc_priv.h | 3 +- drivers/common/cnxk/version.map | 2 + 8 files changed, 295 insertions(+), 29 deletions(-) diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h index 05434aec5a..3257a370bc 100644 --- a/drivers/common/cnxk/roc_mbox.h +++ b/drivers/common/cnxk/roc_mbox.h @@ -298,6 +298,11 @@ struct mbox_msghdr { M(NIX_FREE_BPIDS, 0x8029, nix_free_bpids, nix_bpids, msg_rsp) \ M(NIX_RX_CHAN_CFG, 0x802a, nix_rx_chan_cfg, nix_rx_chan_cfg, \ nix_rx_chan_cfg) \ + M(NIX_MCAST_GRP_CREATE, 0x802b, nix_mcast_grp_create, nix_mcast_grp_create_req, \ + nix_mcast_grp_create_rsp) \ + M(NIX_MCAST_GRP_DESTROY, 0x802c, nix_mcast_grp_destroy, nix_mcast_grp_destroy_req, msg_rsp)\ + M(NIX_MCAST_GRP_UPDATE, 0x802d, nix_mcast_grp_update, nix_mcast_grp_update_req, \ + nix_mcast_grp_update_rsp) \ /* MCS mbox IDs (range 0xa000 - 0xbFFF) */ \ M(MCS_ALLOC_RESOURCES, 0xa000, mcs_alloc_resources, mcs_alloc_rsrc_req, \ mcs_alloc_rsrc_rsp) \ @@ -1768,6 +1773,57 @@ struct nix_rx_chan_cfg { uint64_t __io rsvd; }; +struct nix_mcast_grp_create_req { + struct mbox_msghdr hdr; +#define NIX_MCAST_INGRESS 0 +#define NIX_MCAST_EGRESS 1 + uint8_t __io dir; + uint8_t __io reserved[11]; + /* Reserving few bytes for future requirement */ +}; + +struct nix_mcast_grp_create_rsp { + struct mbox_msghdr hdr; + /* This mcast_grp_idx should be passed during MCAM + * write entry for multicast. AF will identify the + * corresponding multicast table index associated + * with the group id and program the same to MCAM entry. + * This group id is also needed during group delete + * and update request. + */ + uint32_t __io mcast_grp_idx; +}; +struct nix_mcast_grp_destroy_req { + struct mbox_msghdr hdr; + /* Group id returned by nix_mcast_grp_create_rsp */ + uint32_t __io mcast_grp_idx; +}; + +struct nix_mcast_grp_update_req { + struct mbox_msghdr hdr; + /* Group id returned by nix_mcast_grp_create_rsp */ + uint32_t __io mcast_grp_idx; + /* Number of multicast/mirror entries requested */ + uint32_t __io num_mce_entry; +#define NIX_MCE_ENTRY_MAX 64 +#define NIX_RX_RQ 0 +#define NIX_RX_RSS 1 + /* Receive queue or RSS index within pf_func */ + uint32_t __io rq_rss_index[NIX_MCE_ENTRY_MAX]; + uint16_t __io pcifunc[NIX_MCE_ENTRY_MAX]; + uint16_t __io channel[NIX_MCE_ENTRY_MAX]; +#define NIX_MCAST_OP_ADD_ENTRY 0 +#define NIX_MCAST_OP_DEL_ENTRY 1 + /* Destination type. 0:Receive queue, 1:RSS*/ + uint8_t __io dest_type[NIX_MCE_ENTRY_MAX]; + uint8_t __io op; +}; + +struct nix_mcast_grp_update_rsp { + struct mbox_msghdr hdr; + uint32_t __io mce_start_index; +}; + /* Global NIX inline IPSec configuration */ struct nix_inline_ipsec_cfg { struct mbox_msghdr hdr; diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index 82997c38ce..c1ebf971f7 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -1005,6 +1005,10 @@ int __roc_api roc_nix_mcast_mcam_entry_write(struct roc_nix *roc_nix, struct mcam_entry *entry, uint32_t index, uint8_t intf, uint64_t action); -int __roc_api roc_nix_mcast_mcam_entry_ena_dis(struct roc_nix *roc_nix, - uint32_t index, bool enable); +int __roc_api roc_nix_mcast_mcam_entry_ena_dis(struct roc_nix *roc_nix, uint32_t index, + bool enable); +int __roc_api roc_nix_mcast_list_setup(struct mbox *mbox, uint8_t intf, int nb_entries, + uint16_t *pf_funcs, uint16_t *channels, uint32_t *rqs, + uint32_t *grp_index, uint32_t *start_index); +int __roc_api roc_nix_mcast_list_free(struct mbox *mbox, uint32_t mcast_grp_index); #endif /* _ROC_NIX_H_ */ diff --git a/drivers/common/cnxk/roc_nix_mcast.c b/drivers/common/cnxk/roc_nix_mcast.c index 3d74111274..615014e820 100644 --- a/drivers/common/cnxk/roc_nix_mcast.c +++ b/drivers/common/cnxk/roc_nix_mcast.c @@ -107,3 +107,89 @@ roc_nix_mcast_mcam_entry_ena_dis(struct roc_nix *roc_nix, uint32_t index, mbox_put(mbox); return rc; } + +int +roc_nix_mcast_list_setup(struct mbox *mbox, uint8_t intf, int nb_entries, uint16_t *pf_funcs, + uint16_t *channels, uint32_t *rqs, uint32_t *grp_index, + uint32_t *start_index) +{ + struct nix_mcast_grp_create_req *mce_grp_create_req; + struct nix_mcast_grp_create_rsp *mce_grp_create_rsp; + struct nix_mcast_grp_update_req *mce_grp_update_req; + struct nix_mcast_grp_update_rsp *mce_grp_update_rsp; + int rc = 0, i; + + mbox_get(mbox); + + mce_grp_create_req = mbox_alloc_msg_nix_mcast_grp_create(mbox); + if (mce_grp_create_req == NULL) { + rc = -ENOSPC; + goto exit; + } + + mce_grp_create_req->dir = intf; + rc = mbox_process_msg(mbox, (void *)&mce_grp_create_rsp); + if (rc) { + plt_err("Failed to create mirror list"); + goto exit; + } + + *grp_index = mce_grp_create_rsp->mcast_grp_idx; + + mce_grp_update_req = mbox_alloc_msg_nix_mcast_grp_update(mbox); + if (mce_grp_update_req == NULL) { + rc = -ENOSPC; + goto exit; + } + + mce_grp_update_req->mcast_grp_idx = *grp_index; + mce_grp_update_req->op = NIX_MCAST_OP_ADD_ENTRY; + mce_grp_update_req->num_mce_entry = nb_entries; + for (i = 0; i < nb_entries; i++) { + mce_grp_update_req->pcifunc[i] = pf_funcs[i]; + mce_grp_update_req->channel[i] = channels[i]; + mce_grp_update_req->rq_rss_index[i] = rqs[i]; + mce_grp_update_req->dest_type[i] = NIX_RX_RQ; + } + + rc = mbox_process_msg(mbox, (void *)&mce_grp_update_rsp); + if (rc) { + plt_err("Failed to create mirror list"); + goto exit; + } + + *start_index = (mce_grp_update_rsp->mce_start_index & 0xFFFFF); + + rc = 0; +exit: + mbox_put(mbox); + return rc; +} + +int +roc_nix_mcast_list_free(struct mbox *mbox, uint32_t mcast_grp_index) +{ + struct nix_mcast_grp_destroy_req *mce_grp_destroy_req; + struct nix_mcast_grp_destroy_rsp *mce_grp_destroy_rsp; + int rc = 0; + + mbox_get(mbox); + + mce_grp_destroy_req = mbox_alloc_msg_nix_mcast_grp_destroy(mbox); + if (mce_grp_destroy_req == NULL) { + rc = -ENOSPC; + goto exit; + } + + mce_grp_destroy_req->mcast_grp_idx = mcast_grp_index; + rc = mbox_process_msg(mbox, (void *)&mce_grp_destroy_rsp); + if (rc) { + plt_err("Failed to destroy mirror group index"); + goto exit; + } + + rc = 0; +exit: + mbox_put(mbox); + return rc; +} diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c index 1958b3089d..65f99549c9 100644 --- a/drivers/common/cnxk/roc_npc.c +++ b/drivers/common/cnxk/roc_npc.c @@ -497,6 +497,39 @@ npc_parse_spi_to_sa_action(struct roc_npc *roc_npc, const struct roc_npc_action return 0; } +static int +roc_npc_process_sample_action(struct roc_npc *roc_npc, + const struct roc_npc_action_sample *sample_action, + struct roc_npc_flow *flow) +{ + struct nix *nix = roc_nix_to_nix_priv(roc_npc->roc_nix); + struct npc *npc = roc_npc_to_npc_priv(roc_npc); + + flow->is_sampling_rule = true; + + switch (sample_action->action_type) { + case ROC_NPC_ACTION_TYPE_PORT_ID: + flow->mcast_pf_funcs[0] = sample_action->pf_func; + flow->mcast_channels[0] = sample_action->channel; + break; + case ROC_NPC_ACTION_TYPE_PF: + flow->mcast_pf_funcs[0] = roc_npc->pf_func; + flow->mcast_channels[0] = npc->channel; + break; + case ROC_NPC_ACTION_TYPE_VF: + if (sample_action->pf_func >= nix->dev.maxvf) + return -EINVAL; + flow->mcast_pf_funcs[0] = + ((roc_npc->pf_func & 0xfc00) | (sample_action->pf_func + 1)); + flow->mcast_channels[0] = npc->channel; + break; + default: + return -EINVAL; + } + + return 0; +} + static int npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, const struct roc_npc_action actions[], struct roc_npc_flow *flow, @@ -504,6 +537,7 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, { struct npc *npc = roc_npc_to_npc_priv(roc_npc); const struct roc_npc_action *sec_action = NULL; + const struct roc_npc_action_sample *act_sample; const struct roc_npc_action_mark *act_mark; const struct roc_npc_action_meter *act_mtr; const struct roc_npc_action_queue *act_q; @@ -562,8 +596,7 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, break; case ROC_NPC_ACTION_TYPE_VF: - vf_act = - (const struct roc_npc_action_vf *)actions->conf; + vf_act = (const struct roc_npc_action_vf *)actions->conf; req_act |= ROC_NPC_ACTION_TYPE_VF; vf_id = vf_act->id & RVU_PFVF_FUNC_MASK; pf_func &= (0xfc00); @@ -576,9 +609,8 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, break; case ROC_NPC_ACTION_TYPE_QUEUE: - act_q = (const struct roc_npc_action_queue *) - actions->conf; - rq = act_q->index; + act_q = (const struct roc_npc_action_queue *)actions->conf; + rq = act_q->index & 0xFFFFF; req_act |= ROC_NPC_ACTION_TYPE_QUEUE; break; @@ -648,6 +680,13 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; req_act |= ROC_NPC_ACTION_TYPE_AGE; break; + case ROC_NPC_ACTION_TYPE_SAMPLE: + req_act |= ROC_NPC_ACTION_TYPE_SAMPLE; + act_sample = actions->conf; + errcode = roc_npc_process_sample_action(roc_npc, act_sample, flow); + if (errcode) + goto err_exit; + break; default: errcode = NPC_ERR_ACTION_NOTSUP; goto err_exit; @@ -688,6 +727,27 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; } + if (req_act & ROC_NPC_ACTION_TYPE_SAMPLE) { + /* One entry for the mce list PF and channel comes from the sample subaction. + * Another one is the action target of the flow rule getting created. + */ + flow->mcast_pf_funcs[1] = pf_func; + flow->mcast_channels[1] = npc->channel; + if (req_act & (ROC_NPC_ACTION_TYPE_DROP | ROC_NPC_ACTION_TYPE_SEC | + ROC_NPC_ACTION_TYPE_RSS)) { + plt_err("Drop/RSS/SEC not supported with action type sample"); + return -EINVAL; + } + if (flow->mcast_pf_funcs[0] == flow->mcast_pf_funcs[1]) { + plt_err("Sample destination and target cannot be same"); + return -EINVAL; + } + if ((attr->egress) && (flow->mcast_channels[0] == flow->mcast_channels[1])) { + plt_err("Mirroring within PF and VF not allowed"); + return -EINVAL; + } + } + /* Check if actions specified are compatible */ if (attr->egress) { if (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP) { @@ -697,11 +757,10 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, } 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_DROP | ROC_NPC_ACTION_TYPE_COUNT)) { - plt_err("Only VLAN insert, drop, count supported on Egress"); + ~(ROC_NPC_ACTION_TYPE_VLAN_INSERT | ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT | + ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT | ROC_NPC_ACTION_TYPE_DROP | + ROC_NPC_ACTION_TYPE_COUNT | ROC_NPC_ACTION_TYPE_SAMPLE)) { + plt_err("Only VLAN insert, drop, count, sample supported on Egress"); errcode = NPC_ERR_ACTION_NOTSUP; goto err_exit; } @@ -724,6 +783,11 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; } + if (req_act & ROC_NPC_ACTION_TYPE_SAMPLE) { + flow->mcast_pf_funcs[1] = pf_func; + flow->mcast_channels[1] = npc->channel; + } + goto set_pf_func; } else { if (vlan_insert_action) { @@ -771,13 +835,13 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, } else { flow->npc_action = NIX_RX_ACTIONOP_UCAST; if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) - flow->npc_action |= (uint64_t)rq << 20; + flow->recv_queue = rq; } } else if (req_act & ROC_NPC_ACTION_TYPE_DROP) { flow->npc_action = NIX_RX_ACTIONOP_DROP; } else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) { flow->npc_action = NIX_RX_ACTIONOP_UCAST; - flow->npc_action |= (uint64_t)rq << 20; + flow->recv_queue = rq; } else if (req_act & ROC_NPC_ACTION_TYPE_RSS) { flow->npc_action = NIX_RX_ACTIONOP_UCAST; } else if (req_act & ROC_NPC_ACTION_TYPE_SEC) { @@ -797,6 +861,9 @@ npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; } + if (req_act & ROC_NPC_ACTION_TYPE_SAMPLE) + flow->npc_action = NIX_RX_ACTIONOP_MCAST; + if (mark) flow->npc_action |= (uint64_t)mark << 40; @@ -1639,6 +1706,9 @@ roc_npc_flow_destroy(struct roc_npc *roc_npc, struct roc_npc_flow *flow) return rc; } + if (flow->is_sampling_rule) + roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index); + rc = roc_npc_mcam_free(roc_npc, flow); if (rc != 0) return rc; diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h index cb59db2220..e880a7fa67 100644 --- a/drivers/common/cnxk/roc_npc.h +++ b/drivers/common/cnxk/roc_npc.h @@ -196,11 +196,19 @@ enum roc_npc_action_type { ROC_NPC_ACTION_TYPE_PORT_ID = (1 << 16), ROC_NPC_ACTION_TYPE_METER = (1 << 17), ROC_NPC_ACTION_TYPE_AGE = (1 << 18), + ROC_NPC_ACTION_TYPE_SAMPLE = (1 << 19), }; struct roc_npc_action { enum roc_npc_action_type type; /**< Action type. */ - const void *conf; /**< Pointer to action configuration object. */ + const void *conf; /**< Pointer to action configuration object. */ +}; + +struct roc_npc_action_sample { + uint32_t ratio; /**< packets sampled equals to '1/ratio'. */ + uint32_t action_type; /* PF or VF or PORT_ID target. */ + uint16_t pf_func; + uint16_t channel; }; struct roc_npc_action_mark { @@ -294,6 +302,8 @@ struct roc_npc_spi_to_sa_action_info { bool has_action; }; +struct mbox; + struct roc_npc_flow { uint8_t nix_intf; uint8_t enable; @@ -322,6 +332,13 @@ struct roc_npc_flow { void *age_context; uint32_t timeout; bool has_age_action; + bool is_sampling_rule; + uint32_t recv_queue; + uint32_t mcast_grp_index; + uint32_t mce_start_index; +#define ROC_NPC_MIRROR_LIST_SIZE 2 + uint16_t mcast_pf_funcs[ROC_NPC_MIRROR_LIST_SIZE]; + uint16_t mcast_channels[ROC_NPC_MIRROR_LIST_SIZE]; TAILQ_ENTRY(roc_npc_flow) next; }; diff --git a/drivers/common/cnxk/roc_npc_mcam.c b/drivers/common/cnxk/roc_npc_mcam.c index 41edec7d8d..3ef189e184 100644 --- a/drivers/common/cnxk/roc_npc_mcam.c +++ b/drivers/common/cnxk/roc_npc_mcam.c @@ -680,6 +680,40 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_ } } + if (flow->nix_intf == NIX_INTF_TX) { + uint16_t pf_func = (flow->npc_action >> 4) & 0xffff; + + pf_func = plt_cpu_to_be_16(pf_func); + + rc = npc_mcam_set_pf_func(npc, flow, pf_func); + if (rc) + return rc; + } + + if (flow->is_sampling_rule) { + /* Save and restore any mark value set */ + uint16_t mark = (flow->npc_action >> 40) & 0xffff; + uint16_t mce_index = 0; + uint32_t rqs[2] = {}; + + rqs[1] = flow->recv_queue; + rc = roc_nix_mcast_list_setup(npc->mbox, flow->nix_intf, 2, flow->mcast_pf_funcs, + flow->mcast_channels, rqs, &flow->mcast_grp_index, + &flow->mce_start_index); + if (rc) + return rc; + + flow->npc_action = NIX_RX_ACTIONOP_MCAST; + mce_index = flow->mce_start_index; + if (flow->nix_intf == NIX_INTF_TX) { + flow->npc_action |= (uint64_t)mce_index << 12; + flow->npc_action |= (uint64_t)mark << 32; + } else { + flow->npc_action |= (uint64_t)mce_index << 20; + flow->npc_action |= (uint64_t)mark << 40; + } + } + req = mbox_alloc_msg_npc_mcam_write_entry(mbox_get(mbox)); if (req == NULL) { rc = -ENOSPC; @@ -691,6 +725,8 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_ req->intf = (flow->nix_intf == NIX_INTF_RX) ? NPC_MCAM_RX : NPC_MCAM_TX; req->enable_entry = 1; + if (flow->nix_intf == NIX_INTF_RX) + flow->npc_action |= (uint64_t)flow->recv_queue << 20; req->entry_data.action = flow->npc_action; /* @@ -707,16 +743,6 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_ */ req->entry_data.vtag_action = flow->vtag_action; - if (flow->nix_intf == NIX_INTF_TX) { - uint16_t pf_func = (flow->npc_action >> 4) & 0xffff; - - pf_func = plt_cpu_to_be_16(pf_func); - - rc = npc_mcam_set_pf_func(npc, flow, pf_func); - if (rc) - return rc; - } - for (idx = 0; idx < ROC_NPC_MAX_MCAM_WIDTH_DWORDS; idx++) { req->entry_data.kw[idx] = flow->mcam_data[idx]; req->entry_data.kw_mask[idx] = flow->mcam_mask[idx]; @@ -746,7 +772,7 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_ */ if (pst->is_second_pass_rule || (!pst->is_second_pass_rule && pst->has_eth_type)) { la_offset = plt_popcount32(npc->keyx_supp_nmask[flow->nix_intf] & - ((1ULL << 9 /* LA offset */) - 1)); + ((1ULL << 9 /* LA offset */) - 1)); la_offset *= 4; mask = ~((0xfULL << la_offset)); @@ -778,8 +804,11 @@ npc_mcam_alloc_and_write(struct npc *npc, struct roc_npc_flow *flow, struct npc_ if (flow->use_ctr) flow->ctr_id = ctr; rc = 0; + exit: mbox_put(mbox); + if (rc) + roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index); return rc; } @@ -836,7 +865,7 @@ npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst) */ if (pst->npc->keyx_supp_nmask[pst->nix_intf] & (1ULL << NPC_LFLAG_LC_OFFSET)) { lcflag_offset = plt_popcount32(pst->npc->keyx_supp_nmask[pst->nix_intf] & - ((1ULL << NPC_LFLAG_LC_OFFSET) - 1)); + ((1ULL << NPC_LFLAG_LC_OFFSET) - 1)); lcflag_offset *= 4; mask = (0xfULL << lcflag_offset); @@ -1020,6 +1049,9 @@ npc_flow_free_all_resources(struct npc *npc) rc |= npc_mcam_free_counter(npc->mbox, flow->ctr_id); } + if (flow->is_sampling_rule) + roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index); + npc_delete_prio_list_entry(npc, flow); TAILQ_REMOVE(&npc->flow_list[idx], flow, next); diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h index 424f8e207a..c0809407a6 100644 --- a/drivers/common/cnxk/roc_npc_priv.h +++ b/drivers/common/cnxk/roc_npc_priv.h @@ -493,8 +493,7 @@ void npc_age_flow_list_entry_delete(struct roc_npc *npc, struct roc_npc_flow *fl uint32_t npc_aged_flows_get(void *args); int npc_aged_flows_bitmap_alloc(struct roc_npc *roc_npc); void npc_aged_flows_bitmap_free(struct roc_npc *roc_npc); -int npc_aging_ctrl_thread_create(struct roc_npc *roc_npc, - const struct roc_npc_action_age *age, +int npc_aging_ctrl_thread_create(struct roc_npc *roc_npc, const struct roc_npc_action_age *age, struct roc_npc_flow *flow); void npc_aging_ctrl_thread_destroy(struct roc_npc *roc_npc); #endif /* _ROC_NPC_PRIV_H_ */ diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index 52faf676ba..1b531da36d 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -294,6 +294,8 @@ INTERNAL { roc_nix_mac_promisc_mode_enable; roc_nix_mac_rxtx_start_stop; roc_nix_max_pkt_len; + roc_nix_mcast_list_free; + roc_nix_mcast_list_setup; roc_nix_mcast_mcam_entry_alloc; roc_nix_mcast_mcam_entry_ena_dis; roc_nix_mcast_mcam_entry_free; From patchwork Thu Dec 14 10:58:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Satheesh Paul Antonysamy X-Patchwork-Id: 135195 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 695D8436EE; Thu, 14 Dec 2023 11:58:28 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 70BEF43036; Thu, 14 Dec 2023 11:58:27 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 78BDA40697 for ; Thu, 14 Dec 2023 11:58:26 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 3BE9LV7n016648 for ; Thu, 14 Dec 2023 02:58:25 -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=WbqK5bJLqDraZpO1lAB1z1Y4xES1y8WR8UfsTVQ3UPA=; b=iF5 LpVw5y0/uMhb11fNyENnjZVfJQlG3kJkA+2tvcFCQIlnIvaO26jsWrpAmrlk2fnd HE1AtRThizNfUFCdzvAZt/5zqpFHxA5NRVG7wcvZLe7diQ3Bh7vv81atYIJKIS2N EpIfmH7uzlpZqHvCwO/GypqLkGx6uuZr2IrtyWYNlmACcb6qo98hyzpXIA64wTTm eBSL3+Fs3IpXk7PeQYiZaZx1GAFYaOSIwP3lJ4ljnaegHPdVkBKN2gk+co//Wr4n Z4PgEs/nZ97L31oJZT+7tjhuj2xb8natpIpeHS+WAWSak+w8ArD1ovm5M9PahxOe iUXbLSmbLGEXhNao/UQ== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3uyy0nr8yj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 14 Dec 2023 02:58:25 -0800 (PST) Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Thu, 14 Dec 2023 02:58:23 -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.48 via Frontend Transport; Thu, 14 Dec 2023 02:58:23 -0800 Received: from satheeshpaullabpc.. (unknown [10.28.34.33]) by maili.marvell.com (Postfix) with ESMTP id ADD293F7045; Thu, 14 Dec 2023 02:58:21 -0800 (PST) From: To: Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao CC: , Satheesh Paul Subject: [dpdk-dev] [PATCH 2/3] net/cnxk: support mirror flow action Date: Thu, 14 Dec 2023 16:28:12 +0530 Message-ID: <20231214105813.570597-2-psatheesh@marvell.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231214105813.570597-1-psatheesh@marvell.com> References: <20231214105813.570597-1-psatheesh@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: tgh-c6cycCFvVZpwrGsBrP9mhDlXAcyV X-Proofpoint-GUID: tgh-c6cycCFvVZpwrGsBrP9mhDlXAcyV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-09_02,2023-12-07_01,2023-05-22_02 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 Added RTE_FLOW_ACTION_TYPE_SAMPLE action type for cnxk device. Signed-off-by: Satheesh Paul Reviewed-by: Kiran Kumar K --- doc/guides/nics/features/cnxk.ini | 1 + drivers/net/cnxk/cnxk_flow.c | 121 ++++++++++++++++++++++++++++-- 2 files changed, 115 insertions(+), 7 deletions(-) diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini index cc7deaeaa9..94e7a6ab8d 100644 --- a/doc/guides/nics/features/cnxk.ini +++ b/doc/guides/nics/features/cnxk.ini @@ -97,6 +97,7 @@ port_id = Y queue = Y represented_port = Y rss = Y +sample = Y security = Y skip_cman = Y vf = Y diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c index 2eee44ed09..11670d37e0 100644 --- a/drivers/net/cnxk/cnxk_flow.c +++ b/drivers/net/cnxk/cnxk_flow.c @@ -114,14 +114,102 @@ npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev, *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss->types, rss->level); } +static int +npc_parse_port_id_action(struct rte_eth_dev *eth_dev, const struct rte_flow_action *action, + uint16_t *dst_pf_func, uint16_t *dst_channel) +{ + const struct rte_flow_action_port_id *port_act; + struct rte_eth_dev *portid_eth_dev; + char if_name[RTE_ETH_NAME_MAX_LEN]; + struct cnxk_eth_dev *hw_dst; + struct roc_npc *roc_npc_dst; + int rc = 0; + + port_act = (const struct rte_flow_action_port_id *)action->conf; + + rc = rte_eth_dev_get_name_by_port(port_act->id, if_name); + if (rc) { + plt_err("Name not found for output port id"); + goto err_exit; + } + portid_eth_dev = rte_eth_dev_allocated(if_name); + if (!portid_eth_dev) { + plt_err("eth_dev not found for output port id"); + goto err_exit; + } + if (strcmp(portid_eth_dev->device->driver->name, eth_dev->device->driver->name) != 0) { + plt_err("Output port not under same driver"); + goto err_exit; + } + hw_dst = portid_eth_dev->data->dev_private; + roc_npc_dst = &hw_dst->npc; + *dst_pf_func = roc_npc_dst->pf_func; + *dst_channel = hw_dst->npc.channel; + + return 0; + +err_exit: + return -EINVAL; +} + +static int +roc_npc_parse_sample_subaction(struct rte_eth_dev *eth_dev, const struct rte_flow_action actions[], + struct roc_npc_action_sample *sample_action) +{ + uint16_t dst_pf_func = 0, dst_channel = 0; + const struct roc_npc_action_vf *vf_act; + int rc = 0, count = 0; + bool is_empty = true; + + if (sample_action->ratio != 1) { + plt_err("Sample ratio must be 1"); + return -EINVAL; + } + + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + is_empty = false; + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_PF: + count++; + sample_action->action_type |= ROC_NPC_ACTION_TYPE_PF; + break; + case RTE_FLOW_ACTION_TYPE_VF: + count++; + vf_act = (const struct roc_npc_action_vf *)actions->conf; + sample_action->action_type |= ROC_NPC_ACTION_TYPE_VF; + sample_action->pf_func = vf_act->id & NPC_PFVF_FUNC_MASK; + break; + case RTE_FLOW_ACTION_TYPE_PORT_ID: + rc = npc_parse_port_id_action(eth_dev, actions, &dst_pf_func, &dst_channel); + if (rc) + return -EINVAL; + + count++; + sample_action->action_type |= ROC_NPC_ACTION_TYPE_PORT_ID; + sample_action->pf_func = dst_pf_func; + sample_action->channel = dst_channel; + break; + default: + continue; + } + } + + if (count > 1 || is_empty) + return -EINVAL; + + return 0; +} + static int cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, const struct rte_flow_action actions[], struct roc_npc_action in_actions[], - uint32_t *flowkey_cfg, uint16_t *dst_pf_func) + struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg, + uint16_t *dst_pf_func) { struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); const struct rte_flow_action_queue *act_q = NULL; const struct rte_flow_action_ethdev *act_ethdev; + const struct rte_flow_action_sample *act_sample; const struct rte_flow_action_port_id *port_act; struct rte_eth_dev *portid_eth_dev; char if_name[RTE_ETH_NAME_MAX_LEN]; @@ -237,9 +325,21 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, in_actions[i].type = ROC_NPC_ACTION_TYPE_AGE; in_actions[i].conf = actions->conf; break; + case RTE_FLOW_ACTION_TYPE_SAMPLE: + act_sample = actions->conf; + in_sample_actions->ratio = act_sample->ratio; + rc = roc_npc_parse_sample_subaction(eth_dev, act_sample->actions, + in_sample_actions); + if (rc) { + plt_err("Sample subaction parsing failed."); + goto err_exit; + } + + in_actions[i].type = ROC_NPC_ACTION_TYPE_SAMPLE; + in_actions[i].conf = in_sample_actions; + break; default: - plt_npc_dbg("Action is not supported = %d", - actions->type); + plt_npc_dbg("Action is not supported = %d", actions->type); goto err_exit; } i++; @@ -263,7 +363,9 @@ static int cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], struct roc_npc_attr *in_attr, struct roc_npc_item_info in_pattern[], - struct roc_npc_action in_actions[], uint32_t *flowkey_cfg, uint16_t *dst_pf_func) + struct roc_npc_action in_actions[], + struct roc_npc_action_sample *in_sample_actions, uint32_t *flowkey_cfg, + uint16_t *dst_pf_func) { int i = 0; @@ -282,7 +384,8 @@ cnxk_map_flow_data(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr } in_pattern[i].type = ROC_NPC_ITEM_TYPE_END; - return cnxk_map_actions(eth_dev, attr, actions, in_actions, flowkey_cfg, dst_pf_func); + return cnxk_map_actions(eth_dev, attr, actions, in_actions, in_sample_actions, flowkey_cfg, + dst_pf_func); } static int @@ -293,6 +396,7 @@ cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1]; struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT]; struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + struct roc_npc_action_sample in_sample_action; struct roc_npc *npc = &dev->npc; struct roc_npc_attr in_attr; struct roc_npc_flow flow; @@ -306,10 +410,11 @@ cnxk_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr return 0; memset(&flow, 0, sizeof(flow)); + memset(&in_sample_action, 0, sizeof(in_sample_action)); flow.is_validate = true; rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions, - &flowkey_cfg, &dst_pf_func); + &in_sample_action, &flowkey_cfg, &dst_pf_func); if (rc) { rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, "Failed to map flow data"); @@ -335,6 +440,7 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1]; struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT]; + struct roc_npc_action_sample in_sample_action; struct roc_npc *npc = &dev->npc; struct roc_npc_attr in_attr; struct roc_npc_flow *flow; @@ -342,8 +448,9 @@ cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr, int errcode = 0; int rc; + memset(&in_sample_action, 0, sizeof(in_sample_action)); rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr, in_pattern, in_actions, - &npc->flowkey_cfg_state, &dst_pf_func); + &in_sample_action, &npc->flowkey_cfg_state, &dst_pf_func); if (rc) { rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM, NULL, "Failed to map flow data"); From patchwork Thu Dec 14 10:58:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Satheesh Paul Antonysamy X-Patchwork-Id: 135196 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 A7844436EE; Thu, 14 Dec 2023 11:58:36 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0DC7C43250; Thu, 14 Dec 2023 11:58:33 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id A304640697 for ; Thu, 14 Dec 2023 11:58:30 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 3BE9LPYt002192 for ; Thu, 14 Dec 2023 02:58:29 -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=zPkXK4RtopGIhgtZzEZBLItU9m5tJO5t18MtIvsZtAw=; b=ErB Wval92j6cZysNggeePfxn7KbWMHI0RY+PBKEEdQ5+dP5h1j+6Juwl1L8pSv04O8w KTPBVY8i5H78cW8rXgsRiKdNbhl1rqRzeZSBdPweynaSzd8G4/FB5TNUrSfyoTIF WLqP9Q8x46ju2Il6ycYEheM9zMtCESFXRpYr3HL28FlZlExL4xNgqhQDqIxDCUML WhjisUyXKVaQWvX3VJPjTATkb1XEBvJ/7x95qrhImwvOYCMnseWQhvJf+rNiewub 42LCPsona2TWSk4P9hs8xRCjJsx59eSk+Q3sEIB2IvEuqGPec/xCP5FoEYQXhCO4 5StKajsn5T2rV99opsg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3uyy0m89bf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 14 Dec 2023 02:58:29 -0800 (PST) Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Thu, 14 Dec 2023 02:58:28 -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.48 via Frontend Transport; Thu, 14 Dec 2023 02:58:28 -0800 Received: from satheeshpaullabpc.. (unknown [10.28.34.33]) by maili.marvell.com (Postfix) with ESMTP id 1628A3F7045; Thu, 14 Dec 2023 02:58:25 -0800 (PST) From: To: Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao CC: , Satheesh Paul Subject: [dpdk-dev] [PATCH 3/3] common/cnxk: add egress mirror support Date: Thu, 14 Dec 2023 16:28:13 +0530 Message-ID: <20231214105813.570597-3-psatheesh@marvell.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231214105813.570597-1-psatheesh@marvell.com> References: <20231214105813.570597-1-psatheesh@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: P6lZkFEskb9HMKIinzm0XHR_qe41x7Id X-Proofpoint-ORIG-GUID: P6lZkFEskb9HMKIinzm0XHR_qe41x7Id X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-09_02,2023-12-07_01,2023-05-22_02 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: Satha Rao Added ROC api to send packets on multiple links when egress mirror enabled. Signed-off-by: Satha Rao Reviewed-by: Nithin Dabilpuram Reviewed-by: Kiran Kumar K Reviewed-by: Satheesh Paul --- drivers/common/cnxk/roc_nix.h | 2 + drivers/common/cnxk/roc_nix_tm_ops.c | 70 ++++++++++++++++++++++++++++ drivers/common/cnxk/roc_npc.c | 26 +++++++++++ drivers/common/cnxk/version.map | 1 + 4 files changed, 99 insertions(+) diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index c1ebf971f7..84e6fc3df5 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -755,6 +755,8 @@ int __roc_api roc_nix_tm_mark_config(struct roc_nix *roc_nix, int mark_red); uint64_t __roc_api roc_nix_tm_mark_format_get(struct roc_nix *roc_nix, uint64_t *flags); +int __roc_api roc_nix_tm_egress_link_cfg_set(struct roc_nix *roc_nix, uint64_t dst_pf_func, + bool enable); /* Ingress Policer API */ int __roc_api roc_nix_bpf_timeunit_get(struct roc_nix *roc_nix, diff --git a/drivers/common/cnxk/roc_nix_tm_ops.c b/drivers/common/cnxk/roc_nix_tm_ops.c index 2c53472047..900b182c76 100644 --- a/drivers/common/cnxk/roc_nix_tm_ops.c +++ b/drivers/common/cnxk/roc_nix_tm_ops.c @@ -1316,3 +1316,73 @@ roc_nix_tm_root_has_sp(struct roc_nix *roc_nix) return false; return true; } + +static inline struct nix * +pf_func_to_nix_get(uint16_t pf_func) +{ + struct roc_nix *roc_nix_tmp = NULL; + struct roc_nix_list *nix_list; + + nix_list = roc_idev_nix_list_get(); + if (nix_list == NULL) + return NULL; + + /* Find the NIX of given pf_func */ + TAILQ_FOREACH(roc_nix_tmp, nix_list, next) { + struct nix *nix = roc_nix_to_nix_priv(roc_nix_tmp); + + if (nix->dev.pf_func == pf_func) + return nix; + } + + return NULL; +} + +int +roc_nix_tm_egress_link_cfg_set(struct roc_nix *roc_nix, uint64_t dst_pf_func, bool enable) +{ + struct nix *src_nix = roc_nix_to_nix_priv(roc_nix), *dst_nix; + struct mbox *mbox = (&src_nix->dev)->mbox; + struct nix_txschq_config *req = NULL; + struct nix_tm_node_list *list; + struct nix_tm_node *node; + int rc = 0, k; + + dst_nix = pf_func_to_nix_get(dst_pf_func); + if (!dst_nix) + return -EINVAL; + + if (dst_nix == src_nix) + return 0; + + list = nix_tm_node_list(src_nix, src_nix->tm_tree); + TAILQ_FOREACH(node, list, node) { + if (node->hw_lvl != src_nix->tm_link_cfg_lvl) + continue; + + if (!(node->flags & NIX_TM_NODE_HWRES)) + continue; + + /* Allocating TL3 request */ + req = mbox_alloc_msg_nix_txschq_cfg(mbox_get(mbox)); + req->lvl = src_nix->tm_link_cfg_lvl; + k = 0; + + /* Enable PFC/pause on the identified TL3 */ + req->reg[k] = NIX_AF_TL3_TL2X_LINKX_CFG(node->hw_id, dst_nix->tx_link); + if (enable) + req->regval[k] |= BIT_ULL(12); + else + req->regval[k] &= ~(BIT_ULL(12)); + req->regval_mask[k] = ~(BIT_ULL(12)); + k++; + + req->num_regs = k; + rc = mbox_process(mbox); + mbox_put(mbox); + if (rc) + goto err; + } +err: + return rc; +} diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c index 65f99549c9..9a0fe5f4e2 100644 --- a/drivers/common/cnxk/roc_npc.c +++ b/drivers/common/cnxk/roc_npc.c @@ -1595,6 +1595,21 @@ roc_npc_flow_create(struct roc_npc *roc_npc, const struct roc_npc_attr *attr, goto err_exit; } + /* If Egress mirror requested then enable TL3_TL2_LINK_CFG */ + if (flow->is_sampling_rule && (flow->nix_intf == NIX_INTF_TX)) { + if (flow->mcast_pf_funcs[0] == npc->pf_func) + rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, + flow->mcast_pf_funcs[1], true); + else + rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, + flow->mcast_pf_funcs[0], true); + if (rc) { + plt_err("Adding egress mirror failed"); + *errcode = rc; + goto err_exit; + } + } + rc = npc_rss_action_program(roc_npc, actions, flow); if (rc != 0) { *errcode = rc; @@ -1706,6 +1721,17 @@ roc_npc_flow_destroy(struct roc_npc *roc_npc, struct roc_npc_flow *flow) return rc; } + /* Disable egress mirror rule */ + if (flow->is_sampling_rule && (flow->nix_intf == NIX_INTF_TX)) { + if (flow->mcast_pf_funcs[0] == npc->pf_func) + rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, + flow->mcast_pf_funcs[1], false); + else + rc = roc_nix_tm_egress_link_cfg_set(roc_npc->roc_nix, + flow->mcast_pf_funcs[0], false); + if (rc) + plt_err("Failed to remove egress mirror rule"); + } if (flow->is_sampling_rule) roc_nix_mcast_list_free(npc->mbox, flow->mcast_grp_index); diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index 1b531da36d..7b6afa63a9 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -355,6 +355,7 @@ INTERNAL { roc_nix_switch_hdr_set; roc_nix_eeprom_info_get; roc_nix_smq_flush; + roc_nix_tm_egress_link_cfg_set; roc_nix_tm_dump; roc_nix_tm_err_to_rte_err; roc_nix_tm_fini;