From nobody Thu Apr 2 12:35:29 2026 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FAEE2BDC0C; Tue, 24 Feb 2026 08:01:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771920087; cv=none; b=bCjsvTLGbQ/CSEoFluNYk5f19ndHnIxuMLd5xpUTB0SK3oT5pTDmMGkQ6vKZXYUA2wEFGN8tD5wM+UpzoNDm5GBT+UuqIVoW/dGOFIhQg4sFXas7y5Nzxu0xFh6USSbjXKbeQ+B22izSHKFPg7eYQERyb/DS86qpmY9Ft9/UbpY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771920087; c=relaxed/simple; bh=CaG4Cw3J8CkC7pK1ATAZZ+fd95jzcxh8imG2z7Luj5w=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lcZfjKOBCaRvv8zdSJSefXqCMqU6ccT2yJLKOhkSHfw7IoZnV5YxYwAes1gSd5bC/K2KzdgynoAj25ULCn59MTisHqNaHXfQA1cNTdO2wXIY3R6xUOqk3nmY/tDp0Jsq9G5WPkPTuKpdSNThtTaUFN8pF5pz0ptmVogkoEqJZqM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=GULpSBB1; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="GULpSBB1" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 61NHSmOe3895504; Tue, 24 Feb 2026 00:01:13 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=v JKsIv4ztzBb8lMa+2BPAg6Ay6lQoQxwd/FBHekVrEE=; b=GULpSBB19ZkB54YtM O8sfMLZoY+wEww1Our57CP3NtfXOnuTI6TLX8FR4d9laFAIkvF5RU73hA4Bwa2AE 7P3Dfk77OptTyWewheZLjJc/jJ3IYUqBa3m9XQ7oJ3fdb76Kk6F8TKiDtYC8nBJc Z7TXSblVAW3eh+PMv4lsEIIzpXilcNaWg2g1eWNA6Q+muRInkv3PAuFAYgw8x8Li r0usLGLONwnewZyzAzSw6xpljnNrIRXM2jdYAECtdTa6rvrD/zAAL1CuAEF6ZcL/ yAJR+Pad8fbMxKaL/hONcFVHAU0aBwwYvm/R26JDSv9IbyNZw3kppNmObtEkxqj3 wGWFw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4cfaxp5gw3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 24 Feb 2026 00:01:09 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Tue, 24 Feb 2026 00:01:07 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Tue, 24 Feb 2026 00:01:07 -0800 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 6CB3A3F708C; Tue, 24 Feb 2026 00:00:56 -0800 (PST) From: Ratheesh Kannoth To: , CC: , , , , , , "Ratheesh Kannoth" Subject: [PATCH net-next v9 05/13] octeontx2-af: npc: cn20k: Allocate default MCAM indexes Date: Tue, 24 Feb 2026 13:30:01 +0530 Message-ID: <20260224080009.4147301-6-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260224080009.4147301-1-rkannoth@marvell.com> References: <20260224080009.4147301-1-rkannoth@marvell.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: t8g-UKpCWNuEITxs14gBX1eP4Q1ZtAoe X-Authority-Analysis: v=2.4 cv=IsQTsb/g c=1 sm=1 tr=0 ts=699d5ac5 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=HzLeVaNsDn8A:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=M5GUcnROAAAA:8 a=s374GtA9f-YmEK9EDmoA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMjI0MDA2OCBTYWx0ZWRfX0gDglc5i39uN kC4aQIVq6rKPleECmCla/boIdnc+fROqNOtVkWXOX0ew1hXWCug3YPlT+YhuWNbj3JQJ2NgCDR9 WNkkygpPqggiigJlZYnQTUnZzcU5lgc1sEXAtvgqTLUwqX88wyvtLBJw9eyV+1PCBdThFB5Hu06 FNrgPyXh4WX2wb1GyGPsNTdDnZGT+4aKnBvrU4DSLqu2sawCpgZBtX6jxr/DZa3Jn1EL8H1kQyw fdXLhq2zQaQLFATBcTfJrY4BtZMaz9i2GeP/tcqDlwdBjgOI6eXUwaTUkV3MtH7sDwpDlbcfUhZ oL5+HkLERTSuy8sy5a3DVGgonyJBptJPDDv0CaIQSY+Ll7jDBx7lYpRVft+MYfTT/9rKCIuTcky hn/pKxrYAmCBdGT/4tstT8dqmrxpFJ3HaUg9RRXysl+D8c1ELAh9I64s1MBH8dSMM0FSJt7cIZv ChPtCV7PQvYQfvDdoEQ== X-Proofpoint-ORIG-GUID: t8g-UKpCWNuEITxs14gBX1eP4Q1ZtAoe X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-02-24_01,2026-02-23_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Reserving MCAM entries in the AF driver for installing default MCAM entries is not an efficient allocation method, as it results in significant wastage of entries. This patch allocates MCAM indexes for promiscuous, multicast, broadcast, and unicast traffic in descending order of indexes (from lower to higher priority) when the NIX LF is attached to the PF/VF. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 361 ++++++++++++++++++ .../ethernet/marvell/octeontx2/af/cn20k/npc.h | 29 ++ .../net/ethernet/marvell/octeontx2/af/mbox.h | 8 +- .../net/ethernet/marvell/octeontx2/af/rvu.c | 32 +- .../net/ethernet/marvell/octeontx2/af/rvu.h | 1 + .../ethernet/marvell/octeontx2/af/rvu_npc.c | 36 +- .../marvell/octeontx2/nic/otx2_flows.c | 2 +- 7 files changed, 447 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.c index 41164b65085f..a15d408b0fa9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -25,10 +25,28 @@ static const char *npc_kw_name[NPC_MCAM_KEY_MAX] =3D { [NPC_MCAM_KEY_X4] =3D "X4", }; =20 +static const char *npc_dft_rule_name[NPC_DFT_RULE_MAX_ID] =3D { + [NPC_DFT_RULE_PROMISC_ID] =3D "Promisc", + [NPC_DFT_RULE_MCAST_ID] =3D "Mcast", + [NPC_DFT_RULE_BCAST_ID] =3D "Bcast", + [NPC_DFT_RULE_UCAST_ID] =3D "Ucast", +}; + #define KEX_EXTR_CFG(bytesm1, hdr_ofs, ena, key_ofs) \ (((bytesm1) << 16) | ((hdr_ofs) << 8) | ((ena) << 7) | \ ((key_ofs) & 0x3F)) =20 +#define NPC_DFT_RULE_ID_MK(pcifunc, id) \ + ((pcifunc) | FIELD_PREP(GENMASK_ULL(31, 16), id)) + +#define NPC_DFT_RULE_ID_2_PCIFUNC(rid) \ + FIELD_GET(GENMASK_ULL(15, 0), rid) + +#define NPC_DFT_RULE_ID_2_ID(rid) \ + FIELD_GET(GENMASK_ULL(31, 16), rid) + +#define NPC_DFT_RULE_PRIO 127 + static const char cn20k_def_pfl_name[] =3D "default"; =20 static struct npc_mcam_kex_extr npc_mkex_extr_default =3D { @@ -2380,6 +2398,346 @@ static int npc_pcifunc_map_create(struct rvu *rvu) return cnt; } =20 +int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast, + u16 *mcast, u16 *promisc, u16 *ucast) +{ + u16 *ptr[4] =3D {promisc, mcast, bcast, ucast}; + unsigned long idx; + bool set =3D false; + void *val; + int i, j; + + if (!npc_priv.init_done) + return 0; + + if (is_lbk_vf(rvu, pcifunc)) { + if (!ptr[0]) + return -EINVAL; + + idx =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_PROMISC_ID); + val =3D xa_load(&npc_priv.xa_pf2dfl_rmap, idx); + if (!val) { + pr_debug("%s: Failed to find %s index for pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[NPC_DFT_RULE_PROMISC_ID], + pcifunc); + + *ptr[0] =3D USHRT_MAX; + return -ESRCH; + } + + *ptr[0] =3D xa_to_value(val); + return 0; + } + + if (is_vf(pcifunc)) { + if (!ptr[3]) + return -EINVAL; + + idx =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_UCAST_ID); + val =3D xa_load(&npc_priv.xa_pf2dfl_rmap, idx); + if (!val) { + pr_debug("%s: Failed to find %s index for pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[NPC_DFT_RULE_UCAST_ID], + pcifunc); + + *ptr[3] =3D USHRT_MAX; + return -ESRCH; + } + + *ptr[3] =3D xa_to_value(val); + return 0; + } + + for (i =3D NPC_DFT_RULE_START_ID, j =3D 0; i < NPC_DFT_RULE_MAX_ID; i++, + j++) { + if (!ptr[j]) + continue; + + idx =3D NPC_DFT_RULE_ID_MK(pcifunc, i); + val =3D xa_load(&npc_priv.xa_pf2dfl_rmap, idx); + if (!val) { + pr_debug("%s: Failed to find %s index for pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[i], pcifunc); + + *ptr[j] =3D USHRT_MAX; + continue; + } + + *ptr[j] =3D xa_to_value(val); + set =3D true; + } + + return set ? 0 : -ESRCH; +} + +static bool npc_is_cgx_or_lbk(struct rvu *rvu, u16 pcifunc) +{ + return is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)) || + is_lbk_vf(rvu, pcifunc); +} + +void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc) +{ + struct npc_mcam_free_entry_req free_req =3D { 0 }; + unsigned long index; + struct msg_rsp rsp; + u16 ptr[4]; + int rc, i; + void *map; + + if (!npc_priv.init_done) + return; + + if (!npc_is_cgx_or_lbk(rvu, pcifunc)) { + dev_dbg(rvu->dev, + "%s: dft rule allocation is only for cgx mapped device, pcifunc=3D%#x\n= ", + __func__, pcifunc); + return; + } + + rc =3D npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &ptr[0], &ptr[1], + &ptr[2], &ptr[3]); + if (rc) + return; + + /* LBK */ + if (is_lbk_vf(rvu, pcifunc)) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_PROMISC_ID); + map =3D xa_erase(&npc_priv.xa_pf2dfl_rmap, index); + if (!map) + dev_dbg(rvu->dev, + "%s: Err from delete %s mcam idx from xarray (pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[NPC_DFT_RULE_PROMISC_ID], + pcifunc); + + goto free_rules; + } + + /* VF */ + if (is_vf(pcifunc)) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_UCAST_ID); + map =3D xa_erase(&npc_priv.xa_pf2dfl_rmap, index); + if (!map) + dev_dbg(rvu->dev, + "%s: Err from delete %s mcam idx from xarray (pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[NPC_DFT_RULE_UCAST_ID], + pcifunc); + + goto free_rules; + } + + /* PF */ + for (i =3D NPC_DFT_RULE_START_ID; i < NPC_DFT_RULE_MAX_ID; i++) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, i); + map =3D xa_erase(&npc_priv.xa_pf2dfl_rmap, index); + if (!map) + dev_dbg(rvu->dev, + "%s: Err from delete %s mcam idx from xarray (pcifunc=3D%#x\n", + __func__, npc_dft_rule_name[i], + pcifunc); + } + +free_rules: + + free_req.hdr.pcifunc =3D pcifunc; + free_req.all =3D 1; + rc =3D rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp); + if (rc) + dev_err(rvu->dev, + "%s: Error deleting default entries (pcifunc=3D%#x\n", + __func__, pcifunc); +} + +int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc) +{ + struct npc_mcam_free_entry_req free_req =3D { 0 }; + u16 mcam_idx[4] =3D { 0 }, pf_ucast, pf_pcifunc; + struct npc_mcam_alloc_entry_req req =3D { 0 }; + struct npc_mcam_alloc_entry_rsp rsp =3D { 0 }; + int ret, eidx, i, k, pf, cnt; + struct rvu_pfvf *pfvf; + unsigned long index; + struct msg_rsp free_rsp; + u16 b, m, p, u; + + if (!npc_priv.init_done) + return 0; + + if (!npc_is_cgx_or_lbk(rvu, pcifunc)) { + dev_dbg(rvu->dev, + "%s: dft rule allocation is only for cgx mapped device, pcifunc=3D%#x\n= ", + __func__, pcifunc); + return 0; + } + + /* Check if default rules are already alloced for this pcifunc */ + ret =3D npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &b, &m, &p, &u); + if (!ret) { + dev_dbg(rvu->dev, + "%s: default rules are already installed (pcifunc=3D%#x)\n", + __func__, pcifunc); + dev_dbg(rvu->dev, + "%s: bcast(%u) mcast(%u) promisc(%u) ucast(%u)\n", + __func__, b, m, p, u); + return 0; + } + + /* Set ref index as lowest priority index */ + eidx =3D 2 * npc_priv.bank_depth - 1; + + /* Install only UCAST for VF */ + cnt =3D is_vf(pcifunc) ? 1 : ARRAY_SIZE(mcam_idx); + + /* For VF pcifunc, allocate default mcam indexes by taking + * ref as PF's ucast index. + */ + if (is_vf(pcifunc)) { + pf =3D rvu_get_pf(rvu->pdev, pcifunc); + pf_pcifunc =3D pf << RVU_CN20K_PFVF_PF_SHIFT; + + /* Get PF's ucast entry index */ + ret =3D npc_cn20k_dft_rules_idx_get(rvu, pf_pcifunc, NULL, + NULL, NULL, &pf_ucast); + + /* There is no PF rules installed; and VF installation comes + * first. PF may come later. + * TODO: Install PF rules before installing VF rules. + */ + + /* Set PF's ucast as ref entry */ + if (!ret) + eidx =3D pf_ucast; + } + + pfvf =3D rvu_get_pfvf(rvu, pcifunc); + pfvf->hw_prio =3D NPC_DFT_RULE_PRIO; + + req.contig =3D false; + req.ref_prio =3D NPC_MCAM_HIGHER_PRIO; + req.ref_entry =3D eidx; + req.kw_type =3D NPC_MCAM_KEY_X2; + req.count =3D cnt; + req.hdr.pcifunc =3D pcifunc; + + ret =3D rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &req, &rsp); + + /* successfully allocated index */ + if (!ret) { + /* Copy indexes to local array */ + for (i =3D 0; i < cnt; i++) + mcam_idx[i] =3D rsp.entry_list[i]; + + goto chk_sanity; + } + + /* If there is no slots available and request is for PF, + * return error. + */ + if (!is_vf(pcifunc)) { + dev_err(rvu->dev, + "%s: Default index allocation failed for pcifunc=3D%#x\n", + __func__, pcifunc); + return ret; + } + + /* We could not find an index with higher priority index for VF. + * Find rule with lower priority index and set hardware priority + * as NPC_DFT_RULE_PRIO - 1 (higher hw priority) + */ + req.contig =3D false; + req.kw_type =3D NPC_MCAM_KEY_X2; + req.count =3D cnt; + req.hdr.pcifunc =3D pcifunc; + req.ref_prio =3D NPC_MCAM_LOWER_PRIO; + req.ref_entry =3D eidx + 1; + ret =3D rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &req, &rsp); + if (ret) { + dev_err(rvu->dev, + "%s: Default index allocation failed for pcifunc=3D%#x\n", + __func__, pcifunc); + return ret; + } + + /* Copy indexes to local array */ + for (i =3D 0; i < cnt; i++) + mcam_idx[i] =3D rsp.entry_list[i]; + + pfvf->hw_prio =3D NPC_DFT_RULE_PRIO - 1; + +chk_sanity: + /* LBK */ + if (is_lbk_vf(rvu, pcifunc)) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_PROMISC_ID); + ret =3D xa_insert(&npc_priv.xa_pf2dfl_rmap, index, + xa_mk_value(mcam_idx[0]), GFP_KERNEL); + if (ret) { + dev_err(rvu->dev, + "%s: Err to insert %s mcam idx to xarray pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[NPC_DFT_RULE_PROMISC_ID], + pcifunc); + goto err; + } + + goto done; + } + + /* VF */ + if (is_vf(pcifunc)) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_UCAST_ID); + ret =3D xa_insert(&npc_priv.xa_pf2dfl_rmap, index, + xa_mk_value(mcam_idx[0]), GFP_KERNEL); + if (ret) { + dev_err(rvu->dev, + "%s: Err to insert %s mcam idx to xarray pcifunc=3D%#x\n", + __func__, + npc_dft_rule_name[NPC_DFT_RULE_UCAST_ID], + pcifunc); + goto err; + } + + goto done; + } + + /* PF */ + for (i =3D NPC_DFT_RULE_START_ID, k =3D 0; i < NPC_DFT_RULE_MAX_ID && + k < cnt; i++, k++) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, i); + ret =3D xa_insert(&npc_priv.xa_pf2dfl_rmap, index, + xa_mk_value(mcam_idx[k]), GFP_KERNEL); + if (ret) { + dev_err(rvu->dev, + "%s: Err to insert %s mcam idx to xarray pcifunc=3D%#x\n", + __func__, npc_dft_rule_name[i], + pcifunc); + for (int p =3D NPC_DFT_RULE_START_ID; p < i; p++) { + index =3D NPC_DFT_RULE_ID_MK(pcifunc, p); + xa_erase(&npc_priv.xa_pf2dfl_rmap, index); + } + goto err; + } + } + +done: + return 0; + +err: + free_req.hdr.pcifunc =3D pcifunc; + free_req.all =3D 1; + ret =3D rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &free_rsp); + if (ret) + dev_err(rvu->dev, + "%s: Error deleting default entries (pcifunc=3D%#x\n", + __func__, pcifunc); + + return -EFAULT; +} + static int npc_priv_init(struct rvu *rvu) { struct npc_mcam *mcam =3D &rvu->hw->mcam; @@ -2442,6 +2800,7 @@ static int npc_priv_init(struct rvu *rvu) xa_init_flags(&npc_priv.xa_sb_free, XA_FLAGS_ALLOC); xa_init_flags(&npc_priv.xa_idx2pf_map, XA_FLAGS_ALLOC); xa_init_flags(&npc_priv.xa_pf_map, XA_FLAGS_ALLOC); + xa_init_flags(&npc_priv.xa_pf2dfl_rmap, XA_FLAGS_ALLOC); =20 if (npc_create_srch_order(num_subbanks)) goto fail1; @@ -2474,6 +2833,7 @@ static int npc_priv_init(struct rvu *rvu) xa_destroy(&npc_priv.xa_sb_free); xa_destroy(&npc_priv.xa_idx2pf_map); xa_destroy(&npc_priv.xa_pf_map); + xa_destroy(&npc_priv.xa_pf2dfl_rmap); kfree(npc_priv.sb); npc_priv.sb =3D NULL; return -ENOMEM; @@ -2487,6 +2847,7 @@ void npc_cn20k_deinit(struct rvu *rvu) xa_destroy(&npc_priv.xa_sb_free); xa_destroy(&npc_priv.xa_idx2pf_map); xa_destroy(&npc_priv.xa_pf_map); + xa_destroy(&npc_priv.xa_pf2dfl_rmap); =20 for (i =3D 0; i < npc_priv.pf_cnt; i++) xa_destroy(&npc_priv.xa_pf2idx_map[i]); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.h index 2ed59b3955f4..c4a20f1a5f12 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h @@ -95,6 +95,27 @@ enum npc_subbank_flag { NPC_SUBBANK_FLAG_USED =3D BIT(1), }; =20 +/** + * enum npc_dft_rule_id - Default rule type + * + * Mcam default rule type. + * + * @NPC_DFT_RULE_START_ID: Not used + * @NPC_DFT_RULE_PROMISC_ID: promiscuous rule + * @NPC_DFT_RULE_MCAST_ID: multicast rule + * @NPC_DFT_RULE_BCAST_ID: broadcast rule + * @NPC_DFT_RULE_UCAST_ID: unicast rule + * @NPC_DFT_RULE_MAX_ID: Maximum index. + */ +enum npc_dft_rule_id { + NPC_DFT_RULE_START_ID =3D 1, + NPC_DFT_RULE_PROMISC_ID =3D NPC_DFT_RULE_START_ID, + NPC_DFT_RULE_MCAST_ID, + NPC_DFT_RULE_BCAST_ID, + NPC_DFT_RULE_UCAST_ID, + NPC_DFT_RULE_MAX_ID, +}; + /** * struct npc_subbank - Subbank fields. * @b0b: Subbanks bottom index for bank0 @@ -141,6 +162,7 @@ struct npc_subbank { * @xa_pf_map: Pcifunc to index map. * @pf_cnt: Number of PFs. * @init_done: Indicates MCAM initialization is done. + * @xa_pf2dfl_rmap: PF to default rule index map. * * This structure is populated during probing time by reading * HW csr registers. @@ -157,6 +179,7 @@ struct npc_priv_t { struct xarray *xa_pf2idx_map; struct xarray xa_idx2pf_map; struct xarray xa_pf_map; + struct xarray xa_pf2dfl_rmap; int pf_cnt; bool init_done; }; @@ -265,4 +288,10 @@ int npc_cn20k_apply_custom_kpu(struct rvu *rvu, void npc_cn20k_update_action_entries_n_flags(struct rvu *rvu, struct npc_kpu_profile_adapter *pfl); + +int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc); +void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc); + +int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast, + u16 *mcast, u16 *promisc, u16 *ucast); #endif /* NPC_CN20K_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.h index a393bf884fd6..1b7f1103f78f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1539,9 +1539,10 @@ struct npc_mcam_alloc_entry_req { #define NPC_MCAM_ANY_PRIO 0 #define NPC_MCAM_LOWER_PRIO 1 #define NPC_MCAM_HIGHER_PRIO 2 - u8 priority; /* Lower or higher w.r.t ref_entry */ + u8 ref_prio; /* Lower or higher w.r.t ref_entry */ u16 ref_entry; u16 count; /* Number of entries requested */ + u8 kw_type; /* entry key type, valid for cn20k */ }; =20 struct npc_mcam_alloc_entry_rsp { @@ -1634,10 +1635,12 @@ struct npc_mcam_alloc_and_write_entry_req { struct mbox_msghdr hdr; struct mcam_entry entry_data; u16 ref_entry; - u8 priority; /* Lower or higher w.r.t ref_entry */ + u8 ref_prio; /* Lower or higher w.r.t ref_entry */ u8 intf; /* Rx or Tx interface */ u8 enable_entry;/* Enable this MCAM entry ? */ u8 alloc_cntr; /* Allocate counter and map ? */ + /* hardware priority, supported for cn20k */ + u8 hw_prio; }; =20 struct npc_mcam_alloc_and_write_entry_rsp { @@ -1790,6 +1793,7 @@ struct npc_install_flow_req { u8 vtag1_op; /* old counter value */ u16 cntr_val; + u8 hw_prio; }; =20 struct npc_install_flow_rsp { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.c index 8530df8b3fda..0b94dfd68500 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -22,6 +22,7 @@ #include "rvu_npc_hash.h" #include "cn20k/reg.h" #include "cn20k/api.h" +#include "cn20k/npc.h" =20 #define DRV_NAME "rvu_af" #define DRV_STRING "Marvell OcteonTX2 RVU Admin Function Driver" @@ -1467,6 +1468,13 @@ static int rvu_detach_rsrcs(struct rvu *rvu, struct = rsrc_detach *detach, else if ((blkid =3D=3D BLKADDR_CPT1) && !detach->cptlfs) continue; } + + if (detach_all || + (detach && (blkid =3D=3D BLKADDR_NIX0 || + blkid =3D=3D BLKADDR_NIX1) && + detach->nixlf)) + npc_cn20k_dft_rules_free(rvu, pcifunc); + rvu_detach_block(rvu, pcifunc, block->type); } =20 @@ -1750,6 +1758,12 @@ int rvu_mbox_handler_attach_resources(struct rvu *rv= u, err =3D rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach); if (err) goto fail2; + + if (is_cn20k(rvu->pdev)) { + err =3D npc_cn20k_dft_rules_alloc(rvu, pcifunc); + if (err) + goto fail3; + } } =20 if (attach->sso) { @@ -1763,7 +1777,7 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, err =3D rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO, attach->sso, attach); if (err) - goto fail3; + goto fail4; } =20 if (attach->ssow) { @@ -1772,7 +1786,7 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, err =3D rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW, attach->ssow, attach); if (err) - goto fail4; + goto fail5; } =20 if (attach->timlfs) { @@ -1781,7 +1795,7 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, err =3D rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM, attach->timlfs, attach); if (err) - goto fail5; + goto fail6; } =20 if (attach->cptlfs) { @@ -1791,24 +1805,28 @@ int rvu_mbox_handler_attach_resources(struct rvu *r= vu, err =3D rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT, attach->cptlfs, attach); if (err) - goto fail6; + goto fail7; } =20 mutex_unlock(&rvu->rsrc_lock); return 0; =20 -fail6: +fail7: if (attach->timlfs) rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM); =20 -fail5: +fail6: if (attach->ssow) rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW); =20 -fail4: +fail5: if (attach->sso) rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO); =20 +fail4: + if (is_cn20k(rvu->pdev)) + npc_cn20k_dft_rules_free(rvu, pcifunc); + fail3: if (attach->nixlf) rvu_detach_block(rvu, pcifunc, BLKTYPE_NIX); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.h index dd930aa05582..d2a0f6821cf9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -308,6 +308,7 @@ struct rvu_pfvf { u64 lmt_map_ent_w1; /* Preseving the word1 of lmtst map table entry*/ unsigned long flags; struct sdp_node_info *sdp_info; + u8 hw_prio; /* Hw priority of default rules */ }; =20 enum rvu_pfvf_flags { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_npc.c index 3e4f4fee791a..bdb11f72a08b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -653,6 +653,9 @@ void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 p= cifunc, req.match_id =3D action.match_id; req.flow_key_alg =3D action.flow_key_alg; =20 + if (is_cn20k(rvu->pdev)) + req.hw_prio =3D pfvf->hw_prio; + rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); } =20 @@ -741,6 +744,9 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16= pcifunc, req.match_id =3D action.match_id; req.flow_key_alg =3D flow_key_alg; =20 + if (is_cn20k(rvu->pdev)) + req.hw_prio =3D pfvf->hw_prio; + rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); } =20 @@ -821,6 +827,9 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu,= u16 pcifunc, req.hdr.pcifunc =3D 0; /* AF is requester */ req.vf =3D pcifunc; =20 + if (is_cn20k(rvu->pdev)) + req.hw_prio =3D pfvf->hw_prio; + rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); } =20 @@ -909,6 +918,9 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u1= 6 pcifunc, int nixlf, req.match_id =3D action.match_id; req.flow_key_alg =3D flow_key_alg; =20 + if (is_cn20k(rvu->pdev)) + req.hw_prio =3D pfvf->hw_prio; + rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); } =20 @@ -2491,7 +2503,7 @@ npc_get_mcam_search_range_priority(struct npc_mcam *m= cam, { u16 fcnt; =20 - if (req->priority =3D=3D NPC_MCAM_HIGHER_PRIO) + if (req->ref_prio =3D=3D NPC_MCAM_HIGHER_PRIO) goto hprio; =20 /* For a low priority entry allocation @@ -2591,7 +2603,7 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mc= am, u16 pcifunc, goto lprio_alloc; =20 /* Get the search range for priority allocation request */ - if (req->priority) { + if (req->ref_prio) { npc_get_mcam_search_range_priority(mcam, req, &start, &end, &reverse); goto alloc; @@ -2632,11 +2644,11 @@ static int npc_mcam_alloc_entries(struct npc_mcam *= mcam, u16 pcifunc, * and not in mid zone. */ if (!(pcifunc & RVU_PFVF_FUNC_MASK) && - req->priority =3D=3D NPC_MCAM_HIGHER_PRIO) + req->ref_prio =3D=3D NPC_MCAM_HIGHER_PRIO) end =3D req->ref_entry; =20 if (!(pcifunc & RVU_PFVF_FUNC_MASK) && - req->priority =3D=3D NPC_MCAM_LOWER_PRIO) + req->ref_prio =3D=3D NPC_MCAM_LOWER_PRIO) start =3D req->ref_entry; } =20 @@ -2685,7 +2697,7 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mc= am, u16 pcifunc, /* If allocating requested no of entries is unsucessful, * expand the search range to full bitmap length and retry. */ - if (!req->priority && (rsp->count < req->count) && + if (!req->ref_prio && rsp->count < req->count && ((end - start) !=3D mcam->bmap_entries)) { reverse =3D true; start =3D 0; @@ -2696,14 +2708,14 @@ static int npc_mcam_alloc_entries(struct npc_mcam *= mcam, u16 pcifunc, /* For priority entry allocation requests, if allocation is * failed then expand search to max possible range and retry. */ - if (req->priority && rsp->count < req->count) { - if (req->priority =3D=3D NPC_MCAM_LOWER_PRIO && + if (req->ref_prio && rsp->count < req->count) { + if (req->ref_prio =3D=3D NPC_MCAM_LOWER_PRIO && (start !=3D (req->ref_entry + 1))) { start =3D req->ref_entry + 1; end =3D mcam->bmap_entries; reverse =3D false; goto alloc; - } else if ((req->priority =3D=3D NPC_MCAM_HIGHER_PRIO) && + } else if ((req->ref_prio =3D=3D NPC_MCAM_HIGHER_PRIO) && ((end - start) !=3D req->ref_entry)) { start =3D 0; end =3D req->ref_entry; @@ -2817,9 +2829,9 @@ int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu = *rvu, /* ref_entry can't be '0' if requested priority is high. * Can't be last entry if requested priority is low. */ - if ((!req->ref_entry && req->priority =3D=3D NPC_MCAM_HIGHER_PRIO) || - ((req->ref_entry =3D=3D mcam->bmap_entries) && - req->priority =3D=3D NPC_MCAM_LOWER_PRIO)) + if ((!req->ref_entry && req->ref_prio =3D=3D NPC_MCAM_HIGHER_PRIO) || + (req->ref_entry =3D=3D mcam->bmap_entries && + req->ref_prio =3D=3D NPC_MCAM_LOWER_PRIO)) return NPC_MCAM_INVALID_REQ; =20 /* Since list of allocated indices needs to be sent to requester, @@ -3365,7 +3377,7 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(s= truct rvu *rvu, /* Try to allocate a MCAM entry */ entry_req.hdr.pcifunc =3D req->hdr.pcifunc; entry_req.contig =3D true; - entry_req.priority =3D req->priority; + entry_req.ref_prio =3D req->ref_prio; entry_req.ref_entry =3D req->ref_entry; entry_req.count =3D 1; =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/driv= ers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 64c6d9162ef6..052d989f2d9a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -104,7 +104,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 = count) * will be on top of PF. */ if (!is_otx2_vf(pfvf->pcifunc)) { - req->priority =3D NPC_MCAM_HIGHER_PRIO; + req->ref_prio =3D NPC_MCAM_HIGHER_PRIO; req->ref_entry =3D flow_cfg->def_ent[0]; } =20 --=20 2.43.0