From patchwork Thu Dec 14 14:50:14 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: 135203 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 EC82E436F0; Thu, 14 Dec 2023 15:50:25 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D74D443291; Thu, 14 Dec 2023 15:50:25 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 7E3A24327C for ; Thu, 14 Dec 2023 15:50:24 +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 3BE9LUmU002210 for ; Thu, 14 Dec 2023 06:50:23 -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=k08FvY87DH/qER/t0GSB+mUzsqe/HvBhm9989SDhJLM=; b=Jbo DPzO9HtG/kIh9B/eCdZrstZOU168QuBhcWjWYvx8iwPPykNxZvbn87pMRatwuoV3 r5JZ10UzDGofDEh9yXtPGv2i6IvUhA/LHSftQy5lyZjP+8u4vIG1uv++YdoEAbXg /Db2e5kA5q55gzV1wLLtFFJNcNcjPj8fQtQEXGwrM2yQuJLchY0rCNgqzulLQn+7 ADIHOhPjFHaF7K2fl7HZ3ChATAEk63/ti9ajNApWZCbiV/Swo780agYq17jViiTn 55B2p6CiJOEzwOkpPsaemeZBWQQL5f4LXsqMMPjYTX57i4pAs9amsKPjvs7iKRoZ WP6OainS/mayRYnG5fg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3uyy0m9206-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 14 Dec 2023 06:50:23 -0800 (PST) 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.48; Thu, 14 Dec 2023 06:50:21 -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 06:50:21 -0800 Received: from satheeshpaullabpc.. (unknown [10.28.34.33]) by maili.marvell.com (Postfix) with ESMTP id 163393F7097; Thu, 14 Dec 2023 06:50:18 -0800 (PST) From: To: Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao CC: , Satheesh Paul Subject: [dpdk-dev] [PATCH v2 1/3] common/cnxk: support mirror flow action Date: Thu, 14 Dec 2023 20:20:14 +0530 Message-ID: <20231214145016.571806-1-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: 3f-ViACUznbu1x8vbvFgagBeymC8SYKl X-Proofpoint-ORIG-GUID: 3f-ViACUznbu1x8vbvFgagBeymC8SYKl 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 --- v2: * Updated release notes. Depends-on: series-30556 ("common/cnxk: support PPPoE flow item type in ROC API") 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;