From nobody Mon Jun 8 04:25:13 2026 Received: from mx0a-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 4B88740B6C6; Fri, 5 Jun 2026 06:59:49 +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=1780642790; cv=none; b=XCryLaS/UY3YraPOJm0fUHlffoi6/fFrBerK8znZ9zz0RIj65LstIqMufTe3itP30yn+Qhs+sCFcdwg9GzIKtSuqQ8b2vkxtAxe1Gczpm0PcBuJfaollntRAmeN5tA742JV2BaLSG7suNE5oTf3g3g5skRUTaB+AmUY+Q/xe9JY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780642790; c=relaxed/simple; bh=ekTe7hbZIQd0YB91tpENtmYdl4mtyIgE3ISkU1IeIFc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PU0jIzXEfZAdoYYloYKxPm8RdWn8VUWKXBiGWefvueJhdpsXbWy5SV8FGr5Vb9lHAy2AEMeVCz4Fo+ISSFFjKvTF5BmDeBuB0DQ62tY7/mufyJofoq9UyaS/u4wvgly8Lu6IghN6UhvUOQVKIjjITNzxluV2KWO070bRYL7w72I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=XoI911Z9; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="XoI911Z9" Received: from pps.filterd (m0431384.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 655373hh302316; Thu, 4 Jun 2026 23:59:38 -0700 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=h tuEsZkKi1uXw2QsAcERI5P9a0jvBAlIqlvADZAAJ84=; b=XoI911Z9+Eeps93sB XvQjrR+MKaTpnN1kk5BYUeSqvtMHeN0P+0ga7NbDQiaN4CT+42QCL9QmmnpIzYMd 39E/aC4klW3kPRcCUicYrxupf5iEfSO+04YNoD3rI/t12Kko8Akrt5S0gaHY5wpd FNXQ3Bir60BYZSBnpU2DykBRrnIdJTMhOzgODP++yQrx+WiHE3yi3bpL+RclGQRG 4Q51j2sjgCiJ79hRXi+rTrKM3ElN/ejBr4BTUBQCqbafb1ZeYragzrpRyeNy6mWC i0fe1uiKC9gIidwSNh+q2GJNmeqLzUnWMCb7sRlQDPey25rF+ZP3ex3E7OMiD/VT XFGzA== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekcj0ajjn-12 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 04 Jun 2026 23:59:38 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.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; Thu, 4 Jun 2026 23:59:34 -0700 Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Thu, 4 Jun 2026 23:33:02 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Thu, 4 Jun 2026 23:33:02 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 86F4B3F7074; Thu, 4 Jun 2026 23:32:57 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 1/9] octeontx2-af: Enforce single RVU AF probe Date: Fri, 5 Jun 2026 12:02:37 +0530 Message-ID: <20260605063245.3553861-2-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-Authority-Analysis: v=2.4 cv=G78s1dk5 c=1 sm=1 tr=0 ts=6a2273da cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=TtqV-g6YmW1Jfm2GSLaY:22 a=M5GUcnROAAAA:8 a=T1-iXrwByj4Y60gxB9YA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2NCBTYWx0ZWRfX3d7P7VKmkqm5 R5QnhJoVF7KKREpssG6UIMbE5/IGVYuMD6+eXfhS9mlZkLOdg7AGRZJq8bI7dTuW7WqH8V+gER1 hfWwJ6ZjHQr5TYF15c9N0LoFsqGbOq9tO/l5dp1RFGiqbY0z99cm+eqSs2G9peNtNhLDCJ5FPlY SUKDnnRUHAJDsD7ZgBMjwtX9Mi3rQ51SPCNNXZXwXHPk/VkTkrEiGZAkW/0gj0ITxGISbQnpZSr 3Vfr401TJlBPT8NREQylJgr9Bn7eb13sCAKLKvP8WNbAKHGuytUlzCQMnExCD47DhkU1hNl/uUj 9cTdDHyaUexfdTbXX/DvsMNmPVM0yWgXZYdG6/9x9k5O8DRBIL/WgLz3lNfKhKMH92mOU3ee5Z6 v447iWIWFA+E1STqribOdy+0tkZkLu8G0xi4yxtXK7YKRNhsoZxxjQoD0exe6gVcct0TUiUG5DX 4CvlDdbdCayc0g8nsyw== X-Proofpoint-GUID: 1HZ8lQNiyzAYDbhlEWtpCpoCiQLNE-wf X-Proofpoint-ORIG-GUID: 1HZ8lQNiyzAYDbhlEWtpCpoCiQLNE-wf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" There is only one admin-function PCI device per system. Reject any additional AF probe with -EBUSY so the driver model matches hardware and automated reviewers can rely on a single bound instance. Signed-off-by: Ratheesh Kannoth --- drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.c index 3cf131508ecf..1f0c962e10f4 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -3542,12 +3542,19 @@ static void rvu_update_module_params(struct rvu *rv= u) kpu_profile ? kpu_profile : default_pfl_name, KPU_NAME_LEN); } =20 +static atomic_t device_bound =3D ATOMIC_INIT(0); + static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct device *dev =3D &pdev->dev; struct rvu *rvu; int err; =20 + if (atomic_cmpxchg(&device_bound, 0, 1) !=3D 0) { + dev_warn(dev, "Only one af device is supported.\n"); + return -EBUSY; + } + rvu =3D devm_kzalloc(dev, sizeof(*rvu), GFP_KERNEL); if (!rvu) return -ENOMEM; --=20 2.43.0 From nobody Mon Jun 8 04:25:13 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 E9F8C3168EF; Fri, 5 Jun 2026 06:33:17 +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=1780641199; cv=none; b=qjbrCQZZ9PNAbw5Asx2iffwZ1avRLS6L+fM3CHgDhUSKYyHpF15yG678cpZZda89psFoT8PqTzQJaVj8cmJMzpz58yx9RVzzerGGLUMR0DIh9x50mZAcAvYXdDaghnRzYE5dxeqJaz3Kbq4nOUzafqdszXaJYrA+v9+8AlnEGEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780641199; c=relaxed/simple; bh=YMQeg9bxijFxYVfxp+GeLcy2jlLWYni9+FiXud56gvY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZeGEwza8mNGrjLDAbFvL3lGgq9nzkjt3F5xxek+4c9N6625A6lR+UCY4LwVPotABlOPBVS0Lryd1sC3EMWNcDEXJQDar+fRcIRksTY8Rg9zsMS0AdGSpyZQdGAKffeZz7Ggz/hrElHZ8ycu+/PxplBunYTb0i5FJIacQjpvLM1U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=DZeBgqYz; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="DZeBgqYz" 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 654LPkn03891278; Thu, 4 Jun 2026 23:33:07 -0700 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=a rrRfGbygOBWqRZOZWDrHOfN7QhBRcp/izssYbLkZpQ=; b=DZeBgqYzGJ/WhMM6/ 1wtRZJnBADcH1Eq1+z4PlIlDf/mtoEZ+UGPAWQ2Uqj1w5hdIRZrjMnP2KFkdFY63 47cihJg7ksCr2e7ZUGwkQGMsKXQ/xhVdW6tHRX5n1fpcLXvMEE5dqOfxTFmwR8HV dQ56avsBQvoDkQOkk6lAs20dJjOgPKd5Xt9CQRyq02Jh+AH5VCIYlz4U0QPyDmQ2 EbgBitOQLL597zcC3aDzGWdi8tw8iepMkOdBQhpl7vqi3ao1m8/lU0oFtsdmHiB8 P5cXhoagBjNMcsQEUjlygyoPyXf8ipPlL6c6BcftmowY3PscOU1EH1bOjtnfJZj+ a5lsw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekh8x9b52-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 04 Jun 2026 23:33:07 -0700 (PDT) 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; Thu, 4 Jun 2026 23:33:06 -0700 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; Thu, 4 Jun 2026 23:33:06 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 594743F707A; Thu, 4 Jun 2026 23:33:02 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 2/9] octeontx2-af: npc: cn20k: debugfs enhancements Date: Fri, 5 Jun 2026 12:02:38 +0530 Message-ID: <20260605063245.3553861-3-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-ORIG-GUID: TCs1mYdx-PKEgxiyJn9uFdj67kaJ3VrK X-Authority-Analysis: v=2.4 cv=DqNmPm/+ c=1 sm=1 tr=0 ts=6a226da3 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=M5GUcnROAAAA:8 a=MGki9FtnWEUF7_4ZUUMA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2MSBTYWx0ZWRfX0HvX87YYz0Zg 7ph7V0cf57oxO3a8X0SvcYoiZ1/0h5VzlJ5J7EGWqtjBHXlSZMjHG7S581XCh51tHVm+4ulBCNi qWlkwakQ8FJS2gFCFUhHEYWEo6tMttpo/j1U2280yD/S93Yac/4qV7nxt3owG220k+hZUBgctSp sxzNAiXyJej5X/VNOnCatvIY7Vsro4INozsBb+h98wtu5ERbN7SGQEb9if/Y3j9xomS0N++gzEY L0V2y7ovtgcfQZyO767C8zfGT7XNUnBw8y1BFbI4ivoG8dSgrxgfN13kEw062sZffr2Hb7czWXv P4cv94bxvQ8AjC/fUs98ja7KtZPvU2vE0Jgbb43/5rAAYrjAt39IoZ2d4Sa4Ks150h1W59IbcwV O+cgmFuwQUfCNGIJvfesdJjbT/dN8YznrUA1RP+LYGAg4yAXIpeJ0Ybf4rYxoi7YruiJdZon0uW DZuOGzeoHFdw586Zd2w== X-Proofpoint-GUID: TCs1mYdx-PKEgxiyJn9uFdj67kaJ3VrK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Improve MCAM visibility and field debugging for CN20K NPC. - Extend "mcam_layout" to show enabled (+) or disabled state per entry so status can be verified without parsing the full "mcam_entry" dump. - Add "dstats" debugfs entry: for enabled MCAM indices, print hit deltas since the prior read by comparing hardware counters to a per-entry software baseline and advancing that baseline after each read (hardware counters are not cleared). - Add "mismatch" debugfs entry: lists MCAM entries that are enabled but not explicitly allocated, helping diagnose allocation/field issues. Signed-off-by: Ratheesh Kannoth --- .../marvell/octeontx2/af/cn20k/debugfs.c | 158 +++++++++++++++++- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 37 +++- .../ethernet/marvell/octeontx2/af/cn20k/npc.h | 11 ++ 3 files changed, 191 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c index 6f13296303cb..730ef97a57e6 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c @@ -13,6 +13,7 @@ #include "struct.h" #include "rvu.h" #include "debugfs.h" +#include "cn20k/reg.h" #include "cn20k/npc.h" =20 static int npc_mcam_layout_show(struct seq_file *s, void *unused) @@ -58,7 +59,8 @@ static int npc_mcam_layout_show(struct seq_file *s, void = *unused) "v:%u", vidx0); } =20 - seq_printf(s, "\t%u(%#x) %s\n", idx0, pf1, + seq_printf(s, "\t%u(%#x)%c %s\n", idx0, pf1, + test_bit(idx0, npc_priv->en_map) ? '+' : ' ', map ? buf0 : " "); } goto next; @@ -101,9 +103,13 @@ static int npc_mcam_layout_show(struct seq_file *s, vo= id *unused) vidx1); } =20 - seq_printf(s, "%05u(%#x) %s\t\t%05u(%#x) %s\n", - idx1, pf2, v1 ? buf1 : " ", - idx0, pf1, v0 ? buf0 : " "); + seq_printf(s, "%05u(%#x)%c %s\t\t%05u(%#x)%c %s\n", + idx1, pf2, + test_bit(idx1, npc_priv->en_map) ? '+' : ' ', + v1 ? buf1 : " ", + idx0, pf1, + test_bit(idx0, npc_priv->en_map) ? '+' : ' ', + v0 ? buf0 : " "); =20 continue; } @@ -120,8 +126,9 @@ static int npc_mcam_layout_show(struct seq_file *s, voi= d *unused) vidx0); } =20 - seq_printf(s, "\t\t \t\t%05u(%#x) %s\n", idx0, - pf1, map ? buf0 : " "); + seq_printf(s, "\t\t \t\t%05u(%#x)%c %s\n", idx0, pf1, + test_bit(idx0, npc_priv->en_map) ? '+' : ' ', + map ? buf0 : " "); continue; } =20 @@ -134,7 +141,8 @@ static int npc_mcam_layout_show(struct seq_file *s, voi= d *unused) snprintf(buf1, sizeof(buf1), "v:%05u", vidx1); } =20 - seq_printf(s, "%05u(%#x) %s\n", idx1, pf1, + seq_printf(s, "%05u(%#x)%c %s\n", idx1, pf1, + test_bit(idx1, npc_priv->en_map) ? '+' : ' ', map ? buf1 : " "); } next: @@ -145,6 +153,136 @@ static int npc_mcam_layout_show(struct seq_file *s, v= oid *unused) =20 DEFINE_SHOW_ATTRIBUTE(npc_mcam_layout); =20 +#define __OCTEONTX2_DEBUGFS_ATTRIBUTE_FOPS(__name) \ +static const struct file_operations __name ## _fops =3D { \ + .owner =3D THIS_MODULE, \ + .open =3D __name ## _open, \ + .read =3D seq_read, \ + .llseek =3D seq_lseek, \ + .release =3D single_release, \ +} + +#define DEFINE_OCTEONTX2_DEBUGFS_ATTRIBUTE_WITH_SIZE(__name, __size) \ +static int __name ## _open(struct inode *inode, struct file *file) \ +{ \ + return single_open_size(file, __name ## _show, inode->i_private, \ + __size); \ +} \ +__OCTEONTX2_DEBUGFS_ATTRIBUTE_FOPS(__name) + +static DEFINE_MUTEX(stats_lock); + +/* MAX_NUM_BANKS, MAX_SUBBANK_DEPTH and MAX_NUM_SUB_BANKS represent + * hard limit on all silicon variants, preventing any possibility of + * out-of-bounds access. + */ +static u64 dstats[MAX_NUM_BANKS][MAX_SUBBANK_DEPTH * MAX_NUM_SUB_BANKS] = =3D {}; +static int npc_mcam_dstats_show(struct seq_file *s, void *unused) +{ + struct npc_priv_t *npc_priv; + int blkaddr, pf, mcam_idx; + u64 stats, delta; + struct rvu *rvu; + char buff[64]; + u8 key_type; + void *map; + + npc_priv =3D npc_priv_get(); + rvu =3D s->private; + blkaddr =3D rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); + if (blkaddr < 0) + return 0; + + mutex_lock(&stats_lock); + seq_puts(s, "idx\tpfunc\tstats\n"); + for (int bank =3D npc_priv->num_banks - 1; bank >=3D 0; bank--) { + for (int idx =3D npc_priv->bank_depth - 1; idx >=3D 0; idx--) { + mcam_idx =3D bank * npc_priv->bank_depth + idx; + + if (npc_mcam_idx_2_key_type(rvu, mcam_idx, &key_type)) + continue; + + if (key_type =3D=3D NPC_MCAM_KEY_X4 && bank !=3D 0) + continue; + + if (!test_bit(mcam_idx, npc_priv->en_map)) + continue; + + stats =3D rvu_read64(rvu, blkaddr, + NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(idx, bank)); + if (!stats) + continue; + if (stats =3D=3D dstats[bank][idx]) + continue; + + if (stats < dstats[bank][idx]) + dstats[bank][idx] =3D 0; + + pf =3D 0xFFFF; + map =3D xa_load(&npc_priv->xa_idx2pf_map, mcam_idx); + if (map) + pf =3D xa_to_value(map); + + delta =3D stats - dstats[bank][idx]; + + snprintf(buff, sizeof(buff), "%u\t%#04x\t%llu\n", + mcam_idx, pf, delta); + seq_puts(s, buff); + + dstats[bank][idx] =3D stats; + } + } + + mutex_unlock(&stats_lock); + return 0; +} + +/* "%u\t%#04x\t%llu\n" needs less than 64 characters to print */ +#define TOTAL_SZ (MAX_NUM_BANKS * MAX_NUM_SUB_BANKS * MAX_SUBBANK_DEPTH * = 64) +DEFINE_OCTEONTX2_DEBUGFS_ATTRIBUTE_WITH_SIZE(npc_mcam_dstats, TOTAL_SZ); + +static int npc_mcam_mismatch_show(struct seq_file *s, void *unused) +{ + struct npc_priv_t *npc_priv; + struct npc_subbank *sb; + int mcam_idx, sb_off; + struct rvu *rvu; + char buff[64]; + void *map; + int rc; + + npc_priv =3D npc_priv_get(); + rvu =3D s->private; + + seq_puts(s, "index\tsb idx\tkw type\n"); + for (int bank =3D npc_priv->num_banks - 1; bank >=3D 0; bank--) { + for (int idx =3D npc_priv->bank_depth - 1; idx >=3D 0; idx--) { + mcam_idx =3D bank * npc_priv->bank_depth + idx; + + if (!test_bit(mcam_idx, npc_priv->en_map)) + continue; + + map =3D xa_load(&npc_priv->xa_idx2pf_map, mcam_idx); + if (map) + continue; + + rc =3D npc_mcam_idx_2_subbank_idx(rvu, mcam_idx, + &sb, &sb_off); + if (rc) + continue; + + snprintf(buff, sizeof(buff), "%u\t%d\t%u\n", + mcam_idx, sb->idx, sb->key_type); + + seq_puts(s, buff); + } + } + return 0; +} + +/* "%u\t%d\t%u\n" needs less than 64 characters to print. */ +DEFINE_OCTEONTX2_DEBUGFS_ATTRIBUTE_WITH_SIZE(npc_mcam_mismatch, TOTAL_SZ); + static int npc_mcam_default_show(struct seq_file *s, void *unused) { struct npc_priv_t *npc_priv; @@ -259,6 +397,12 @@ int npc_cn20k_debugfs_init(struct rvu *rvu) debugfs_create_file("vidx2idx", 0444, rvu->rvu_dbg.npc, npc_priv, &npc_vidx2idx_map_fops); =20 + debugfs_create_file("dstats", 0444, rvu->rvu_dbg.npc, rvu, + &npc_mcam_dstats_fops); + + debugfs_create_file("mismatch", 0444, rvu->rvu_dbg.npc, rvu, + &npc_mcam_mismatch_fops); + debugfs_create_file("idx2vidx", 0444, rvu->rvu_dbg.npc, npc_priv, &npc_idx2vidx_map_fops); =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.c index 003487d7c3cf..31eaaceb8766 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -824,7 +824,7 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkadd= r, rvu_write64(rvu, blkaddr, NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank), cfg); - return 0; + goto update_en_map; } =20 /* For NPC_CN20K_MCAM_KEY_X4 keys, both the banks @@ -842,6 +842,12 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkad= dr, cfg); } =20 +update_en_map: + if (enable) + set_bit(index, npc_priv.en_map); + else + clear_bit(index, npc_priv.en_map); + return 0; } =20 @@ -1789,9 +1795,9 @@ static int npc_subbank_idx_2_mcam_idx(struct rvu *rvu= , struct npc_subbank *sb, return 0; } =20 -static int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx, - struct npc_subbank **sb, - int *sb_off) +int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx, + struct npc_subbank **sb, + int *sb_off) { int bank_off, sb_id; =20 @@ -4498,11 +4504,19 @@ static int npc_priv_init(struct rvu *rvu) npc_const2 =3D rvu_read64(rvu, blkaddr, NPC_AF_CONST2); =20 num_banks =3D mcam->banks; + if (num_banks > MAX_NUM_BANKS) { + dev_err(rvu->dev, + "Number of banks(%u) is invalid\n", num_banks); + return -EINVAL; + } + bank_depth =3D mcam->banksize; =20 num_subbanks =3D FIELD_GET(GENMASK_ULL(39, 32), npc_const2); - if (!num_subbanks) { - dev_err(rvu->dev, "Number of subbanks is zero\n"); + if (!num_subbanks || num_subbanks > MAX_NUM_SUB_BANKS) { + dev_err(rvu->dev, + "Number of subbanks is invalid %u\n", + num_subbanks); return -EFAULT; } =20 @@ -4513,10 +4527,15 @@ static int npc_priv_init(struct rvu *rvu) return -EINVAL; } =20 - npc_priv.num_subbanks =3D num_subbanks; - subbank_depth =3D bank_depth / num_subbanks; + if (subbank_depth > MAX_SUBBANK_DEPTH) { + dev_err(rvu->dev, + "Invalid subbank depth %u\n", + subbank_depth); + return -EINVAL; + } =20 + npc_priv.num_subbanks =3D num_subbanks; npc_priv.bank_depth =3D bank_depth; npc_priv.subbank_depth =3D subbank_depth; =20 @@ -4605,6 +4624,8 @@ void npc_cn20k_deinit(struct rvu *rvu) */ kfree(npc_priv.sb); kfree(subbank_srch_order); + bitmap_clear(npc_priv.en_map, 0, MAX_NUM_BANKS * MAX_NUM_SUB_BANKS * + MAX_SUBBANK_DEPTH); } =20 static int npc_setup_mcam_section(struct rvu *rvu, int key_type) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.h index 3d5eb952cc07..3e851950be64 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h @@ -10,6 +10,10 @@ =20 #define MKEX_CN20K_SIGN 0x19bbfdbd160 =20 +/* MAX_NUM_BANKS, MAX_SUBBANK_DEPTH and MAX_NUM_SUB_BANKS represent + * hard limit on all silicon variants, preventing any possibility of + * out-of-bounds access on matrix defined using these values. + */ #define MAX_NUM_BANKS 2 #define MAX_NUM_SUB_BANKS 32 #define MAX_SUBBANK_DEPTH 256 @@ -170,6 +174,7 @@ struct npc_defrag_show_node { * @num_banks: Number of banks. * @num_subbanks: Number of subbanks. * @subbank_depth: Depth of subbank. + * @en_map: Enable/disable status. * @kw: Kex configured key type. * @sb: Subbank array. * @xa_sb_used: Array of used subbanks. @@ -193,6 +198,9 @@ struct npc_priv_t { const int num_banks; int num_subbanks; int subbank_depth; + DECLARE_BITMAP(en_map, MAX_NUM_BANKS * + MAX_NUM_SUB_BANKS * + MAX_SUBBANK_DEPTH); u8 kw; struct npc_subbank *sb; struct xarray xa_sb_used; @@ -336,5 +344,8 @@ u16 npc_cn20k_vidx2idx(u16 index); u16 npc_cn20k_idx2vidx(u16 idx); int npc_cn20k_defrag(struct rvu *rvu); bool npc_is_cgx_or_lbk(struct rvu *rvu, u16 pcifunc); +int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx, + struct npc_subbank **sb, + int *sb_off); =20 #endif /* NPC_CN20K_H */ --=20 2.43.0 From nobody Mon Jun 8 04:25:13 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 B3E3140B6E0; Fri, 5 Jun 2026 06:33:21 +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=1780641203; cv=none; b=B60Ix224oRm0+NMXc3BY6OkD7HoNMIRniaFwiu+jI3+u8p461FFpf1iyiBxFCrfEz/Dj51pf3VjuK+HN2PVhrOcz7yb8fj3wtuxN3Wkt8444PRlqAEE/dajoNm9/GfXh1oRt5ATywwvFiXj43LZN5Yjv9Hb3PZHbB4NMXrZfQqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780641203; c=relaxed/simple; bh=tH3gpipaaf6zuzf8TbSjpYAS5YH8WLfKDKVYxfRj0us=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=syp+Liud4JVWxuD1KQiCMEu8fMvejorNU1kveS6ZXdxCIAnr9A7S401hkGSq+mr+kfZSn9xsan/WYUR6RgY4VbO8xFH63X+p+aRHgvoMNMS6hLvS2l9wmIdVPswNb/HhtNdo0xWhUI1uumpZWeqanpDC+nq9xUjdBTpdHANjQ9Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=KNPWDj/7; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="KNPWDj/7" 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 654LQTOJ3892410; Thu, 4 Jun 2026 23:33:12 -0700 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=r kDUHU6kRBibHWT4gD5lvpI1GvEbstr+RjZ4RIUDcvY=; b=KNPWDj/7yEDfLi7HT l2VppbeTbVmnCrOvZ4TF0Zq7eEiD66Ogn8wphIu6nc3TVZvKV8KTUCiqfUDCnoHQ rJuZxQya7CWImxgN8xP32wMZqDmANIi2oljimDTXSIfEWXvqZO2P9PZMAwJ7zICw AUQtdQHIW+yn1yR7qHfg8qpXSkt4S6mw78X2vtZ77GJ3VwTJDc/2B8IiExofmMdw ogO+N1AikmDuWHV3oCv3NbK/EuJMdK+qRE7DiKXN6l+mieUjYCPTc1McVamCY7oR 7Px3AobG6kKcX4T2HhuDld20PgYLgj/T7/HfVCQgjTb2IDgBUHoj65EetT0fBcCW /+DZA== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekh8x9b55-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 04 Jun 2026 23:33:12 -0700 (PDT) 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; Thu, 4 Jun 2026 23:33:11 -0700 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; Thu, 4 Jun 2026 23:33:11 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 708D83F7074; Thu, 4 Jun 2026 23:33:07 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 3/9] devlink: heap-allocate param fill buffers in devlink_nl_param_fill Date: Fri, 5 Jun 2026 12:02:39 +0530 Message-ID: <20260605063245.3553861-4-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-ORIG-GUID: uDM72DtcRSBpg9bI4uCz0mv99HlLQYNA X-Authority-Analysis: v=2.4 cv=DqNmPm/+ c=1 sm=1 tr=0 ts=6a226da8 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=M5GUcnROAAAA:8 a=QAS8UgIW8qh4FKEizQ4A:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2MSBTYWx0ZWRfX9GNtx7sEYoLn H22pDb0YyKxN4n2vvHgVx9fYtRunwe2H3h/njShAkJ/Fh8E5uApux2o8oLTVDwTCbcwH07WR92/ v5oaLEPxK9WFMQ6MzIj2QCiK664KN+HKcgtHwU67jx8LHWskyqb3lL+6MTBOFiD9/AY5yuZso25 Jsz3gIGDA1JjuPM9e56mOhPH0BwRHFCwm5b5LupA7ftGwfiVioOlMlHOl8pS4X5S+26BL1TWYmp AbwMn+SZCSx00Ox0LerpDGBvdQNP3jfvFoQXJqGSmnRK0FH649w0QFQERb4Hx1LAVtyWIzJB846 2nP4AvAj4bYg7AC1BcCpvOZLMLLQMRXQFb7dpJN4xL7w7fyGsDAVC5taooeukGZvPeO5nYvlSUb XPv98UZmMwECeSk/9DmmU4Bz8Z0nS38XbRxnH+YY6N6D/IVHkKbYAVa71DrK602hhCU1E/o+NVL CT2bkd+7IJnWDuS6Lqg== X-Proofpoint-GUID: uDM72DtcRSBpg9bI4uCz0mv99HlLQYNA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" devlink_nl_param_fill() kept two per-configuration-mode copies of union devlink_param_value plus a struct devlink_param_gset_ctx on the stack while building the Netlink reply. Allocate those with kcalloc() and kzalloc_obj() instead, and route failures through a single cleanup path so temporary buffers are always freed. Signed-off-by: Ratheesh Kannoth --- net/devlink/param.c | 62 +++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/net/devlink/param.c b/net/devlink/param.c index 1a196d3a843d..bd3881349c60 100644 --- a/net/devlink/param.c +++ b/net/devlink/param.c @@ -304,56 +304,79 @@ static int devlink_nl_param_fill(struct sk_buff *msg,= struct devlink *devlink, u32 portid, u32 seq, int flags, struct netlink_ext_ack *extack) { - union devlink_param_value default_value[DEVLINK_PARAM_CMODE_MAX + 1]; - union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; bool default_value_set[DEVLINK_PARAM_CMODE_MAX + 1] =3D {}; bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] =3D {}; const struct devlink_param *param =3D param_item->param; - struct devlink_param_gset_ctx ctx; + union devlink_param_value *default_value; + union devlink_param_value *param_value; + struct devlink_param_gset_ctx *ctx; struct nlattr *param_values_list; struct nlattr *param_attr; void *hdr; int err; int i; =20 + default_value =3D kcalloc(DEVLINK_PARAM_CMODE_MAX + 1, + sizeof(*default_value), GFP_KERNEL); + if (!default_value) + return -ENOMEM; + + param_value =3D kcalloc(DEVLINK_PARAM_CMODE_MAX + 1, + sizeof(*param_value), GFP_KERNEL); + if (!param_value) { + kfree(default_value); + return -ENOMEM; + } + + ctx =3D kzalloc_obj(*ctx); + if (!ctx) { + kfree(param_value); + kfree(default_value); + return -ENOMEM; + } + /* Get value from driver part to driverinit configuration mode */ for (i =3D 0; i <=3D DEVLINK_PARAM_CMODE_MAX; i++) { if (!devlink_param_cmode_is_supported(param, i)) continue; if (i =3D=3D DEVLINK_PARAM_CMODE_DRIVERINIT) { - if (param_item->driverinit_value_new_valid) + if (param_item->driverinit_value_new_valid) { param_value[i] =3D param_item->driverinit_value_new; - else if (param_item->driverinit_value_valid) + } else if (param_item->driverinit_value_valid) { param_value[i] =3D param_item->driverinit_value; - else - return -EOPNOTSUPP; + } else { + err =3D -EOPNOTSUPP; + goto get_put_fail; + } =20 if (param_item->driverinit_value_valid) { default_value[i] =3D param_item->driverinit_default; default_value_set[i] =3D true; } } else { - ctx.cmode =3D i; - err =3D devlink_param_get(devlink, param, &ctx, extack); + ctx->cmode =3D i; + err =3D devlink_param_get(devlink, param, ctx, extack); if (err) - return err; - param_value[i] =3D ctx.val; + goto get_put_fail; =20 - err =3D devlink_param_get_default(devlink, param, &ctx, + param_value[i] =3D ctx->val; + + err =3D devlink_param_get_default(devlink, param, ctx, extack); if (!err) { - default_value[i] =3D ctx.val; + default_value[i] =3D ctx->val; default_value_set[i] =3D true; } else if (err !=3D -EOPNOTSUPP) { - return err; + goto get_put_fail; } } param_value_set[i] =3D true; } =20 + err =3D -EMSGSIZE; hdr =3D genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); if (!hdr) - return -EMSGSIZE; + goto get_put_fail; =20 if (devlink_nl_put_handle(msg, devlink)) goto genlmsg_cancel; @@ -393,6 +416,9 @@ static int devlink_nl_param_fill(struct sk_buff *msg, s= truct devlink *devlink, nla_nest_end(msg, param_values_list); nla_nest_end(msg, param_attr); genlmsg_end(msg, hdr); + kfree(default_value); + kfree(param_value); + kfree(ctx); return 0; =20 values_list_nest_cancel: @@ -401,7 +427,11 @@ static int devlink_nl_param_fill(struct sk_buff *msg, = struct devlink *devlink, nla_nest_cancel(msg, param_attr); genlmsg_cancel: genlmsg_cancel(msg, hdr); - return -EMSGSIZE; +get_put_fail: + kfree(default_value); + kfree(param_value); + kfree(ctx); + return err; } =20 static void devlink_param_notify(struct devlink *devlink, --=20 2.43.0 From nobody Mon Jun 8 04:25:13 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 09737409627; Fri, 5 Jun 2026 06:33:28 +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=1780641209; cv=none; b=hHrtX0tYKMaZmt3ShnqCZ0YCa/vavuqkL/Z8dvsL7zxE/wvzQEuxIBbUydchLq75U7wLCXgW2Ow1p7XPQc5uWUcIp+hy/XXCFA3kVxwUv6oYhQJb5kzDOEtRqByy4RzNwGEmp2IBqXeU4jWfmkmmOrkjIBUHpNWe8YxxoaxyvHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780641209; c=relaxed/simple; bh=GZdS2QUjakgYotPC3ba+HveGsz2JyY7CGy5ir1LoI/Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n4Bap+mr99ef1JG1QASxnltaeVzF1rgXr/P7C96LwrlJYzIlrA6o29fZl8LTAntJhoSRwpzXw6O9pXjULGYh5s1j8f+J1MysVPWnWUL1ukM4yQ+mKc7QP2xHDqY/NxY6e1zVrH57oREoFVzofg29NqnK7jjRDMs4lPrO/lyttIo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=GjyfbjFh; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="GjyfbjFh" 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 654LPXva3891046; Thu, 4 Jun 2026 23:33:17 -0700 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=0 UMGw1wARK2aeNfvc9AWyb50o++H2+0dJcA2ALBV1ws=; b=GjyfbjFhtcIypwZAM m7tEeK+D4JFWFtF/8/S7oFUHDZ8hoswPFcwXm2IG/Cy7jtHvl9u7YRrd36Nirkur SHJ2XW3hfY6KI/Y2GVOqhQEZNSZrohVKUyV7wtfH0qPUMf5J7DpRG2OE6TI1YacV BWVzQnFGdZoMrkMSYAxJ6caoUuvyc8GQt2OMwhQtJt6PWMQXYTAEIsMhwcSF8X5Z hbkdMByI6U2D4rcG7BhJSieIz8Y9iLSgBfNzbWPDnf7ZvrE14VoaOBEfzjtc572c VAHJYq9mVIOKX6n0g2BEt0cL95jsOX5+0CauqFrSFgtANIYPEoDrAgDyjxINYFeV gRj8g== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekh8x9b5b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 04 Jun 2026 23:33:17 -0700 (PDT) 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; Thu, 4 Jun 2026 23:33:16 -0700 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; Thu, 4 Jun 2026 23:33:16 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 422D23F7074; Thu, 4 Jun 2026 23:33:11 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Saeed Mahameed" , Ratheesh Kannoth Subject: [PATCH v19 net-next 4/9] devlink: Implement devlink param multi attribute nested data values Date: Fri, 5 Jun 2026 12:02:40 +0530 Message-ID: <20260605063245.3553861-5-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-ORIG-GUID: jAUTPjAzjDQqK9dSTlFzER1CTeOClhlY X-Authority-Analysis: v=2.4 cv=DqNmPm/+ c=1 sm=1 tr=0 ts=6a226dad cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=Ikd4Dj_1AAAA:8 a=M5GUcnROAAAA:8 a=poRX95JG0-uQvCm-gVcA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2MSBTYWx0ZWRfXxowGPRK0p2gk VXfATM2qoLT/sUUnc5vX9Xs9FfFWtyvuyJG6So7JqpqyQ0M9s+DC+eW9wCft4yihNrdOJf8/kIX Tp8jtjprbwcbdwneooytk6h+PyXaIedtBKg0doZk72WaBFL4iM7I9ai/ywTwzSm/raSg2udPScY Vp9/aYRldwpGt0oNGlG5Wm9j4fw2GEmXGKMIsqFlMq+TTD/WAE0PfSGe8ZDp5YTlIZLeDWXK+Qr WShUnle5sLoCFx7Y1+NlAhrVS8O+iGQjchJk9eB20yVeCk7ESBUEyH7l4gU0o39I9TyTFrzI35t Nf2W2W7DN2JE4Ao7RpVnrg1slVrc8ECS5X5woAJm+3Rsr98X+VHQW/mE5RWglUhdTvxXEa4qRKu 47cyPWvrpfY3zNpOM0fo3a5Cg0tAOseskEe2UJGCmFS5YZtoSFiNEfjakqgDU6p/dkWN/l55O5R 0CDJGXqcaKAK1W3Fdlg== X-Proofpoint-GUID: jAUTPjAzjDQqK9dSTlFzER1CTeOClhlY X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" From: Saeed Mahameed Devlink param value attribute is not defined since devlink is handling the value validating and parsing internally, this allows us to implement multi attribute values without breaking any policies. Devlink param multi-attribute values are considered to be dynamically sized arrays of u64 values, by introducing a new devlink param type DEVLINK_PARAM_TYPE_U64_ARRAY, driver and user space can set a variable count of u64 values into the DEVLINK_ATTR_PARAM_VALUE_DATA attribute. Implement get/set parsing and add to the internal value structure passed to drivers. This is useful for devices that need to configure a list of values for a specific configuration. example: $ devlink dev param show pci/... name multi-value-param name multi-value-param type driver-specific values: cmode permanent value: 0,1,2,3,4,5,6,7 $ devlink dev param set pci/... name multi-value-param \ value 4,5,6,7,0,1,2,3 cmode permanent Signed-off-by: Saeed Mahameed Signed-off-by: Ratheesh Kannoth --- Documentation/netlink/specs/devlink.yaml | 4 +++ include/net/devlink.h | 8 ++++++ include/uapi/linux/devlink.h | 1 + net/devlink/netlink_gen.c | 2 ++ net/devlink/param.c | 33 +++++++++++++++++++++++- 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netli= nk/specs/devlink.yaml index 247b147d689f..52ad1e7805d1 100644 --- a/Documentation/netlink/specs/devlink.yaml +++ b/Documentation/netlink/specs/devlink.yaml @@ -234,6 +234,10 @@ definitions: value: 10 - name: binary + - + name: u64-array + value: 129 + - name: rate-tc-index-max type: const diff --git a/include/net/devlink.h b/include/net/devlink.h index 5f4083dc4345..dd546dbd57cf 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -433,6 +433,13 @@ enum devlink_param_type { DEVLINK_PARAM_TYPE_U64 =3D DEVLINK_VAR_ATTR_TYPE_U64, DEVLINK_PARAM_TYPE_STRING =3D DEVLINK_VAR_ATTR_TYPE_STRING, DEVLINK_PARAM_TYPE_BOOL =3D DEVLINK_VAR_ATTR_TYPE_FLAG, + DEVLINK_PARAM_TYPE_U64_ARRAY =3D DEVLINK_VAR_ATTR_TYPE_U64_ARRAY, +}; + +#define __DEVLINK_PARAM_MAX_ARRAY_SIZE 32 +struct devlink_param_u64_array { + u64 size; + u64 val[__DEVLINK_PARAM_MAX_ARRAY_SIZE]; }; =20 union devlink_param_value { @@ -442,6 +449,7 @@ union devlink_param_value { u64 vu64; char vstr[__DEVLINK_PARAM_MAX_STRING_VALUE]; bool vbool; + struct devlink_param_u64_array u64arr; }; =20 struct devlink_param_gset_ctx { diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 0b165eac7619..ca713bcc47b9 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -406,6 +406,7 @@ enum devlink_var_attr_type { DEVLINK_VAR_ATTR_TYPE_BINARY, __DEVLINK_VAR_ATTR_TYPE_CUSTOM_BASE =3D 0x80, /* Any possible custom types, unrelated to NLA_* values go below */ + DEVLINK_VAR_ATTR_TYPE_U64_ARRAY, }; =20 enum devlink_attr { diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c index 81899786fd98..f52b0c2b19ed 100644 --- a/net/devlink/netlink_gen.c +++ b/net/devlink/netlink_gen.c @@ -37,6 +37,8 @@ devlink_attr_param_type_validate(const struct nlattr *att= r, case DEVLINK_VAR_ATTR_TYPE_NUL_STRING: fallthrough; case DEVLINK_VAR_ATTR_TYPE_BINARY: + fallthrough; + case DEVLINK_VAR_ATTR_TYPE_U64_ARRAY: return 0; } NL_SET_ERR_MSG_ATTR(extack, attr, "invalid enum value"); diff --git a/net/devlink/param.c b/net/devlink/param.c index bd3881349c60..3e9d2e5750c2 100644 --- a/net/devlink/param.c +++ b/net/devlink/param.c @@ -252,6 +252,15 @@ devlink_nl_param_value_put(struct sk_buff *msg, enum d= evlink_param_type type, return -EMSGSIZE; } break; + case DEVLINK_PARAM_TYPE_U64_ARRAY: + if (val->u64arr.size > __DEVLINK_PARAM_MAX_ARRAY_SIZE) + return -EMSGSIZE; + + for (int i =3D 0; i < val->u64arr.size; i++) { + if (nla_put_uint(msg, nla_type, val->u64arr.val[i])) + return -EMSGSIZE; + } + break; } return 0; } @@ -537,7 +546,7 @@ devlink_param_value_get_from_info(const struct devlink_= param *param, union devlink_param_value *value) { struct nlattr *param_data; - int len; + int len, cnt, rem; =20 param_data =3D info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; =20 @@ -577,6 +586,28 @@ devlink_param_value_get_from_info(const struct devlink= _param *param, return -EINVAL; value->vbool =3D nla_get_flag(param_data); break; + + case DEVLINK_PARAM_TYPE_U64_ARRAY: + cnt =3D 0; + nla_for_each_attr_type(param_data, + DEVLINK_ATTR_PARAM_VALUE_DATA, + genlmsg_data(info->genlhdr), + genlmsg_len(info->genlhdr), rem) { + if (cnt >=3D __DEVLINK_PARAM_MAX_ARRAY_SIZE) + return -EMSGSIZE; + + if ((nla_len(param_data) !=3D sizeof(u64)) && + (nla_len(param_data) !=3D sizeof(u32))) { + NL_SET_BAD_ATTR(info->extack, param_data); + return -EINVAL; + } + + value->u64arr.val[cnt] =3D nla_get_uint(param_data); + cnt++; + } + + value->u64arr.size =3D cnt; + break; } return 0; } --=20 2.43.0 From nobody Mon Jun 8 04:25:13 2026 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (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 1886443E4B4; Fri, 5 Jun 2026 07:00:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780642843; cv=none; b=o+yGRzjp+mKhnmTVqMfR97rmBJLstLzzphqcKv/BE/+UJlSQie336nzrZSCZ1bk2FWsxdurtd98lmmjlK4F63e760cuUGLtPBAZWE4yIHiZJO6W8Fi21alKTXIGBYaf8BTBDPXJlxAkWXOWyKoSci02ULewW9dAkDTHYkuoQy8o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780642843; c=relaxed/simple; bh=NABlmMVEQU+zULkHS7DYTl05mNhWBxJ2FUTVvu8Wp0o=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nGKkfEFtxLQgo+yRfC8P0oxKdaAdphJyJCVxNP3CHFM7SFPY07LeuHZOoaZ1ijKGkcUXmdYaNTOYi6cjZuEpnxBQsPE9JWz81eptIc6FvvO5LW0euJFp6Om1Bb5vVIX8/sSEZzc7EDSzR87Sid9MWK4cXNQu87N2TROIGLEbY6s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=Fhh6orLo; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="Fhh6orLo" Received: from pps.filterd (m0431383.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 654NRpZg1932966; Fri, 5 Jun 2026 00:00:32 -0700 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=C RJpo/sEPFpn8lmG25ihcflqZeqSgefqTUNjp78tjt8=; b=Fhh6orLo7Ix0Zunoh LYNTdrofNas3ATK3PY+negvrHIdaL8HQYWv99B8U+dvW6/8tS5uvIE1zUas3tvcc aqqh/BehBCSMBLtbH5HA3LSqWQGIUq9UDiiipXy4sv7vExp8rD7v+F9yUWC/6rsP DUXAFXX9jVPjbjmB45RvAKWcJZEiwd9+194GQLJS2UwovKNbDsnk+NYXwjka6xAm 7M1AkGgURahEwWPpuce/4V5DRmZpZKS95BAwjSoc3yWW9zTLd8ohpAojWngPb8eM RYkS4mJY9Fh5fC86eDG56pobFSmdAkCWJNtUuWia18/O7uKeFqQUN6wtZ6VLqfMs s3ovw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 4ekk2911mw-16 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 05 Jun 2026 00:00:32 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.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; Thu, 4 Jun 2026 23:59:50 -0700 Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Thu, 4 Jun 2026 23:33:22 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Thu, 4 Jun 2026 23:33:21 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 88AC43F7074; Thu, 4 Jun 2026 23:33:17 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 5/9] octeontx2-af: npc: cn20k: add subbank search order control Date: Fri, 5 Jun 2026 12:02:41 +0530 Message-ID: <20260605063245.3553861-6-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-Authority-Analysis: v=2.4 cv=MOlQXsZl c=1 sm=1 tr=0 ts=6a227410 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=qit2iCtTFQkLgVSMPQTB:22 a=M5GUcnROAAAA:8 a=z2PpVAnn9QbhSI22PBIA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-ORIG-GUID: zIhZr49SWeyzMPiD4L36fb98IiLyqN6Y X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2NCBTYWx0ZWRfX9NOKPywuUlu3 otKlzD24O596UrdnKVJH22indCfgnI2RYmufOkeiVeVT02zzRgSv3qJhJaQLv1oEmj63wxbLzM2 5+ABPBdvGvwOWCtiM69W7q+zCkd8UMVzFAtYlRCRFteyJ/FcGXTO/5hzNZK6rhi51CpsJsr16gu Xz2pC0bBwUNf08sqN4d8FrSiaG6X0B1IDc6/hWCRr0ERdW/czxwL3xiCHI1F8JoBWlAdvflL2oX 1PfGYXqZmTBvBnGqSHoS596exb+jpKr3tq7nKbiVuLczmUZ6dL+JM7wJwwgcDydyKorFk1Z7TdY z79M1c8Iwh1/mShpI6MxYrC6k/MxPURAP4xOyi4V13Mi6Q8gRxQfG/isQOe7q6MYOdhJLrxJZYA Z6ngdWdosyvZJgs5bRhxxvnP6ez4TwCut3c2fRh9dc6jrC7z2G04hhjbdtz4SFqAaGRGHQ8Vefr PgfZhR9BjM5Mc/7y3xQ== X-Proofpoint-GUID: zIhZr49SWeyzMPiD4L36fb98IiLyqN6Y X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" CN20K NPC MCAM is split into 32 subbanks that are searched in a predefined order during allocation. Lower-numbered subbanks have higher priority than higher-numbered ones. Add a runtime "srch_order" to control the order in which subbanks are searched during MCAM allocation. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 120 +++++++++++++++++- .../ethernet/marvell/octeontx2/af/cn20k/npc.h | 3 + .../marvell/octeontx2/af/rvu_devlink.c | 92 ++++++++++++-- 3 files changed, 203 insertions(+), 12 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 31eaaceb8766..2705753c1878 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -3376,7 +3376,7 @@ rvu_mbox_handler_npc_cn20k_get_kex_cfg(struct rvu *rv= u, return 0; } =20 -static int *subbank_srch_order; +static u32 *subbank_srch_order; =20 static void npc_populate_restricted_idxs(int num_subbanks) { @@ -3388,7 +3388,7 @@ static int npc_create_srch_order(int cnt) { int val =3D 0; =20 - subbank_srch_order =3D kcalloc(cnt, sizeof(int), + subbank_srch_order =3D kcalloc(cnt, sizeof(u32), GFP_KERNEL); if (!subbank_srch_order) return -ENOMEM; @@ -3906,6 +3906,122 @@ static void npc_unlock_all_subbank(void) mutex_unlock(&npc_priv.sb[i].lock); } =20 +int npc_cn20k_search_order_set(struct rvu *rvu, + u64 narr[MAX_NUM_SUB_BANKS], int cnt) +{ + struct npc_mcam *mcam =3D &rvu->hw->mcam; + int rsrc[2][MAX_NUM_SUB_BANKS] =3D { }; + u8 save[MAX_NUM_SUB_BANKS] =3D { }; + struct npc_subbank *sb; + struct xarray *xa; + int prio, rc, err; + int sb_idx; + enum { + FREE =3D 0, + USED =3D 1, + }; + + if (cnt !=3D npc_priv.num_subbanks) { + dev_err(rvu->dev, "Number of entries(%u) !=3D %u\n", + cnt, npc_priv.num_subbanks); + return -EINVAL; + } + + mutex_lock(&mcam->lock); + npc_lock_all_subbank(); + + for (sb_idx =3D 0; sb_idx < cnt; sb_idx++) { + sb =3D &npc_priv.sb[sb_idx]; + save[sb->idx] =3D sb->arr_idx; + } + + for (prio =3D 0; prio < cnt; prio++) { + sb_idx =3D narr[prio]; + sb =3D &npc_priv.sb[sb_idx]; + + if (sb->flags & NPC_SUBBANK_FLAG_USED) + xa =3D &npc_priv.xa_sb_used; + else + xa =3D &npc_priv.xa_sb_free; + + rc =3D xa_err(xa_store(xa, prio, + xa_mk_value(sb_idx), GFP_KERNEL)); + if (rc) { + dev_err(rvu->dev, + "Setting arr_idx=3D%d for sb=3D%d failed\n", + sb->arr_idx, sb_idx); + goto fail; + } + + if (sb->flags & NPC_SUBBANK_FLAG_USED) { + rsrc[USED][sb->arr_idx] -=3D 1; + rsrc[USED][prio] +=3D 1; + } else { + rsrc[FREE][sb->arr_idx] -=3D 1; + rsrc[FREE][prio] +=3D 1; + } + + sb->arr_idx =3D prio; + } + + for (prio =3D 0; prio < cnt; prio++) { + if (rsrc[FREE][prio] =3D=3D -1) + xa_erase(&npc_priv.xa_sb_free, prio); + + if (rsrc[USED][prio] =3D=3D -1) + xa_erase(&npc_priv.xa_sb_used, prio); + } + + for (int i =3D 0; i < cnt; i++) + subbank_srch_order[i] =3D (u32)narr[i]; + + restrict_valid =3D false; + + npc_unlock_all_subbank(); + mutex_unlock(&mcam->lock); + + return 0; + +fail: + for (prio =3D 0; prio < cnt; prio++) { + if (rsrc[FREE][prio] =3D=3D 1) + xa_erase(&npc_priv.xa_sb_free, prio); + + if (rsrc[USED][prio] =3D=3D 1) + xa_erase(&npc_priv.xa_sb_used, prio); + } + + for (sb_idx =3D 0; sb_idx < cnt; sb_idx++) { + sb =3D &npc_priv.sb[sb_idx]; + sb->arr_idx =3D save[sb_idx]; + + if (sb->flags & NPC_SUBBANK_FLAG_USED) + xa =3D &npc_priv.xa_sb_used; + else + xa =3D &npc_priv.xa_sb_free; + + /* Since the entry already exists, xa_store() replaces + * the value without a kmalloc(), making failure highly unlikely. + */ + err =3D xa_err(xa_store(xa, sb->arr_idx, + xa_mk_value(sb->idx), GFP_KERNEL)); + WARN(!!err, "Failed to rollback sb=3D%u idx=3D%u\n", + sb->idx, sb->arr_idx); + } + + npc_unlock_all_subbank(); + mutex_unlock(&mcam->lock); + + return rc; +} + +const u32 *npc_cn20k_search_order_get(bool *restricted_order, u32 *sz) +{ + *restricted_order =3D restrict_valid; + *sz =3D npc_priv.num_subbanks; + return subbank_srch_order; +} + /* Only non-ref non-contigous mcam indexes * are picked for defrag process */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.h index 3e851950be64..8bf857317e49 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h @@ -347,5 +347,8 @@ bool npc_is_cgx_or_lbk(struct rvu *rvu, u16 pcifunc); int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx, struct npc_subbank **sb, int *sb_off); +const u32 *npc_cn20k_search_order_get(bool *restricted_order, u32 *sz); +int npc_cn20k_search_order_set(struct rvu *rvu, u64 narr[MAX_NUM_SUB_BANKS= ], + int cnt); =20 #endif /* NPC_CN20K_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/driv= ers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c index a42404e6db7c..aa3ecab5ebd8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c @@ -1258,6 +1258,7 @@ enum rvu_af_dl_param_id { RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE, RVU_AF_DEVLINK_PARAM_ID_NPC_DEF_RULE_CNTR_ENABLE, RVU_AF_DEVLINK_PARAM_ID_NPC_DEFRAG, + RVU_AF_DEVLINK_PARAM_ID_NPC_SRCH_ORDER, RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF, }; =20 @@ -1619,12 +1620,83 @@ static int rvu_devlink_eswitch_mode_set(struct devl= ink *devlink, u16 mode, return 0; } =20 +static int rvu_af_dl_npc_srch_order_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + struct rvu_devlink *rvu_dl =3D devlink_priv(devlink); + struct rvu *rvu =3D rvu_dl->rvu; + + return npc_cn20k_search_order_set(rvu, + ctx->val.u64arr.val, + ctx->val.u64arr.size); +} + +static int rvu_af_dl_npc_srch_order_get(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + bool restricted_order; + const u32 *order; + u32 sz; + + order =3D npc_cn20k_search_order_get(&restricted_order, &sz); + ctx->val.u64arr.size =3D sz; + for (int i =3D 0; i < sz; i++) + ctx->val.u64arr.val[i] =3D order[i]; + + return 0; +} + +static int rvu_af_dl_npc_srch_order_validate(struct devlink *devlink, u32 = id, + union devlink_param_value *val, + struct netlink_ext_ack *extack) +{ + struct rvu_devlink *rvu_dl =3D devlink_priv(devlink); + struct rvu *rvu =3D rvu_dl->rvu; + bool restricted_order; + unsigned long w =3D 0; + u64 *arr; + u32 sz; + + npc_cn20k_search_order_get(&restricted_order, &sz); + if (sz !=3D val->u64arr.size) { + dev_err(rvu->dev, + "Wrong size %llu, should be %u\n", + val->u64arr.size, sz); + return -EINVAL; + } + + arr =3D val->u64arr.val; + for (int i =3D 0; i < sz; i++) { + if (arr[i] >=3D sz) + return -EINVAL; + + w |=3D BIT_ULL(arr[i]); + } + + if (bitmap_weight(&w, sz) !=3D sz) { + dev_err(rvu->dev, + "Duplicate or out-of-range subbank index. %lu\n", + find_first_zero_bit(&w, sz)); + return -EINVAL; + } + + return 0; +} + static const struct devlink_ops rvu_devlink_ops =3D { .eswitch_mode_get =3D rvu_devlink_eswitch_mode_get, .eswitch_mode_set =3D rvu_devlink_eswitch_mode_set, }; =20 -static const struct devlink_param rvu_af_dl_param_defrag[] =3D { +static const struct devlink_param rvu_af_dl_cn20k_params[] =3D { + DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_SRCH_ORDER, + "npc_srch_order", DEVLINK_PARAM_TYPE_U64_ARRAY, + BIT(DEVLINK_PARAM_CMODE_RUNTIME), + rvu_af_dl_npc_srch_order_get, + rvu_af_dl_npc_srch_order_set, + rvu_af_dl_npc_srch_order_validate), DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_DEFRAG, "npc_defrag", DEVLINK_PARAM_TYPE_STRING, BIT(DEVLINK_PARAM_CMODE_RUNTIME), @@ -1666,13 +1738,13 @@ int rvu_register_dl(struct rvu *rvu) } =20 if (is_cn20k(rvu->pdev)) { - err =3D devlink_params_register(dl, rvu_af_dl_param_defrag, - ARRAY_SIZE(rvu_af_dl_param_defrag)); + err =3D devlink_params_register(dl, rvu_af_dl_cn20k_params, + ARRAY_SIZE(rvu_af_dl_cn20k_params)); if (err) { dev_err(rvu->dev, - "devlink defrag params register failed with error %d", + "devlink cn20k params register failed with error %d", err); - goto err_dl_defrag; + goto err_dl_cn20k_params; } } =20 @@ -1695,10 +1767,10 @@ int rvu_register_dl(struct rvu *rvu) =20 err_dl_exact_match: if (is_cn20k(rvu->pdev)) - devlink_params_unregister(dl, rvu_af_dl_param_defrag, - ARRAY_SIZE(rvu_af_dl_param_defrag)); + devlink_params_unregister(dl, rvu_af_dl_cn20k_params, + ARRAY_SIZE(rvu_af_dl_cn20k_params)); =20 -err_dl_defrag: +err_dl_cn20k_params: devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_para= ms)); =20 err_dl_health: @@ -1717,8 +1789,8 @@ void rvu_unregister_dl(struct rvu *rvu) devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_para= ms)); =20 if (is_cn20k(rvu->pdev)) - devlink_params_unregister(dl, rvu_af_dl_param_defrag, - ARRAY_SIZE(rvu_af_dl_param_defrag)); + devlink_params_unregister(dl, rvu_af_dl_cn20k_params, + ARRAY_SIZE(rvu_af_dl_cn20k_params)); =20 /* Unregister exact match devlink only for CN10K-B */ if (rvu_npc_exact_has_match_table(rvu)) --=20 2.43.0 From nobody Mon Jun 8 04:25:13 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 55AD947798A; Fri, 5 Jun 2026 07:04:42 +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=1780643085; cv=none; b=FliegjH+wOdHG48Z3e1C9vdr/tTERZbdTVcWFU/NllnVYSEYeCx6TxL76fY0hB6nSlrGzggVQ7H0TJ7VO8ZTpZd5LgObqxyt0NMvYMacq+lbbrBDENrfDqJTKqFgnObw6Ma9lg9epV3JP6pjxtwYZBSkmesWhtIc2DIbYS28MPs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780643085; c=relaxed/simple; bh=Z/d/A90k65ZEmjLxckOi5aNSfA7K79CbcoxcYeHLkWk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=d4XEj1C+oLUd6BLmjXnKiMGYtMUAq4zC95nhXGDWqObQBuIt/oIhyY+QqTVPj95ngTKwL9up581QgwHPGLl1OBXD34Smi3gi10UpIggHIYCJUC67l2ZX+4TL90Fg9JqQv+9GmZCHJB3BrOgDdfjViEUN3BJjonEEERpqq7n5TL8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=QSIKqbV9; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="QSIKqbV9" 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 654LQMGv3892390; Fri, 5 Jun 2026 00:04:33 -0700 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=O iks7CmXjiKNmZU9B24n4fWVZ8gh6WXRZOY5Lnuo+/w=; b=QSIKqbV9hnLen9jbD 2GifNUVYfGOWIKM9Nwr4Sh8Oezvh94Ho+yMDPFUcyLLiQZVFVsLr4ybLXZfEMdsj bIBasgM+wdCvc+YEu9lFm3OTbXRup8QIaOc4OEEG3Sa17Pt/qdGsJ7Mlpk8y8mNS orS3C05SsrjqQzSih0my44ZGYV9Fer0A/4KijxpitEVrmdqI05BZt9dCIefcfwKp fJUePORY8chnCe2TGJ2alx6sAWwcDEuyVaAnAHKB16uvKLEKxQlWxu9VS6hLT32V nrTfpBMHvPTZTuJ/HIVUUjGX1KDpdkyOrX2b/zIMavpkXJkw1uC7RQFLntPlobql vB7hw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekh8x9e58-18 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 05 Jun 2026 00:04:32 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.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; Fri, 5 Jun 2026 00:02:56 -0700 Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Thu, 4 Jun 2026 23:33:26 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Thu, 4 Jun 2026 23:33:26 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 3AA033F707A; Thu, 4 Jun 2026 23:33:21 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 6/9] octeontx2: cn20k: Coordinate default rules with NIX LF lifecycle Date: Fri, 5 Jun 2026 12:02:42 +0530 Message-ID: <20260605063245.3553861-7-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-ORIG-GUID: lDjSqbqtRQNWHUZB62IuMD_0riMgkNoc X-Authority-Analysis: v=2.4 cv=DqNmPm/+ c=1 sm=1 tr=0 ts=6a227500 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=M5GUcnROAAAA:8 a=D4RoFv6TgYvzmL5duKYA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2NiBTYWx0ZWRfX3R/wa6v2XEEX HxV8IIYmZ6vgMoUXBmTmSEb27jp9f3RQVQx+fkptudi3rjkHWAu0LimGuik34aoDE4oiX7rYXtD Wlh0cMTc2DbN8Ipd72m8yvDODoqA+FI5bqITAvtIMsRlZVuKI+egymM+PyLDrcGFrRZnUdPBBDz F4XFw4GQjs46oQqrXImIm4leZNUw772fkAYtrPVXkwlo2vCTnYE/+U/awanVcEp9UeWRbmTVxd6 aa9/VgHEEjI6BgOWTw7z3quAPyFpF5kszxf0q3/j1FNRb39+ESAFC6Xv9fsh2FNLX0P6uPHlBn3 iq6Zb6lwV9n/JwzVWmwrnXpvi1giTWCSrwHqI4UtpI+zBpZMlZS3a4XeuvQ4KbV+15cRPw/GnF7 tQtZ8vIK67C8T4Yc3qC117Z+8YbUtBv/n8SrHOB8MCWObjxV8gohyZ8LmX/DbHn4lKUaL2/1rP/ K6YVVz/ou+0QBuj6y2Q== X-Proofpoint-GUID: lDjSqbqtRQNWHUZB62IuMD_0riMgkNoc X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Add NIX_LF_DONT_FREE_DFT_IDXS so the PF can send NIX LF free during hw reinit or teardown without the AF freeing CN20K default NPC rule indexes while the driver still owns that state (otx2_init_hw_resources and otx2_free_hw_resources). On CN20K, allocate default NPC rules from NIX LF alloc before nix_interface_init, roll back with npc_cn20k_dft_rules_free on failure, and free from NIX LF free when the new flag is not set. Tighten rvu_mbox_handler_nix_lf_alloc error handling: use a single rc, propagate qmem_alloc and other errors, and set -ENOMEM only when kcalloc fails (remove the blanket -ENOMEM at the free_mem path). Signed-off-by: Ratheesh Kannoth --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 1 + .../ethernet/marvell/octeontx2/af/rvu_nix.c | 77 +++++++++++++------ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 20 +++-- .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 6 +- 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.h index dc42c81c0942..e07fbf842b94 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1009,6 +1009,7 @@ struct nix_lf_free_req { struct mbox_msghdr hdr; #define NIX_LF_DISABLE_FLOWS BIT_ULL(0) #define NIX_LF_DONT_FREE_TX_VTAG BIT_ULL(1) +#define NIX_LF_DONT_FREE_DFT_IDXS BIT_ULL(2) u64 flags; }; =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_nix.c index f977734ae712..d8989395e875 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -16,6 +16,7 @@ #include "cgx.h" #include "lmac_common.h" #include "rvu_npc_hash.h" +#include "cn20k/npc.h" =20 static void nix_free_tx_vtag_entries(struct rvu *rvu, u16 pcifunc); static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req, @@ -1499,9 +1500,11 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, struct nix_lf_alloc_req *req, struct nix_lf_alloc_rsp *rsp) { - int nixlf, qints, hwctx_size, intf, err, rc =3D 0; + int nixlf, qints, hwctx_size, intf, rc =3D 0; + u16 bcast, mcast, promisc, ucast; struct rvu_hwinfo *hw =3D rvu->hw; u16 pcifunc =3D req->hdr.pcifunc; + bool rules_created =3D false; struct rvu_block *block; struct rvu_pfvf *pfvf; u64 cfg, ctx_cfg; @@ -1555,8 +1558,8 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, return NIX_AF_ERR_RSS_GRPS_INVALID; =20 /* Reset this NIX LF */ - err =3D rvu_lf_reset(rvu, block, nixlf); - if (err) { + rc =3D rvu_lf_reset(rvu, block, nixlf); + if (rc) { dev_err(rvu->dev, "Failed to reset NIX%d LF%d\n", block->addr - BLKADDR_NIX0, nixlf); return NIX_AF_ERR_LF_RESET; @@ -1566,13 +1569,15 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, =20 /* Alloc NIX RQ HW context memory and config the base */ hwctx_size =3D 1UL << ((ctx_cfg >> 4) & 0xF); - err =3D qmem_alloc(rvu->dev, &pfvf->rq_ctx, req->rq_cnt, hwctx_size); - if (err) + rc =3D qmem_alloc(rvu->dev, &pfvf->rq_ctx, req->rq_cnt, hwctx_size); + if (rc) goto free_mem; =20 pfvf->rq_bmap =3D kcalloc(req->rq_cnt, sizeof(long), GFP_KERNEL); - if (!pfvf->rq_bmap) + if (!pfvf->rq_bmap) { + rc =3D -ENOMEM; goto free_mem; + } =20 rvu_write64(rvu, blkaddr, NIX_AF_LFX_RQS_BASE(nixlf), (u64)pfvf->rq_ctx->iova); @@ -1583,13 +1588,15 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, =20 /* Alloc NIX SQ HW context memory and config the base */ hwctx_size =3D 1UL << (ctx_cfg & 0xF); - err =3D qmem_alloc(rvu->dev, &pfvf->sq_ctx, req->sq_cnt, hwctx_size); - if (err) + rc =3D qmem_alloc(rvu->dev, &pfvf->sq_ctx, req->sq_cnt, hwctx_size); + if (rc) goto free_mem; =20 pfvf->sq_bmap =3D kcalloc(req->sq_cnt, sizeof(long), GFP_KERNEL); - if (!pfvf->sq_bmap) + if (!pfvf->sq_bmap) { + rc =3D -ENOMEM; goto free_mem; + } =20 rvu_write64(rvu, blkaddr, NIX_AF_LFX_SQS_BASE(nixlf), (u64)pfvf->sq_ctx->iova); @@ -1599,13 +1606,15 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, =20 /* Alloc NIX CQ HW context memory and config the base */ hwctx_size =3D 1UL << ((ctx_cfg >> 8) & 0xF); - err =3D qmem_alloc(rvu->dev, &pfvf->cq_ctx, req->cq_cnt, hwctx_size); - if (err) + rc =3D qmem_alloc(rvu->dev, &pfvf->cq_ctx, req->cq_cnt, hwctx_size); + if (rc) goto free_mem; =20 pfvf->cq_bmap =3D kcalloc(req->cq_cnt, sizeof(long), GFP_KERNEL); - if (!pfvf->cq_bmap) + if (!pfvf->cq_bmap) { + rc =3D -ENOMEM; goto free_mem; + } =20 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CQS_BASE(nixlf), (u64)pfvf->cq_ctx->iova); @@ -1615,18 +1624,18 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, =20 /* Initialize receive side scaling (RSS) */ hwctx_size =3D 1UL << ((ctx_cfg >> 12) & 0xF); - err =3D nixlf_rss_ctx_init(rvu, blkaddr, pfvf, nixlf, req->rss_sz, - req->rss_grps, hwctx_size, req->way_mask, - !!(req->flags & NIX_LF_RSS_TAG_LSB_AS_ADDER)); - if (err) + rc =3D nixlf_rss_ctx_init(rvu, blkaddr, pfvf, nixlf, req->rss_sz, + req->rss_grps, hwctx_size, req->way_mask, + !!(req->flags & NIX_LF_RSS_TAG_LSB_AS_ADDER)); + if (rc) goto free_mem; =20 /* Alloc memory for CQINT's HW contexts */ cfg =3D rvu_read64(rvu, blkaddr, NIX_AF_CONST2); qints =3D (cfg >> 24) & 0xFFF; hwctx_size =3D 1UL << ((ctx_cfg >> 24) & 0xF); - err =3D qmem_alloc(rvu->dev, &pfvf->cq_ints_ctx, qints, hwctx_size); - if (err) + rc =3D qmem_alloc(rvu->dev, &pfvf->cq_ints_ctx, qints, hwctx_size); + if (rc) goto free_mem; =20 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_BASE(nixlf), @@ -1639,8 +1648,8 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, cfg =3D rvu_read64(rvu, blkaddr, NIX_AF_CONST2); qints =3D (cfg >> 12) & 0xFFF; hwctx_size =3D 1UL << ((ctx_cfg >> 20) & 0xF); - err =3D qmem_alloc(rvu->dev, &pfvf->nix_qints_ctx, qints, hwctx_size); - if (err) + rc =3D qmem_alloc(rvu->dev, &pfvf->nix_qints_ctx, qints, hwctx_size); + if (rc) goto free_mem; =20 rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_BASE(nixlf), @@ -1684,10 +1693,22 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, if (is_sdp_pfvf(rvu, pcifunc)) intf =3D NIX_INTF_TYPE_SDP; =20 - err =3D nix_interface_init(rvu, pcifunc, intf, nixlf, rsp, - !!(req->flags & NIX_LF_LBK_BLK_SEL)); - if (err) - goto free_mem; + if (is_cn20k(rvu->pdev)) { + rc =3D npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &bcast, &mcast, + &promisc, &ucast); + if (rc) { + rc =3D npc_cn20k_dft_rules_alloc(rvu, pcifunc); + if (rc) + goto free_mem; + + rules_created =3D true; + } + } + + rc =3D nix_interface_init(rvu, pcifunc, intf, nixlf, rsp, + !!(req->flags & NIX_LF_LBK_BLK_SEL)); + if (rc) + goto free_dft; =20 /* Disable NPC entries as NIXLF's contexts are not initialized yet */ rvu_npc_disable_default_entries(rvu, pcifunc, nixlf); @@ -1699,9 +1720,12 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, =20 goto exit; =20 +free_dft: + if (is_cn20k(rvu->pdev) && rules_created) + npc_cn20k_dft_rules_free(rvu, pcifunc); + free_mem: nix_ctx_free(rvu, pfvf); - rc =3D -ENOMEM; =20 exit: /* Set macaddr of this PF/VF */ @@ -1775,6 +1799,9 @@ int rvu_mbox_handler_nix_lf_free(struct rvu *rvu, str= uct nix_lf_free_req *req, =20 nix_ctx_free(rvu, pfvf); =20 + if (is_cn20k(rvu->pdev) && !(req->flags & NIX_LF_DONT_FREE_DFT_IDXS)) + npc_cn20k_dft_rules_free(rvu, pcifunc); + return 0; } =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_npc.c index d301a3f0f87a..150d50b72c48 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -1285,11 +1285,18 @@ void npc_enadis_default_mce_entry(struct rvu *rvu, = u16 pcifunc, struct nix_mce_list *mce_list; int index, blkaddr, mce_idx; struct rvu_pfvf *pfvf; + u16 ptr[4]; =20 /* multicast pkt replication is not enabled for AF's VFs & SDP links */ if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(rvu, pcifunc)) return; =20 + /* In cn20k, only CGX mapped devices have default MCAST entry */ + if (is_cn20k(rvu->pdev) && + npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &ptr[0], &ptr[1], + &ptr[2], &ptr[3])) + return; + blkaddr =3D rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); if (blkaddr < 0) return; @@ -1329,9 +1336,12 @@ static void npc_enadis_default_entries(struct rvu *r= vu, u16 pcifunc, struct rvu_pfvf *pfvf =3D rvu_get_pfvf(rvu, pcifunc); struct npc_mcam *mcam =3D &rvu->hw->mcam; int index, blkaddr; + u16 ptr[4]; =20 /* only CGX or LBK interfaces have default entries */ - if (is_cn20k(rvu->pdev) && !npc_is_cgx_or_lbk(rvu, pcifunc)) + if (is_cn20k(rvu->pdev) && + npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &ptr[0], &ptr[1], + &ptr[2], &ptr[3])) return; =20 blkaddr =3D rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); @@ -4085,12 +4095,10 @@ void rvu_npc_clear_ucast_entry(struct rvu *rvu, int= pcifunc, int nixlf) =20 ucast_idx =3D npc_get_nixlf_mcam_index(mcam, pcifunc, nixlf, NIXLF_UCAST_ENTRY); - if (ucast_idx < 0) { - dev_err(rvu->dev, - "%s: Error to get ucast entry for pcifunc=3D%#x\n", - __func__, pcifunc); + + /* In cn20k, default rules are freed before detach rsrc */ + if (ucast_idx < 0) return; - } =20 npc_enable_mcam_entry(rvu, mcam, blkaddr, ucast_idx, false); =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers= /net/ethernet/marvell/octeontx2/nic/otx2_pf.c index f9fbf0c17648..b4538edb13f8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1053,7 +1053,6 @@ irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void= *pf_irq) /* Clear the IRQ */ otx2_write64(pf, RVU_PF_INT, BIT_ULL(0)); =20 - mbox_data =3D otx2_read64(pf, RVU_PF_PFAF_MBOX0); =20 if (mbox_data & MBOX_UP_MSG) { @@ -1729,7 +1728,7 @@ int otx2_init_hw_resources(struct otx2_nic *pf) mutex_lock(&mbox->lock); free_req =3D otx2_mbox_alloc_msg_nix_lf_free(mbox); if (free_req) { - free_req->flags =3D NIX_LF_DISABLE_FLOWS; + free_req->flags =3D NIX_LF_DISABLE_FLOWS | NIX_LF_DONT_FREE_DFT_IDXS; if (otx2_sync_mbox_msg(mbox)) dev_err(pf->dev, "%s failed to free nixlf\n", __func__); } @@ -1803,7 +1802,7 @@ void otx2_free_hw_resources(struct otx2_nic *pf) /* Reset NIX LF */ free_req =3D otx2_mbox_alloc_msg_nix_lf_free(mbox); if (free_req) { - free_req->flags =3D NIX_LF_DISABLE_FLOWS; + free_req->flags =3D NIX_LF_DISABLE_FLOWS | NIX_LF_DONT_FREE_DFT_IDXS; if (!(pf->flags & OTX2_FLAG_PF_SHUTDOWN)) free_req->flags |=3D NIX_LF_DONT_FREE_TX_VTAG; if (otx2_sync_mbox_msg(mbox)) @@ -1926,7 +1925,6 @@ int otx2_alloc_queue_mem(struct otx2_nic *pf) struct otx2_qset *qset =3D &pf->qset; struct otx2_cq_poll *cq_poll; =20 - /* RQ and SQs are mapped to different CQs, * so find out max CQ IRQs (i.e CINTs) needed. */ --=20 2.43.0 From nobody Mon Jun 8 04:25:13 2026 Received: from mx0a-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 62D5F3672A2; Fri, 5 Jun 2026 06:33:42 +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=1780641224; cv=none; b=MeJngSjMjC4tSZlPjlMcCHYlbNXMcBr9Bv2Z7WijQ82N1q7JA8ipvCq5xhJjvE80/Bi3IYJghx9dZNia7NCxiwwQCtiXIldmXLYCtxwUU3yybTSg00+HzQLllMJfmfEjGrBP+61rT9dJIbejamXBtO/ONMiiAlNxoGvELOqQRWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780641224; c=relaxed/simple; bh=7LCYA0/0AqZisN1ZDfRo39/63Ht+GEgoDEv0EXzrhiY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EIlzYLkpRdSnqzCUwSF/jJwZJcRz8hYgyYAzukXypR2hcZCEXXEPDqRdkueGhkPTHuD6FhcWhj2TKGgXl9trJdilJf8LQKUoo8yA+VuF1n73JuQJYJuMSkqBsNqfC2mrfQebD4I6VF6x0SDzWKlH2hVJcxRjESr2bj9EMawHnqY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=dYPjlH3y; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="dYPjlH3y" Received: from pps.filterd (m0431384.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6553Y2x3302329; Thu, 4 Jun 2026 23:33:31 -0700 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=4 fQ8GdI+wOyDUWFVMy74A7gXeh6NNt3X3lWBcnXJRSY=; b=dYPjlH3yABC/rspwN 3hkTL0YReN3MbjNfrRvoHAFCQxh0U7FT6+YZLQ5Tdi5INk2zCbafiIXuAcQHvktw RXSSFBmDJeA4T9GzirrN6+dPPaWuYZY840F+dl0EN7rDTYLu1USsXvsq6f6xkxSI AqGKPgVvnZfefBYmwTbnmEci0igYkUlD9wHBuB+wIyhJKYJQFxtYzDMbLkrJm5Oo 0aIZzOsScjbqV55VvCaj399HLuEyzZeupCIwzwiAfu7JQ23fHYzzVsjT0DtEoTIe nNZBmLbF4ymIWfhEMffqZV3vUiICIoxdNdvHHzbfbz21viv0UZcRyO1RrnB58q1a KvqNQ== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekcj0agnj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 04 Jun 2026 23:33:31 -0700 (PDT) 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; Thu, 4 Jun 2026 23:33:30 -0700 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; Thu, 4 Jun 2026 23:33:30 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id AD8953F7074; Thu, 4 Jun 2026 23:33:26 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 7/9] octeontx2-af: npc: Support for custom KPU profile from filesystem Date: Fri, 5 Jun 2026 12:02:43 +0530 Message-ID: <20260605063245.3553861-8-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-Authority-Analysis: v=2.4 cv=G78s1dk5 c=1 sm=1 tr=0 ts=6a226dbb cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=TtqV-g6YmW1Jfm2GSLaY:22 a=M5GUcnROAAAA:8 a=RqBH2XuCMo2EIviFO1EA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2MSBTYWx0ZWRfX6rOF40U5iDQ7 wX2D84OYWHJ8fFEUCTYmHxzB5RDWTFo3xm2W4cktT8Pd4/c+vh2D3k7BU1QbXbhefY42BJaVIPB bwrH0H5nsCm9oDNW6Md8PCHOlJOoqxWAg1k6njqOlpHAAz6FOfv6ZoCOSUdQ9TnEXW8ytUc2QwW Kyl10Mo4RAUGqGED4RcFsZj5j/HjhE273JPI8yzv61Gr09QUk/gzgaPj6WnLKgg39vQIcS+yZ6c Yvp3XA+mPlyYThS/sQUiPgEv9hY/TycIr3YBi0O2icYoEk55H0qz+Pv0BrhKoM7bt6IOlwOUJJ+ rH1MQDepgmDkBy6DOQMtVYN8SEsUMIwsjaHRqEty/0Nyrq7258dPdcmiUP/kypIH3XxoTbopItm BSpLOYrxSeoLWDvkdqPE4MPlH/pFGT5a1v5/JaFxK9Bla8v/8Tpq5Qkg2g4TCcFeBHKn2TBIi00 IXb8n402YLXJRf50cyQ== X-Proofpoint-GUID: BsV8YaopJ15eDyU2ATdRkZI_Tha15J3P X-Proofpoint-ORIG-GUID: BsV8YaopJ15eDyU2ATdRkZI_Tha15J3P X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Flashing updated firmware on deployed devices is cumbersome. Provide a mechanism to load a custom KPU (Key Parse Unit) profile directly from the filesystem at module load time. When the rvu_af module is loaded with the kpu_profile parameter, the specified profile is read from /lib/firmware/kpu and programmed into the KPU registers. Add npc_kpu_profile_cam2 for the extended cam format used by filesystem-loaded profiles and support ptype/ptype_mask in npc_config_kpucam when profile->from_fs is set. Usage: 1. Copy the KPU profile file to /lib/firmware/kpu. 2. Build OCTEONTX2_AF as a module. 3. Load: insmod rvu_af.ko kpu_profile=3D Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 57 ++- .../net/ethernet/marvell/octeontx2/af/npc.h | 17 + .../net/ethernet/marvell/octeontx2/af/rvu.h | 12 +- .../ethernet/marvell/octeontx2/af/rvu_npc.c | 466 ++++++++++++++---- .../ethernet/marvell/octeontx2/af/rvu_npc.h | 17 + .../ethernet/marvell/octeontx2/af/rvu_reg.h | 1 + 6 files changed, 459 insertions(+), 111 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 2705753c1878..32b53b5bc57a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -521,13 +521,17 @@ npc_program_single_kpm_profile(struct rvu *rvu, int b= lkaddr, int kpm, int start_entry, const struct npc_kpu_profile *profile) { + int num_cam_entries, num_action_entries; int entry, num_entries, max_entries; u64 idx; =20 - if (profile->cam_entries !=3D profile->action_entries) { + num_cam_entries =3D npc_get_num_kpu_cam_entries(rvu, profile); + num_action_entries =3D npc_get_num_kpu_action_entries(rvu, profile); + + if (num_cam_entries !=3D num_action_entries) { dev_err(rvu->dev, "kpm%d: CAM and action entries [%d !=3D %d] not equal\n", - kpm, profile->cam_entries, profile->action_entries); + kpm, num_cam_entries, num_action_entries); =20 WARN(1, "Fatal error\n"); return; @@ -536,16 +540,18 @@ npc_program_single_kpm_profile(struct rvu *rvu, int b= lkaddr, max_entries =3D rvu->hw->npc_kpu_entries / 2; entry =3D start_entry; /* Program CAM match entries for previous kpm extracted data */ - num_entries =3D min_t(int, profile->cam_entries, max_entries); + num_entries =3D min_t(int, num_cam_entries, max_entries); for (idx =3D 0; entry < num_entries + start_entry; entry++, idx++) - npc_config_kpmcam(rvu, blkaddr, &profile->cam[idx], + npc_config_kpmcam(rvu, blkaddr, + npc_get_kpu_cam_nth_entry(rvu, profile, idx), kpm, entry); =20 entry =3D start_entry; /* Program this kpm's actions */ - num_entries =3D min_t(int, profile->action_entries, max_entries); + num_entries =3D min_t(int, num_action_entries, max_entries); for (idx =3D 0; entry < num_entries + start_entry; entry++, idx++) - npc_config_kpmaction(rvu, blkaddr, &profile->action[idx], + npc_config_kpmaction(rvu, blkaddr, + npc_get_kpu_action_nth_entry(rvu, profile, idx), kpm, entry, false); } =20 @@ -611,20 +617,23 @@ npc_enable_kpm_entry(struct rvu *rvu, int blkaddr, in= t kpm, int num_entries) static void npc_program_kpm_profile(struct rvu *rvu, int blkaddr, int num_= kpms) { const struct npc_kpu_profile *profile1, *profile2; + int pfl1_num_cam_entries, pfl2_num_cam_entries; int idx, total_cam_entries; =20 for (idx =3D 0; idx < num_kpms; idx++) { profile1 =3D &rvu->kpu.kpu[idx]; + pfl1_num_cam_entries =3D npc_get_num_kpu_cam_entries(rvu, profile1); npc_program_single_kpm_profile(rvu, blkaddr, idx, 0, profile1); profile2 =3D &rvu->kpu.kpu[idx + KPU_OFFSET]; + pfl2_num_cam_entries =3D npc_get_num_kpu_cam_entries(rvu, profile2); + npc_program_single_kpm_profile(rvu, blkaddr, idx, - profile1->cam_entries, + pfl1_num_cam_entries, profile2); - total_cam_entries =3D profile1->cam_entries + - profile2->cam_entries; + total_cam_entries =3D pfl1_num_cam_entries + pfl2_num_cam_entries; npc_enable_kpm_entry(rvu, blkaddr, idx, total_cam_entries); rvu_write64(rvu, blkaddr, NPC_AF_KPMX_PASS2_OFFSET(idx), - profile1->cam_entries); + pfl1_num_cam_entries); /* Enable the KPUs associated with this KPM */ rvu_write64(rvu, blkaddr, NPC_AF_KPUX_CFG(idx), 0x01); rvu_write64(rvu, blkaddr, NPC_AF_KPUX_CFG(idx + KPU_OFFSET), @@ -634,6 +643,7 @@ static void npc_program_kpm_profile(struct rvu *rvu, in= t blkaddr, int num_kpms) =20 void npc_cn20k_parser_profile_init(struct rvu *rvu, int blkaddr) { + struct npc_kpu_profile_action *act; struct rvu_hwinfo *hw =3D rvu->hw; int num_pkinds, idx; =20 @@ -665,9 +675,15 @@ void npc_cn20k_parser_profile_init(struct rvu *rvu, in= t blkaddr) num_pkinds =3D rvu->kpu.pkinds; num_pkinds =3D min_t(int, hw->npc_pkinds, num_pkinds); =20 - for (idx =3D 0; idx < num_pkinds; idx++) - npc_config_kpmaction(rvu, blkaddr, &rvu->kpu.ikpu[idx], + /* Cn20k does not support Custom profile from filesystem */ + for (idx =3D 0; idx < num_pkinds; idx++) { + act =3D npc_get_ikpu_nth_entry(rvu, idx); + if (!act) + continue; + + npc_config_kpmaction(rvu, blkaddr, act, 0, idx, true); + } =20 /* Program KPM CAM and Action profiles */ npc_program_kpm_profile(rvu, blkaddr, hw->npc_kpms); @@ -679,7 +695,7 @@ struct npc_priv_t *npc_priv_get(void) } =20 static void npc_program_mkex_rx(struct rvu *rvu, int blkaddr, - struct npc_mcam_kex_extr *mkex_extr, + const struct npc_mcam_kex_extr *mkex_extr, u8 intf) { u8 num_extr =3D rvu->hw->npc_kex_extr; @@ -708,7 +724,7 @@ static void npc_program_mkex_rx(struct rvu *rvu, int bl= kaddr, } =20 static void npc_program_mkex_tx(struct rvu *rvu, int blkaddr, - struct npc_mcam_kex_extr *mkex_extr, + const struct npc_mcam_kex_extr *mkex_extr, u8 intf) { u8 num_extr =3D rvu->hw->npc_kex_extr; @@ -737,7 +753,7 @@ static void npc_program_mkex_tx(struct rvu *rvu, int bl= kaddr, } =20 static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr, - struct npc_mcam_kex_extr *mkex_extr) + const struct npc_mcam_kex_extr *mkex_extr) { struct rvu_hwinfo *hw =3D rvu->hw; u8 intf; @@ -1630,8 +1646,8 @@ npc_cn20k_update_action_entries_n_flags(struct rvu *r= vu, int npc_cn20k_apply_custom_kpu(struct rvu *rvu, struct npc_kpu_profile_adapter *profile) { + const struct npc_cn20k_kpu_profile_fwdata *fw =3D rvu->kpu_fwdata; size_t hdr_sz =3D sizeof(struct npc_cn20k_kpu_profile_fwdata); - struct npc_cn20k_kpu_profile_fwdata *fw =3D rvu->kpu_fwdata; struct npc_kpu_profile_action *action; struct npc_kpu_profile_cam *cam; struct npc_kpu_fwdata *fw_kpu; @@ -1676,8 +1692,15 @@ int npc_cn20k_apply_custom_kpu(struct rvu *rvu, } =20 /* Verify if profile fits the HW */ + if (fw->kpus > rvu->hw->npc_kpus) { + dev_warn(rvu->dev, "Not enough KPUs: %d > %d\n", fw->kpus, + rvu->hw->npc_kpus); + return -EINVAL; + } + + /* Check if there is enough memory */ if (fw->kpus > profile->kpus) { - dev_warn(rvu->dev, "Not enough KPUs: %d > %ld\n", fw->kpus, + dev_warn(rvu->dev, "Not enough KPUs: %d > %zu\n", fw->kpus, profile->kpus); return -EINVAL; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/= ethernet/marvell/octeontx2/af/npc.h index 2138c044fe41..eaed172f1606 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h @@ -267,6 +267,19 @@ struct npc_kpu_profile_cam { u16 dp2_mask; } __packed; =20 +struct npc_kpu_profile_cam2 { + u8 state; + u8 state_mask; + u16 dp0; + u16 dp0_mask; + u16 dp1; + u16 dp1_mask; + u16 dp2; + u16 dp2_mask; + u8 ptype; + u8 ptype_mask; +} __packed; + struct npc_kpu_profile_action { u8 errlev; u8 errcode; @@ -292,6 +305,10 @@ struct npc_kpu_profile { int action_entries; struct npc_kpu_profile_cam *cam; struct npc_kpu_profile_action *action; + int cam_entries2; + int action_entries2; + struct npc_kpu_profile_action *action2; + struct npc_kpu_profile_cam2 *cam2; }; =20 /* NPC KPU register formats */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.h index 65397daae4c2..7f3505ae6860 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -553,17 +553,19 @@ struct npc_kpu_profile_adapter { const char *name; u64 version; const struct npc_lt_def_cfg *lt_def; - const struct npc_kpu_profile_action *ikpu; /* array[pkinds] */ - const struct npc_kpu_profile *kpu; /* array[kpus] */ + struct npc_kpu_profile_action *ikpu; /* array[pkinds] */ + struct npc_kpu_profile_action *ikpu2; /* array[pkinds] */ + struct npc_kpu_profile *kpu; /* array[kpus] */ union npc_mcam_key_prfl { - struct npc_mcam_kex *mkex; + const struct npc_mcam_kex *mkex; /* used for cn9k and cn10k */ - struct npc_mcam_kex_extr *mkex_extr; /* used for cn20k */ + const struct npc_mcam_kex_extr *mkex_extr; /* used for cn20k */ } mcam_kex_prfl; struct npc_mcam_kex_hash *mkex_hash; bool custom; size_t pkinds; size_t kpus; + bool from_fs; }; =20 #define RVU_SWITCH_LBK_CHAN 63 @@ -634,7 +636,7 @@ struct rvu { =20 /* Firmware data */ struct rvu_fwdata *fwdata; - void *kpu_fwdata; + const void *kpu_fwdata; size_t kpu_fwdata_sz; void __iomem *kpu_prfl_addr; =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_npc.c index 150d50b72c48..b4635d78f9d5 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -1495,7 +1495,8 @@ void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 p= cifunc, int nixlf) } =20 static void npc_program_mkex_rx(struct rvu *rvu, int blkaddr, - struct npc_mcam_kex *mkex, u8 intf) + const struct npc_mcam_kex *mkex, + u8 intf) { int lid, lt, ld, fl; =20 @@ -1524,7 +1525,8 @@ static void npc_program_mkex_rx(struct rvu *rvu, int = blkaddr, } =20 static void npc_program_mkex_tx(struct rvu *rvu, int blkaddr, - struct npc_mcam_kex *mkex, u8 intf) + const struct npc_mcam_kex *mkex, + u8 intf) { int lid, lt, ld, fl; =20 @@ -1553,7 +1555,7 @@ static void npc_program_mkex_tx(struct rvu *rvu, int = blkaddr, } =20 static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr, - struct npc_mcam_kex *mkex) + const struct npc_mcam_kex *mkex) { struct rvu_hwinfo *hw =3D rvu->hw; u8 intf; @@ -1693,8 +1695,12 @@ static void npc_config_kpucam(struct rvu *rvu, int b= lkaddr, const struct npc_kpu_profile_cam *kpucam, int kpu, int entry) { + const struct npc_kpu_profile_cam2 *kpucam2 =3D (void *)kpucam; + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; struct npc_kpu_cam cam0 =3D {0}; struct npc_kpu_cam cam1 =3D {0}; + u64 *val =3D (u64 *)&cam1; + u64 *mask =3D (u64 *)&cam0; =20 cam1.state =3D kpucam->state & kpucam->state_mask; cam1.dp0_data =3D kpucam->dp0 & kpucam->dp0_mask; @@ -1706,6 +1712,14 @@ static void npc_config_kpucam(struct rvu *rvu, int b= lkaddr, cam0.dp1_data =3D ~kpucam->dp1 & kpucam->dp1_mask; cam0.dp2_data =3D ~kpucam->dp2 & kpucam->dp2_mask; =20 + if (profile->from_fs) { + u8 ptype =3D kpucam2->ptype; + u8 pmask =3D kpucam2->ptype_mask; + + *val |=3D FIELD_PREP(GENMASK_ULL(57, 56), ptype & pmask); + *mask |=3D FIELD_PREP(GENMASK_ULL(57, 56), ~ptype & pmask); + } + rvu_write64(rvu, blkaddr, NPC_AF_KPUX_ENTRYX_CAMX(kpu, entry, 0), *(u64 *)&cam0); rvu_write64(rvu, blkaddr, @@ -1717,34 +1731,104 @@ u64 npc_enable_mask(int count) return (((count) < 64) ? ~(BIT_ULL(count) - 1) : (0x00ULL)); } =20 +struct npc_kpu_profile_action * +npc_get_ikpu_nth_entry(struct rvu *rvu, int n) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + + if (profile->from_fs) + return &profile->ikpu2[n]; + + return &profile->ikpu[n]; +} + +int +npc_get_num_kpu_cam_entries(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + + if (profile->from_fs) + return kpu_pfl->cam_entries2; + + return kpu_pfl->cam_entries; +} + +struct npc_kpu_profile_cam * +npc_get_kpu_cam_nth_entry(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl, int n) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + + if (profile->from_fs) + return (void *)&kpu_pfl->cam2[n]; + + return (void *)&kpu_pfl->cam[n]; +} + +int +npc_get_num_kpu_action_entries(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + + if (profile->from_fs) + return kpu_pfl->action_entries2; + + return kpu_pfl->action_entries; +} + +struct npc_kpu_profile_action * +npc_get_kpu_action_nth_entry(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl, + int n) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + + if (profile->from_fs) + return (void *)&kpu_pfl->action2[n]; + + return (void *)&kpu_pfl->action[n]; +} + static void npc_program_kpu_profile(struct rvu *rvu, int blkaddr, int kpu, const struct npc_kpu_profile *profile) { + int num_cam_entries, num_action_entries; int entry, num_entries, max_entries; u64 entry_mask; =20 - if (profile->cam_entries !=3D profile->action_entries) { + num_cam_entries =3D npc_get_num_kpu_cam_entries(rvu, profile); + num_action_entries =3D npc_get_num_kpu_action_entries(rvu, profile); + + if (num_cam_entries !=3D num_action_entries) { dev_err(rvu->dev, "KPU%d: CAM and action entries [%d !=3D %d] not equal\n", - kpu, profile->cam_entries, profile->action_entries); + kpu, num_cam_entries, num_action_entries); } =20 max_entries =3D rvu->hw->npc_kpu_entries; =20 + WARN(num_cam_entries > max_entries, + "KPU%u: err: hw max entries=3D%u, input entries=3D%u\n", + kpu, rvu->hw->npc_kpu_entries, num_cam_entries); + /* Program CAM match entries for previous KPU extracted data */ - num_entries =3D min_t(int, profile->cam_entries, max_entries); + num_entries =3D min_t(int, num_cam_entries, max_entries); for (entry =3D 0; entry < num_entries; entry++) npc_config_kpucam(rvu, blkaddr, - &profile->cam[entry], kpu, entry); + (void *)npc_get_kpu_cam_nth_entry(rvu, profile, entry), + kpu, entry); =20 /* Program this KPU's actions */ - num_entries =3D min_t(int, profile->action_entries, max_entries); + num_entries =3D min_t(int, num_action_entries, max_entries); for (entry =3D 0; entry < num_entries; entry++) - npc_config_kpuaction(rvu, blkaddr, &profile->action[entry], + npc_config_kpuaction(rvu, blkaddr, + (void *)npc_get_kpu_action_nth_entry(rvu, profile, entry), kpu, entry, false); =20 /* Enable all programmed entries */ - num_entries =3D min_t(int, profile->action_entries, profile->cam_entries); + num_entries =3D min_t(int, num_action_entries, num_cam_entries); entry_mask =3D npc_enable_mask(num_entries); /* Disable first KPU_MAX_CST_ENT entries for built-in profile */ if (!rvu->kpu.custom) @@ -1788,26 +1872,175 @@ static void npc_prepare_default_kpu(struct rvu *rv= u, npc_cn20k_update_action_entries_n_flags(rvu, profile); } =20 -static int npc_apply_custom_kpu(struct rvu *rvu, - struct npc_kpu_profile_adapter *profile) +static int npc_alloc_kpu_cam2_n_action2(struct rvu *rvu, int kpu_num, + int num_entries) +{ + struct npc_kpu_profile_adapter *adapter =3D &rvu->kpu; + struct npc_kpu_profile *kpu; + + kpu =3D &adapter->kpu[kpu_num]; + + kpu->cam2 =3D devm_kcalloc(rvu->dev, num_entries, + sizeof(*kpu->cam2), GFP_KERNEL); + if (!kpu->cam2) + return -ENOMEM; + + kpu->action2 =3D devm_kcalloc(rvu->dev, num_entries, + sizeof(*kpu->action2), GFP_KERNEL); + if (!kpu->action2) + return -ENOMEM; + + return 0; +} + +static int npc_apply_custom_kpu_from_fw(struct rvu *rvu, + struct npc_kpu_profile_adapter *profile) { size_t hdr_sz =3D sizeof(struct npc_kpu_profile_fwdata), offset =3D 0; + const struct npc_kpu_profile_fwdata *fw; struct npc_kpu_profile_action *action; - struct npc_kpu_profile_fwdata *fw; struct npc_kpu_profile_cam *cam; struct npc_kpu_fwdata *fw_kpu; - int entries; - u16 kpu, entry; + int entries, entry, kpu; =20 - if (is_cn20k(rvu->pdev)) - return npc_cn20k_apply_custom_kpu(rvu, profile); + fw =3D rvu->kpu_fwdata; + + for (kpu =3D 0; kpu < fw->kpus; kpu++) { + if (rvu->kpu_fwdata_sz < hdr_sz + offset) { + dev_warn(rvu->dev, + "Profile size mismatch on KPU%i parsing\n", + kpu + 1); + return -EINVAL; + } + + fw_kpu =3D (struct npc_kpu_fwdata *)(fw->data + offset); + if (fw_kpu->entries < 0) { + dev_warn(rvu->dev, + "Profile entries is negative on KPU%i parsing\n", + kpu + 1); + return -EINVAL; + } + + if (fw_kpu->entries > KPU_MAX_CST_ENT) + dev_warn(rvu->dev, + "Too many custom entries on KPU%d: %d > %d\n", + kpu, fw_kpu->entries, KPU_MAX_CST_ENT); + entries =3D min_t(int, fw_kpu->entries, KPU_MAX_CST_ENT); + cam =3D (struct npc_kpu_profile_cam *)fw_kpu->data; + offset +=3D sizeof(*fw_kpu) + fw_kpu->entries * sizeof(*cam); + action =3D (struct npc_kpu_profile_action *)(fw->data + offset); + offset +=3D fw_kpu->entries * sizeof(*action); + if (rvu->kpu_fwdata_sz < hdr_sz + offset) { + dev_warn(rvu->dev, + "Profile size mismatch on KPU%i parsing.\n", + kpu + 1); + return -EINVAL; + } + for (entry =3D 0; entry < entries; entry++) { + profile->kpu[kpu].cam[entry] =3D cam[entry]; + profile->kpu[kpu].action[entry] =3D action[entry]; + } + } + + return 0; +} + +static int npc_apply_custom_kpu_from_fs(struct rvu *rvu, + struct npc_kpu_profile_adapter *profile) +{ + size_t hdr_sz =3D sizeof(struct npc_kpu_profile_fwdata), offset =3D 0; + const struct npc_kpu_profile_fwdata *fw; + struct npc_kpu_profile_action *action; + struct npc_kpu_profile_cam2 *cam2; + struct npc_kpu_fwdata *fw_kpu; + int entries, ret, entry, kpu; =20 fw =3D rvu->kpu_fwdata; =20 + /* Binary blob contains ikpu actions entries at start of data[0] */ + profile->ikpu2 =3D devm_kcalloc(rvu->dev, 1, + sizeof(ikpu_action_entries), + GFP_KERNEL); + if (!profile->ikpu2) + return -ENOMEM; + + action =3D (struct npc_kpu_profile_action *)(fw->data + offset); + + if (rvu->kpu_fwdata_sz < hdr_sz + sizeof(ikpu_action_entries)) + return -EINVAL; + + /* The firmware layout does dependent on the internal size of + * ikpu_action_entries. + */ + memcpy((void *)profile->ikpu2, action, sizeof(ikpu_action_entries)); + offset +=3D sizeof(ikpu_action_entries); + + for (kpu =3D 0; kpu < fw->kpus; kpu++) { + if (rvu->kpu_fwdata_sz < hdr_sz + offset + sizeof(*fw_kpu)) { + dev_warn(rvu->dev, + "profile size mismatch on kpu%i parsing\n", + kpu + 1); + return -EINVAL; + } + + fw_kpu =3D (struct npc_kpu_fwdata *)(fw->data + offset); + if (fw_kpu->entries <=3D 0) { + dev_warn(rvu->dev, + "Invalid kpu entries on KPU%d\n", kpu); + return -EINVAL; + } + + entries =3D min_t(int, fw_kpu->entries, rvu->hw->npc_kpu_entries); + dev_info(rvu->dev, + "Loading %u entries on KPU%d\n", entries, kpu); + + cam2 =3D (struct npc_kpu_profile_cam2 *)fw_kpu->data; + offset +=3D sizeof(*fw_kpu) + fw_kpu->entries * sizeof(*cam2); + action =3D (struct npc_kpu_profile_action *)(fw->data + offset); + offset +=3D fw_kpu->entries * sizeof(*action); + if (rvu->kpu_fwdata_sz < hdr_sz + offset) { + dev_warn(rvu->dev, + "profile size mismatch on kpu%i parsing.\n", + kpu + 1); + return -EINVAL; + } + + profile->kpu[kpu].cam_entries2 =3D entries; + profile->kpu[kpu].action_entries2 =3D entries; + ret =3D npc_alloc_kpu_cam2_n_action2(rvu, kpu, entries); + if (ret) { + dev_warn(rvu->dev, + "profile entry allocation failed for kpu=3D%d for %d entries\n", + kpu, entries); + return -EINVAL; + } + + for (entry =3D 0; entry < entries; entry++) { + profile->kpu[kpu].cam2[entry] =3D cam2[entry]; + profile->kpu[kpu].action2[entry] =3D action[entry]; + } + } + + return 0; +} + +static int npc_apply_custom_kpu(struct rvu *rvu, + struct npc_kpu_profile_adapter *profile, + bool from_fs, int *fw_kpus) +{ + size_t hdr_sz =3D sizeof(struct npc_kpu_profile_fwdata); + const struct npc_kpu_profile_fwdata *fw; + struct npc_kpu_profile_fwdata *sfw; + + if (is_cn20k(rvu->pdev)) + return npc_cn20k_apply_custom_kpu(rvu, profile); + if (rvu->kpu_fwdata_sz < hdr_sz) { dev_warn(rvu->dev, "Invalid KPU profile size\n"); return -EINVAL; } + + fw =3D rvu->kpu_fwdata; if (le64_to_cpu(fw->signature) !=3D KPU_SIGN) { dev_warn(rvu->dev, "Invalid KPU profile signature %llx\n", fw->signature); @@ -1835,42 +2068,38 @@ static int npc_apply_custom_kpu(struct rvu *rvu, return -EINVAL; } /* Verify if profile fits the HW */ + if (fw->kpus > rvu->hw->npc_kpus) { + dev_warn(rvu->dev, "Not enough KPUs: %d > %d\n", fw->kpus, + rvu->hw->npc_kpus); + return -EINVAL; + } + + /* Check if there is enough memory for fw loading. + * Check if there is enough entries for profile->kpu[] to + * set cam_entries2 and action_entries2 + */ if (fw->kpus > profile->kpus) { - dev_warn(rvu->dev, "Not enough KPUs: %d > %ld\n", fw->kpus, + dev_warn(rvu->dev, "Not enough KPUs: %d > %zu\n", fw->kpus, profile->kpus); return -EINVAL; } =20 + *fw_kpus =3D fw->kpus; + + sfw =3D devm_kcalloc(rvu->dev, 1, sizeof(*sfw), GFP_KERNEL); + if (!sfw) + return -ENOMEM; + + memcpy(sfw, fw, sizeof(*sfw)); + profile->custom =3D 1; - profile->name =3D fw->name; + profile->name =3D sfw->name; profile->version =3D le64_to_cpu(fw->version); - profile->mcam_kex_prfl.mkex =3D &fw->mkex; - profile->lt_def =3D &fw->lt_def; - - for (kpu =3D 0; kpu < fw->kpus; kpu++) { - fw_kpu =3D (struct npc_kpu_fwdata *)(fw->data + offset); - if (fw_kpu->entries > KPU_MAX_CST_ENT) - dev_warn(rvu->dev, - "Too many custom entries on KPU%d: %d > %d\n", - kpu, fw_kpu->entries, KPU_MAX_CST_ENT); - entries =3D min(fw_kpu->entries, KPU_MAX_CST_ENT); - cam =3D (struct npc_kpu_profile_cam *)fw_kpu->data; - offset +=3D sizeof(*fw_kpu) + fw_kpu->entries * sizeof(*cam); - action =3D (struct npc_kpu_profile_action *)(fw->data + offset); - offset +=3D fw_kpu->entries * sizeof(*action); - if (rvu->kpu_fwdata_sz < hdr_sz + offset) { - dev_warn(rvu->dev, - "Profile size mismatch on KPU%i parsing.\n", - kpu + 1); - return -EINVAL; - } - for (entry =3D 0; entry < entries; entry++) { - profile->kpu[kpu].cam[entry] =3D cam[entry]; - profile->kpu[kpu].action[entry] =3D action[entry]; - } - } + profile->mcam_kex_prfl.mkex =3D &sfw->mkex; + profile->lt_def =3D &sfw->lt_def; =20 - return 0; + return from_fs ? npc_apply_custom_kpu_from_fs(rvu, profile) : + npc_apply_custom_kpu_from_fw(rvu, profile); } =20 static int npc_load_kpu_prfl_img(struct rvu *rvu, void __iomem *prfl_addr, @@ -1958,45 +2187,19 @@ static int npc_load_kpu_profile_fwdb(struct rvu *rv= u, const char *kpu_profile) return ret; } =20 -void npc_load_kpu_profile(struct rvu *rvu) +static int npc_load_kpu_profile_from_fw(struct rvu *rvu) { struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; const char *kpu_profile =3D rvu->kpu_pfl_name; - const struct firmware *fw =3D NULL; - bool retry_fwdb =3D false; - - /* If user not specified profile customization */ - if (!strncmp(kpu_profile, def_pfl_name, KPU_NAME_LEN)) - goto revert_to_default; - /* First prepare default KPU, then we'll customize top entries. */ - npc_prepare_default_kpu(rvu, profile); - - /* Order of preceedence for load loading NPC profile (high to low) - * Firmware binary in filesystem. - * Firmware database method. - * Default KPU profile. - */ - if (!request_firmware_direct(&fw, kpu_profile, rvu->dev)) { - dev_info(rvu->dev, "Loading KPU profile from firmware: %s\n", - kpu_profile); - rvu->kpu_fwdata =3D kzalloc(fw->size, GFP_KERNEL); - if (rvu->kpu_fwdata) { - memcpy(rvu->kpu_fwdata, fw->data, fw->size); - rvu->kpu_fwdata_sz =3D fw->size; - } - release_firmware(fw); - retry_fwdb =3D true; - goto program_kpu; - } + int fw_kpus =3D 0; =20 -load_image_fwdb: /* Loading the KPU profile using firmware database */ if (npc_load_kpu_profile_fwdb(rvu, kpu_profile)) - goto revert_to_default; + return -EFAULT; =20 -program_kpu: /* Apply profile customization if firmware was loaded. */ - if (!rvu->kpu_fwdata_sz || npc_apply_custom_kpu(rvu, profile)) { + if (!rvu->kpu_fwdata_sz || + npc_apply_custom_kpu(rvu, profile, false, &fw_kpus)) { /* If image from firmware filesystem fails to load or invalid * retry with firmware database method. */ @@ -2010,10 +2213,6 @@ void npc_load_kpu_profile(struct rvu *rvu) } rvu->kpu_fwdata =3D NULL; rvu->kpu_fwdata_sz =3D 0; - if (retry_fwdb) { - retry_fwdb =3D false; - goto load_image_fwdb; - } } =20 dev_warn(rvu->dev, @@ -2021,22 +2220,101 @@ void npc_load_kpu_profile(struct rvu *rvu) kpu_profile); kfree(rvu->kpu_fwdata); rvu->kpu_fwdata =3D NULL; - goto revert_to_default; + return -EFAULT; } =20 - dev_info(rvu->dev, "Using custom profile '%s', version %d.%d.%d\n", + dev_info(rvu->dev, "Using custom profile '%.32s', version %d.%d.%d\n", profile->name, NPC_KPU_VER_MAJ(profile->version), NPC_KPU_VER_MIN(profile->version), NPC_KPU_VER_PATCH(profile->version)); =20 - return; + return 0; +} + +static int npc_load_kpu_profile_from_fs(struct rvu *rvu) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + const char *kpu_profile =3D rvu->kpu_pfl_name; + const struct firmware *fw =3D NULL; + int ret, fw_kpus =3D 0; + char path[512] =3D "kpu/"; + + if (strlen(kpu_profile) > sizeof(path) - strlen("kpu/") - 1) { + dev_err(rvu->dev, "kpu profile name is too big\n"); + return -ENOSPC; + } + + strcat(path, kpu_profile); + + if (request_firmware_direct(&fw, path, rvu->dev)) + return -ENOENT; + + dev_info(rvu->dev, "Loading KPU profile from filesystem: %s\n", + path); + + rvu->kpu_fwdata =3D fw->data; + rvu->kpu_fwdata_sz =3D fw->size; + + ret =3D npc_apply_custom_kpu(rvu, profile, true, &fw_kpus); + release_firmware(fw); + rvu->kpu_fwdata =3D NULL; + + if (ret) { + rvu->kpu_fwdata_sz =3D 0; + dev_err(rvu->dev, + "Loading KPU profile from filesystem failed\n"); + return ret; + } + + /* In firmware loading from filesystem method, all entries are from + * same binary blob. + */ + rvu->kpu.kpus =3D fw_kpus; + profile->kpus =3D fw_kpus; + profile->from_fs =3D true; + return 0; +} + +void npc_load_kpu_profile(struct rvu *rvu) +{ + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; + const char *kpu_profile =3D rvu->kpu_pfl_name; + + profile->from_fs =3D false; + + npc_prepare_default_kpu(rvu, profile); + + /* If user not specified profile customization */ + if (!strncmp(kpu_profile, def_pfl_name, KPU_NAME_LEN)) + return; + + /* Order of preceedence for load loading NPC profile (high to low) + * Firmware binary in filesystem. + * Firmware database method. + * Default KPU profile. + */ + + /* Filesystem-based KPU loading is not supported on cn20k. + * npc_prepare_default_kpu() was invoked earlier, but control + * reached this point because the default profile was not selected. + * No need to call it again. + */ + if (!is_cn20k(rvu->pdev)) { + if (!npc_load_kpu_profile_from_fs(rvu)) + return; + } + + /* First prepare default KPU, then we'll customize top entries. */ + npc_prepare_default_kpu(rvu, profile); + if (!npc_load_kpu_profile_from_fw(rvu)) + return; =20 -revert_to_default: npc_prepare_default_kpu(rvu, profile); } =20 static void npc_parser_profile_init(struct rvu *rvu, int blkaddr) { + struct npc_kpu_profile_adapter *profile =3D &rvu->kpu; struct rvu_hwinfo *hw =3D rvu->hw; int num_pkinds, num_kpus, idx; =20 @@ -2060,7 +2338,9 @@ static void npc_parser_profile_init(struct rvu *rvu, = int blkaddr) num_pkinds =3D min_t(int, hw->npc_pkinds, num_pkinds); =20 for (idx =3D 0; idx < num_pkinds; idx++) - npc_config_kpuaction(rvu, blkaddr, &rvu->kpu.ikpu[idx], 0, idx, true); + npc_config_kpuaction(rvu, blkaddr, + npc_get_ikpu_nth_entry(rvu, idx), + 0, idx, true); =20 /* Program KPU CAM and Action profiles */ num_kpus =3D rvu->kpu.kpus; @@ -2068,6 +2348,11 @@ static void npc_parser_profile_init(struct rvu *rvu,= int blkaddr) =20 for (idx =3D 0; idx < num_kpus; idx++) npc_program_kpu_profile(rvu, blkaddr, idx, &rvu->kpu.kpu[idx]); + + if (profile->from_fs) { + rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_TYPE(54), 0x03); + rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_TYPE(58), 0x03); + } } =20 void npc_mcam_rsrcs_deinit(struct rvu *rvu) @@ -2297,18 +2582,21 @@ static void rvu_npc_hw_init(struct rvu *rvu, int bl= kaddr) =20 static void rvu_npc_setup_interfaces(struct rvu *rvu, int blkaddr) { - struct npc_mcam_kex_extr *mkex_extr =3D rvu->kpu.mcam_kex_prfl.mkex_extr; - struct npc_mcam_kex *mkex =3D rvu->kpu.mcam_kex_prfl.mkex; + const struct npc_mcam_kex_extr *mkex_extr; struct npc_mcam *mcam =3D &rvu->hw->mcam; struct rvu_hwinfo *hw =3D rvu->hw; + const struct npc_mcam_kex *mkex; u64 nibble_ena, rx_kex, tx_kex; u64 *keyx_cfg, reg; u8 intf; =20 + mkex_extr =3D rvu->kpu.mcam_kex_prfl.mkex_extr; + mkex =3D rvu->kpu.mcam_kex_prfl.mkex; + if (is_cn20k(rvu->pdev)) { - keyx_cfg =3D mkex_extr->keyx_cfg; + keyx_cfg =3D (u64 *)mkex_extr->keyx_cfg; } else { - keyx_cfg =3D mkex->keyx_cfg; + keyx_cfg =3D (u64 *)mkex->keyx_cfg; /* Reserve last counter for MCAM RX miss action which is set to * drop packet. This way we will know how many pkts didn't * match any MCAM entry. diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.h b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_npc.h index 83c5e32e2afc..662f6693cfe9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.h @@ -18,4 +18,21 @@ int npc_fwdb_prfl_img_map(struct rvu *rvu, void __iomem = **prfl_img_addr, =20 void npc_mcam_clear_bit(struct npc_mcam *mcam, u16 index); void npc_mcam_set_bit(struct npc_mcam *mcam, u16 index); + +struct npc_kpu_profile_action * +npc_get_ikpu_nth_entry(struct rvu *rvu, int n); + +int +npc_get_num_kpu_cam_entries(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl); +struct npc_kpu_profile_cam * +npc_get_kpu_cam_nth_entry(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl, int n); + +int +npc_get_num_kpu_action_entries(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl); +struct npc_kpu_profile_action * +npc_get_kpu_action_nth_entry(struct rvu *rvu, + const struct npc_kpu_profile *kpu_pfl, int n); #endif /* RVU_NPC_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/= net/ethernet/marvell/octeontx2/af/rvu_reg.h index 62cdc714ba57..ab89b8c6e490 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h @@ -596,6 +596,7 @@ #define NPC_AF_INTFX_KEX_CFG(a) (0x01010 | (a) << 8) #define NPC_AF_PKINDX_ACTION0(a) (0x80000ull | (a) << 6) #define NPC_AF_PKINDX_ACTION1(a) (0x80008ull | (a) << 6) +#define NPC_AF_PKINDX_TYPE(a) (0x80010ull | (a) << 6) #define NPC_AF_PKINDX_CPI_DEFX(a, b) (0x80020ull | (a) << 6 | (b) << 3) #define NPC_AF_KPUX_ENTRYX_CAMX(a, b, c) \ (0x100000 | (a) << 14 | (b) << 6 | (c) << 3) --=20 2.43.0 From nobody Mon Jun 8 04:25:13 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 7C1B144D68A; Fri, 5 Jun 2026 07:04:36 +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=1780643081; cv=none; b=iffJhOc7vS9G3SzCAHHSYDCIBg7MgS1o3dxY7TgyoivzGIMRqAyGGel8r5NxvqdjmSGTc68Y0qn5AW5CHqR/Zz24fwPbhrWLklk6je8YqSnIrcpu2adXLAw8FX2LQWBb1LeIJTDUR6k1NQT+s77nFS0pHwYmNQt4aQhS1nG1A6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780643081; c=relaxed/simple; bh=jQuojE6Pd6dEdxS9m/VxSCN7wNukWXM1Snhn+bcANLg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=O4qLZpRu4oliTCd2Y6m3F7LDseQetrpm7zm4an8brno1Fsf92of3oQB1VtcY5p4Fg/vjz18WsqVePG3EA0XTdLRngE/IQlQCIJsFlRG+yteKqFFq7kRFjfq07e+YjL0NhkvjSCxmKwt7yMDwC16GFCyuta6kluo19zKYtyeJYa4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=bw+9GiMi; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="bw+9GiMi" 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 654LQMGq3892390; Fri, 5 Jun 2026 00:04:27 -0700 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=y OjoTYfizbwAhVUXVgZxBzdXn60ookjAmORafR9UyZA=; b=bw+9GiMiAIN/tDTvj uGUkUfwfWAUBBUaBACvI1rohiwCToAHhiEgcijftMFje3+yI0awy5YYvcTaCFF+v TWjWZBt+EkSk1N7oSXtMpAFqginTpJn72ITchyvarBxK005YKW5XMJZCYhM4MN5T WYRuB1tY6JgdX8ASTJ9+YloaU4IyOO1OjNrcW4ceyWJ1236hI96Ez/pLUFEB/a/E FdeTC/uAUPydGMtb7ev8omrvUWmQQoabI+UvYEwNkxmFyK0YawdsWBqODf8sxLiL U8GOezxXA93G+SzQ5erzQRvfqLaaLJb+/OQAV8NMJW3iWZE7lxcXyTVrqJA/iihI pyHgw== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekh8x9e58-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 05 Jun 2026 00:04:26 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.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; Fri, 5 Jun 2026 00:02:54 -0700 Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Thu, 4 Jun 2026 23:33:35 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Thu, 4 Jun 2026 23:33:35 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 6C2A23F7074; Thu, 4 Jun 2026 23:33:31 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 8/9] octeontx2: cn20k: Respect NPC MCAM X2/X4 profile in flows and DFT alloc Date: Fri, 5 Jun 2026 12:02:44 +0530 Message-ID: <20260605063245.3553861-9-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-ORIG-GUID: p10t9Tquq4waE593WucdI8BYYThx306h X-Authority-Analysis: v=2.4 cv=DqNmPm/+ c=1 sm=1 tr=0 ts=6a2274fa cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=M5GUcnROAAAA:8 a=3zpKOMqohp-RhpYd6ikA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2NiBTYWx0ZWRfX/mRGk2fFe7Wx eqf5ZSUHjPIpKwlOjevuMomRnBWRT0zZus8ouIW5dwoIAuOr6cA/Cwj2dEs2nSNrkEjq1m1ZE+6 Rlzmhi4SpnVibVsftOfNfd0B1pv4V7x4d/BR8GuAZTKYmsuzb1drW0tnsCidqVFIab9UR2AvipU iXaeKEPWRACVm4Mct/XWOGUgITuPPsrovq0HRNSgb88su4VdhFR4ckc5QozQxP9eSFCAS8l2uIO DR0BMRn/k0qDjt/A1/I9xmdYPfcvz50jChCt1GXYyDuIf2jhWxqQZqnwFJBSTYLhD6bPHIa8Trx Zrwq3IKAvnV4GMMIl1dGKxdKNJMMaP7jdUO75O9gLwW1mqA6uIlXfg7f13ulc2YmnmMTyTJ65j5 ezFd5OLPzwx1tFAucFfs/Sw73fpLtgepe2kcE9F6wYOnB83WInM6ITDvbGlTeObnno2/x1VbunJ WZMrDdSWAMNH8GZIV6A== X-Proofpoint-GUID: p10t9Tquq4waE593WucdI8BYYThx306h X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Default CN20K NPC rule allocation now keys off the active MCAM keyword width: use X4 with a bank-masked reference index when the silicon uses X4 keys, and X2 with the raw index otherwise (replacing the previous always-X2 / eidx + 1 behaviour). In the AF flow-install path, flows that need more than 256 key bits query the NPC profile; if the platform is fixed to X2 entries, fail with -EOPNOTSUPP instead of requesting X4. Otherwise select X4 for the MCAM alloc. On the PF, cache and pass the profile kw_type from npc_get_pfl_info through otx2_mcam_pfl_info_get(), and use it when allocating MCAM entries for RSS/defaults and when installing ethtool flows on CN20K, including masking the reference index for X4 slot layout. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 21 ++++++-- .../marvell/octeontx2/af/rvu_npc_fs.c | 12 ++++- .../marvell/octeontx2/nic/otx2_flows.c | 48 +++++++++++++------ 3 files changed, 61 insertions(+), 20 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 32b53b5bc57a..d76aad867934 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -4500,10 +4500,16 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 = pcifunc) pfvf =3D rvu_get_pfvf(rvu, pcifunc); pfvf->hw_prio =3D NPC_DFT_RULE_PRIO; =20 + if (npc_priv.kw =3D=3D NPC_MCAM_KEY_X4) { + req.kw_type =3D NPC_MCAM_KEY_X4; + req.ref_entry =3D eidx & (npc_priv.bank_depth - 1); + } else { + req.kw_type =3D NPC_MCAM_KEY_X2; + req.ref_entry =3D eidx; + } + 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; =20 @@ -4533,11 +4539,18 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 = pcifunc) * 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; + + if (npc_priv.kw =3D=3D NPC_MCAM_KEY_X4) { + req.kw_type =3D NPC_MCAM_KEY_X4; + req.ref_entry =3D eidx & (npc_priv.bank_depth - 1); + } else { + req.kw_type =3D NPC_MCAM_KEY_X2; + req.ref_entry =3D eidx; + } + ret =3D rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &req, &rsp); if (ret) { dev_err(rvu->dev, diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drive= rs/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c index 34f1e066707b..a22decbe3449 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -1671,9 +1671,11 @@ rvu_npc_alloc_entry_for_flow_install(struct rvu *rvu, { struct npc_mcam_alloc_entry_req entry_req; struct npc_mcam_alloc_entry_rsp entry_rsp; + struct npc_get_pfl_info_rsp rsp =3D { 0 }; struct npc_get_num_kws_req kws_req; struct npc_get_num_kws_rsp kws_rsp; int off, kw_bits, rc; + struct msg_req req; u8 *src, *dst; =20 if (!is_cn20k(rvu->pdev)) { @@ -1697,8 +1699,16 @@ rvu_npc_alloc_entry_for_flow_install(struct rvu *rvu, kw_bits =3D kws_rsp.kws * 64; =20 *kw_type =3D NPC_MCAM_KEY_X2; - if (kw_bits > 256) + if (kw_bits > 256) { + rvu_mbox_handler_npc_get_pfl_info(rvu, &req, &rsp); + if (rsp.kw_type =3D=3D NPC_MCAM_KEY_X2) { + dev_err(rvu->dev, + "Only X2 entries are supported in X2 profile\n"); + return -EOPNOTSUPP; + } + *kw_type =3D NPC_MCAM_KEY_X4; + } =20 memset(&entry_req, 0, sizeof(entry_req)); memset(&entry_rsp, 0, sizeof(entry_rsp)); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/driv= ers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 38cc539d724d..5dd0591fed99 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -37,14 +37,13 @@ static void otx2_clear_ntuple_flow_info(struct otx2_nic= *pfvf, struct otx2_flow_ flow_cfg->max_flows =3D 0; } =20 -static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, bool *is_x2, - u16 *x4_slots) +static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, u16 *x4_slots, u8= *kw_type) { struct npc_get_pfl_info_rsp *rsp; struct msg_req *req; static struct { bool is_set; - bool is_x2; + u8 kw_type; u16 x4_slots; } pfl_info; =20 @@ -53,8 +52,8 @@ static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, = bool *is_x2, */ mutex_lock(&pfvf->mbox.lock); if (pfl_info.is_set) { - *is_x2 =3D pfl_info.is_x2; *x4_slots =3D pfl_info.x4_slots; + *kw_type =3D pfl_info.kw_type; mutex_unlock(&pfvf->mbox.lock); return 0; } @@ -79,16 +78,16 @@ static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf= , bool *is_x2, return -EFAULT; } =20 - *is_x2 =3D (rsp->kw_type =3D=3D NPC_MCAM_KEY_X2); - if (*is_x2) - *x4_slots =3D 0; + pfl_info.kw_type =3D rsp->kw_type; + if (rsp->kw_type =3D=3D NPC_MCAM_KEY_X2) + pfl_info.x4_slots =3D 0; else - *x4_slots =3D rsp->x4_slots; - - pfl_info.is_x2 =3D *is_x2; - pfl_info.x4_slots =3D *x4_slots; + pfl_info.x4_slots =3D rsp->x4_slots; pfl_info.is_set =3D true; =20 + *x4_slots =3D pfl_info.x4_slots; + *kw_type =3D pfl_info.kw_type; + mutex_unlock(&pfvf->mbox.lock); return 0; } @@ -164,6 +163,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 = count) u16 dft_idx =3D 0, x4_slots =3D 0; int ent, allocated =3D 0, ref; bool is_x2 =3D false; + u8 kw_type =3D 0; int rc; =20 /* Free current ones and allocate new ones with requested count */ @@ -182,12 +182,14 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u1= 6 count) } =20 if (is_cn20k(pfvf->pdev)) { - rc =3D otx2_mcam_pfl_info_get(pfvf, &is_x2, &x4_slots); + rc =3D otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type); if (rc) { netdev_err(pfvf->netdev, "Error to retrieve profile info\n"); return rc; } =20 + is_x2 =3D kw_type =3D=3D NPC_MCAM_KEY_X2; + rc =3D otx2_get_dft_rl_idx(pfvf, &dft_idx); if (rc) { netdev_err(pfvf->netdev, @@ -289,6 +291,8 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf) struct npc_mcam_alloc_entry_rsp *rsp; int vf_vlan_max_flows, count; int rc, ref, prio, ent; + u8 kw_type =3D 0; + u16 x4_slots; u16 dft_idx; =20 ref =3D 0; @@ -315,6 +319,16 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf) if (!flow_cfg->def_ent) return -ENOMEM; =20 + kw_type =3D NPC_MCAM_KEY_X2; + if (is_cn20k(pfvf->pdev)) { + rc =3D otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type); + if (rc) { + netdev_err(pfvf->netdev, + "Error to get pfl info\n"); + return rc; + } + } + mutex_lock(&pfvf->mbox.lock); =20 req =3D otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox); @@ -324,6 +338,10 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf) } =20 req->kw_type =3D NPC_MCAM_KEY_X2; + if (is_cn20k(pfvf->pdev) && kw_type =3D=3D NPC_MCAM_KEY_X4) { + req->kw_type =3D NPC_MCAM_KEY_X4; + ref &=3D (x4_slots - 1); + } req->contig =3D false; req->count =3D count; req->ref_prio =3D prio; @@ -1174,15 +1192,14 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf,= struct otx2_flow *flow) #ifdef CONFIG_DCB int vlan_prio, qidx, pfc_rule =3D 0; #endif + bool modify =3D false, is_x2; int err, vf =3D 0, off, sz; - bool modify =3D false; u8 kw_type =3D 0; u8 *src, *dst; u16 x4_slots; - bool is_x2; =20 if (is_cn20k(pfvf->pdev)) { - err =3D otx2_mcam_pfl_info_get(pfvf, &is_x2, &x4_slots); + err =3D otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type); if (err) { netdev_err(pfvf->netdev, "Error to retrieve NPC profile info, pcifunc=3D%#x\n", @@ -1190,6 +1207,7 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, s= truct otx2_flow *flow) return -EFAULT; } =20 + is_x2 =3D kw_type =3D=3D NPC_MCAM_KEY_X2; if (!is_x2) { err =3D otx2_prepare_flow_request(&flow->flow_spec, &treq); --=20 2.43.0 From nobody Mon Jun 8 04:25:13 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 07ACF29A32D; Fri, 5 Jun 2026 06:33:59 +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=1780641241; cv=none; b=XYHCpl/Zn9ixp6oDcRgOLwUYi+phxudlajRSc5zbEbdJc+qd6002V8UxlO3r5UVkVofEtWuk+Bj6jjp1vzonNQhzfxappFDY3vRG6i72OA9XVbfy0LTUjfmLwN3MXb1wmviaej+xj0OwDBaDiJd68oFxO107VYnHMHm4pT9mjiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780641241; c=relaxed/simple; bh=iJl76HCw92+D/pjPpN+GFGcfnIAsqVfvDIwJMrO+WHE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=c0K8hqW2smWekTX1GkL3LwK3nbtCeC7ro5pY1IICeQgDG9Gsz+XBA9LzZ27GQYi9WR6p0k8Ag4H2ZFM0uAv1O4SRwQOvcUBg+If4tY5xslJbiy4as5bzWIkZr7dvcVoqPZdJJbQO0amxOHLAGXNXm66YcU4b2RbiCfXqZ8MSEt8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=hC4XvPoK; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="hC4XvPoK" 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 654LPXvg3891046; Thu, 4 Jun 2026 23:33:41 -0700 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=O eBP448QH3HrULgaPww9KXkoidleymWFHcrBeo0IwPA=; b=hC4XvPoKbE4c1/IHa pV02lrZxoBDPF5zA0rDD5zEkrZq6jXVuWm2iknV4eCVT36eDGmf0FrehXXTmJT7o Q+AUyMzT5AnZlhsEyuMz0yCgHqNqGWEJBCf2L6oW/2mcKrLyg0ybBCh5vBVjXdyW Q+XQGf6VoQ3q+5nFVF3+KavRrrTwgQiYohqJBG9UcLlF/27B4KdUTpyS1Xmk8Jn5 W53l/vkGhghB6fPMOHuNHBMhGrPx1UY6XSLHqwQP/n3UCMvhxU64LtKIhsPAELuu mPryRc80VQNs+kMxK8h6/ybyS8kh6ltPGXKjTxV2NSockuTyWHTd1+GsR3H5cBKH 6vh7w== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4ekh8x9b6w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 04 Jun 2026 23:33:40 -0700 (PDT) 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; Thu, 4 Jun 2026 23:33:39 -0700 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; Thu, 4 Jun 2026 23:33:39 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id AAF5D3F707A; Thu, 4 Jun 2026 23:33:35 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , "Ratheesh Kannoth" Subject: [PATCH v19 net-next 9/9] octeontx2-af: npc: cn20k: Allocate npc_priv and dstats dynamically. Date: Fri, 5 Jun 2026 12:02:45 +0530 Message-ID: <20260605063245.3553861-10-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260605063245.3553861-1-rkannoth@marvell.com> References: <20260605063245.3553861-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-ORIG-GUID: E7_LjEQVyzsWRhYVL0F0jDu4fOF8GGGp X-Authority-Analysis: v=2.4 cv=DqNmPm/+ c=1 sm=1 tr=0 ts=6a226dc4 cx=c_pps a=rEv8fa4AjpPjGxpoe8rlIQ==:117 a=rEv8fa4AjpPjGxpoe8rlIQ==:17 a=FelO9ux0wxsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=EAYMVhzMl8SCOHhVQcBL:22 a=M5GUcnROAAAA:8 a=S7HcfYHk9quoGn6NhDEA:9 a=jzFzRQuv5CvcdMS1:21 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjA1MDA2MSBTYWx0ZWRfXwxfwbh6Tpmb3 qLbfHPn83O94L6nw0uefl+iJJe7TuiIplOqnROxoblh46xo6l33Io0tEMAPwLEH1aCU9eWHaLlI /8dnIZrrGGJ15AqME8HGt4GOhGmNcj32RqVJXZjSxRgE15OyEr1z1SHXUrE5yiq3Nb41YJYzXF4 d8rxY4tnXc6JrULSFsSshrAfUn2HsfzwTCuaZmJBbyruJUjmcYWwgGt3twa90xqY8uxBalNJfWW brWciI7Hi+R2rpDH3y0x0wUtiFaa9nfeM8vWq9UJf1wRmuXD3uGEW425q1K1VbBMbqsj33e+ssj UiB2u1Dy6v8atngnzR4o/vMvnlNEhP1fdJb++WhL1iDwZeigOM8ywSwGPs1vI7b1b0sjndjP/Yw Ddz4xJI1IBJELFEEG9KOrzEQScVAI/FfEu8J+8u7y+BQ12/P484/0X+cLZot3xcozDJXpIYpPBX MGO2blb64+pl4kBtbJA== X-Proofpoint-GUID: E7_LjEQVyzsWRhYVL0F0jDu4fOF8GGGp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-05_01,2026-05-28_03,2025-10-01_01 Content-Type: text/plain; charset="utf-8" Replace the file-scope static npc_priv with a kcalloc'd struct filled from hardware bank/subbank geometry at init (num_banks is no longer a const compile-time constant; drop init_done and use a non-NULL npc_priv pointer for liveness). Thread npc_priv_get() / pointer access through the CN20K NPC code paths, extend teardown to kfree the root struct on failure and in npc_cn20k_deinit, and adjust MCAM section setup to use the discovered subbank count. Allocate MCAM debugfs dstats via devm_kzalloc instead of a static matrix, and use the allocated backing store consistently when computing deltas (including the counter rollover compare). Signed-off-by: Ratheesh Kannoth --- .../marvell/octeontx2/af/cn20k/debugfs.c | 17 +- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 442 +++++++++--------- .../ethernet/marvell/octeontx2/af/cn20k/npc.h | 4 +- 3 files changed, 240 insertions(+), 223 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c b/dr= ivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c index 730ef97a57e6..b6fda42e44c7 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c @@ -176,7 +176,8 @@ static DEFINE_MUTEX(stats_lock); * hard limit on all silicon variants, preventing any possibility of * out-of-bounds access. */ -static u64 dstats[MAX_NUM_BANKS][MAX_SUBBANK_DEPTH * MAX_NUM_SUB_BANKS] = =3D {}; +static u64 (*dstats)[MAX_NUM_BANKS][MAX_SUBBANK_DEPTH * MAX_NUM_SUB_BANKS]; + static int npc_mcam_dstats_show(struct seq_file *s, void *unused) { struct npc_priv_t *npc_priv; @@ -212,24 +213,24 @@ static int npc_mcam_dstats_show(struct seq_file *s, v= oid *unused) NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(idx, bank)); if (!stats) continue; - if (stats =3D=3D dstats[bank][idx]) + if (stats =3D=3D dstats[0][bank][idx]) continue; =20 - if (stats < dstats[bank][idx]) - dstats[bank][idx] =3D 0; + if (stats < dstats[0][bank][idx]) + dstats[0][bank][idx] =3D 0; =20 pf =3D 0xFFFF; map =3D xa_load(&npc_priv->xa_idx2pf_map, mcam_idx); if (map) pf =3D xa_to_value(map); =20 - delta =3D stats - dstats[bank][idx]; + delta =3D stats - dstats[0][bank][idx]; =20 snprintf(buff, sizeof(buff), "%u\t%#04x\t%llu\n", mcam_idx, pf, delta); seq_puts(s, buff); =20 - dstats[bank][idx] =3D stats; + dstats[0][bank][idx] =3D stats; } } =20 @@ -397,6 +398,10 @@ int npc_cn20k_debugfs_init(struct rvu *rvu) debugfs_create_file("vidx2idx", 0444, rvu->rvu_dbg.npc, npc_priv, &npc_vidx2idx_map_fops); =20 + dstats =3D devm_kzalloc(rvu->dev, sizeof(*dstats), GFP_KERNEL); + if (!dstats) + return -ENOMEM; + debugfs_create_file("dstats", 0444, rvu->rvu_dbg.npc, rvu, &npc_mcam_dstats_fops); =20 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.c index d76aad867934..26618c652483 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -16,9 +16,7 @@ #include "cn20k/reg.h" #include "rvu_npc_fs.h" =20 -static struct npc_priv_t npc_priv =3D { - .num_banks =3D MAX_NUM_BANKS, -}; +static struct npc_priv_t *npc_priv; =20 static const char *npc_kw_name[NPC_MCAM_KEY_MAX] =3D { [NPC_MCAM_KEY_DYN] =3D "DYNAMIC", @@ -226,7 +224,7 @@ static u16 npc_idx2vidx(u16 idx) vidx =3D idx; index =3D idx; =20 - map =3D xa_load(&npc_priv.xa_idx2vidx_map, index); + map =3D xa_load(&npc_priv->xa_idx2vidx_map, index); if (!map) goto done; =20 @@ -242,7 +240,7 @@ static u16 npc_idx2vidx(u16 idx) =20 static bool npc_is_vidx(u16 vidx) { - return vidx >=3D npc_priv.bank_depth * 2; + return vidx >=3D npc_priv->bank_depth * 2; } =20 static u16 npc_vidx2idx(u16 vidx) @@ -256,7 +254,7 @@ static u16 npc_vidx2idx(u16 vidx) idx =3D vidx; index =3D vidx; =20 - map =3D xa_load(&npc_priv.xa_vidx2idx_map, index); + map =3D xa_load(&npc_priv->xa_vidx2idx_map, index); if (!map) goto done; =20 @@ -272,7 +270,7 @@ static u16 npc_vidx2idx(u16 vidx) =20 u16 npc_cn20k_vidx2idx(u16 idx) { - if (!npc_priv.init_done) + if (!npc_priv) return idx; =20 if (!npc_is_vidx(idx)) @@ -283,7 +281,7 @@ u16 npc_cn20k_vidx2idx(u16 idx) =20 u16 npc_cn20k_idx2vidx(u16 idx) { - if (!npc_priv.init_done) + if (!npc_priv) return idx; =20 if (npc_is_vidx(idx)) @@ -306,7 +304,7 @@ static int npc_vidx_maps_del_entry(struct rvu *rvu, u16= vidx, u16 *old_midx) =20 mcam_idx =3D npc_vidx2idx(vidx); =20 - map =3D xa_erase(&npc_priv.xa_vidx2idx_map, vidx); + map =3D xa_erase(&npc_priv->xa_vidx2idx_map, vidx); if (!map) { dev_err(rvu->dev, "%s: vidx(%u) does not map to proper mcam idx\n", @@ -314,7 +312,7 @@ static int npc_vidx_maps_del_entry(struct rvu *rvu, u16= vidx, u16 *old_midx) return -ESRCH; } =20 - map =3D xa_erase(&npc_priv.xa_idx2vidx_map, mcam_idx); + map =3D xa_erase(&npc_priv->xa_idx2vidx_map, mcam_idx); if (!map) { dev_err(rvu->dev, "%s: vidx(%u) is not valid\n", @@ -341,7 +339,7 @@ static int npc_vidx_maps_modify(struct rvu *rvu, u16 vi= dx, u16 new_midx) return -ESRCH; } =20 - map =3D xa_erase(&npc_priv.xa_vidx2idx_map, vidx); + map =3D xa_erase(&npc_priv->xa_vidx2idx_map, vidx); if (!map) { dev_err(rvu->dev, "%s: vidx(%u) could not be deleted from vidx2idx map\n", @@ -351,7 +349,7 @@ static int npc_vidx_maps_modify(struct rvu *rvu, u16 vi= dx, u16 new_midx) =20 old_midx =3D xa_to_value(map); =20 - rc =3D xa_insert(&npc_priv.xa_vidx2idx_map, vidx, + rc =3D xa_insert(&npc_priv->xa_vidx2idx_map, vidx, xa_mk_value(new_midx), GFP_KERNEL); if (rc) { dev_err(rvu->dev, @@ -360,7 +358,7 @@ static int npc_vidx_maps_modify(struct rvu *rvu, u16 vi= dx, u16 new_midx) goto fail1; } =20 - map =3D xa_erase(&npc_priv.xa_idx2vidx_map, old_midx); + map =3D xa_erase(&npc_priv->xa_idx2vidx_map, old_midx); if (!map) { dev_err(rvu->dev, "%s: old_midx(%u, vidx(%u)) cannot be added to idx2vidx map\n", @@ -369,7 +367,7 @@ static int npc_vidx_maps_modify(struct rvu *rvu, u16 vi= dx, u16 new_midx) goto fail2; } =20 - rc =3D xa_insert(&npc_priv.xa_idx2vidx_map, new_midx, + rc =3D xa_insert(&npc_priv->xa_idx2vidx_map, new_midx, xa_mk_value(vidx), GFP_KERNEL); if (rc) { dev_err(rvu->dev, @@ -382,21 +380,21 @@ static int npc_vidx_maps_modify(struct rvu *rvu, u16 = vidx, u16 new_midx) =20 fail3: /* Restore vidx at old_midx location */ - if (xa_insert(&npc_priv.xa_idx2vidx_map, old_midx, + if (xa_insert(&npc_priv->xa_idx2vidx_map, old_midx, xa_mk_value(vidx), GFP_KERNEL)) dev_err(rvu->dev, "%s: Error to roll back idx2vidx old_midx=3D%u vidx=3D%u\n", __func__, old_midx, vidx); fail2: /* Erase new_midx inserted at vidx */ - if (!xa_erase(&npc_priv.xa_vidx2idx_map, vidx)) + if (!xa_erase(&npc_priv->xa_vidx2idx_map, vidx)) dev_err(rvu->dev, "%s: Failed to roll back vidx2idx vidx=3D%u\n", __func__, vidx); =20 fail1: /* Restore old_midx at vidx location */ - if (xa_insert(&npc_priv.xa_vidx2idx_map, vidx, + if (xa_insert(&npc_priv->xa_vidx2idx_map, vidx, xa_mk_value(old_midx), GFP_KERNEL)) dev_err(rvu->dev, "%s: Failed to roll back vidx2idx to old_midx=3D%u, vidx=3D%u\n", @@ -412,10 +410,10 @@ static int npc_vidx_maps_add_entry(struct rvu *rvu, u= 16 mcam_idx, int pcifunc, u32 id; =20 /* Virtual index start from maximum mcam index + 1 */ - max =3D npc_priv.bank_depth * 2 * 2 - 1; - min =3D npc_priv.bank_depth * 2; + max =3D npc_priv->bank_depth * 2 * 2 - 1; + min =3D npc_priv->bank_depth * 2; =20 - rc =3D xa_alloc(&npc_priv.xa_vidx2idx_map, &id, + rc =3D xa_alloc(&npc_priv->xa_vidx2idx_map, &id, xa_mk_value(mcam_idx), XA_LIMIT(min, max), GFP_KERNEL); if (rc) { @@ -425,7 +423,7 @@ static int npc_vidx_maps_add_entry(struct rvu *rvu, u16= mcam_idx, int pcifunc, goto fail1; } =20 - rc =3D xa_insert(&npc_priv.xa_idx2vidx_map, mcam_idx, + rc =3D xa_insert(&npc_priv->xa_idx2vidx_map, mcam_idx, xa_mk_value(id), GFP_KERNEL); if (rc) { dev_err(rvu->dev, @@ -440,7 +438,7 @@ static int npc_vidx_maps_add_entry(struct rvu *rvu, u16= mcam_idx, int pcifunc, return 0; =20 fail2: - xa_erase(&npc_priv.xa_vidx2idx_map, id); + xa_erase(&npc_priv->xa_vidx2idx_map, id); fail1: return rc; } @@ -691,7 +689,7 @@ void npc_cn20k_parser_profile_init(struct rvu *rvu, int= blkaddr) =20 struct npc_priv_t *npc_priv_get(void) { - return &npc_priv; + return npc_priv; } =20 static void npc_program_mkex_rx(struct rvu *rvu, int blkaddr, @@ -860,9 +858,9 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkadd= r, =20 update_en_map: if (enable) - set_bit(index, npc_priv.en_map); + set_bit(index, npc_priv->en_map); else - clear_bit(index, npc_priv.en_map); + clear_bit(index, npc_priv->en_map); =20 return 0; } @@ -1751,28 +1749,28 @@ int npc_mcam_idx_2_key_type(struct rvu *rvu, u16 mc= am_idx, u8 *key_type) int bank_off, sb_id; =20 /* mcam_idx should be less than (2 * bank depth) */ - if (mcam_idx >=3D npc_priv.bank_depth * 2) { + if (mcam_idx >=3D npc_priv->bank_depth * 2) { dev_err(rvu->dev, "%s: bad params\n", __func__); return -EINVAL; } =20 /* find mcam offset per bank */ - bank_off =3D mcam_idx & (npc_priv.bank_depth - 1); + bank_off =3D mcam_idx & (npc_priv->bank_depth - 1); =20 /* Find subbank id */ - sb_id =3D bank_off / npc_priv.subbank_depth; + sb_id =3D bank_off / npc_priv->subbank_depth; =20 /* Check if subbank id is more than maximum * number of subbanks available */ - if (sb_id >=3D npc_priv.num_subbanks) { + if (sb_id >=3D npc_priv->num_subbanks) { dev_err(rvu->dev, "%s: invalid subbank %d\n", __func__, sb_id); return -EINVAL; } =20 - sb =3D &npc_priv.sb[sb_id]; + sb =3D &npc_priv->sb[sb_id]; =20 *key_type =3D sb->key_type; =20 @@ -1788,7 +1786,7 @@ static int npc_subbank_idx_2_mcam_idx(struct rvu *rvu= , struct npc_subbank *sb, * subsection depth - 1 */ if (sb->key_type =3D=3D NPC_MCAM_KEY_X4 && - sub_off >=3D npc_priv.subbank_depth) { + sub_off >=3D npc_priv->subbank_depth) { dev_err(rvu->dev, "%s: Failed to get mcam idx (x4) sb->idx=3D%u sub_off=3D%u", __func__, sb->idx, sub_off); @@ -1799,7 +1797,7 @@ static int npc_subbank_idx_2_mcam_idx(struct rvu *rvu= , struct npc_subbank *sb, * 2 * subsection depth - 1 */ if (sb->key_type =3D=3D NPC_MCAM_KEY_X2 && - sub_off >=3D npc_priv.subbank_depth * 2) { + sub_off >=3D npc_priv->subbank_depth * 2) { dev_err(rvu->dev, "%s: Failed to get mcam idx (x2) sb->idx=3D%u sub_off=3D%u", __func__, sb->idx, sub_off); @@ -1807,12 +1805,12 @@ static int npc_subbank_idx_2_mcam_idx(struct rvu *r= vu, struct npc_subbank *sb, } =20 /* Find subbank offset from respective subbank (w.r.t bank) */ - off =3D sub_off & (npc_priv.subbank_depth - 1); + off =3D sub_off & (npc_priv->subbank_depth - 1); =20 /* if subsection idx is in bank1, add bank depth, * which is part of sb->b1b */ - bot =3D sub_off >=3D npc_priv.subbank_depth ? sb->b1b : sb->b0b; + bot =3D sub_off >=3D npc_priv->subbank_depth ? sb->b1b : sb->b0b; =20 *mcam_idx =3D bot + off; return 0; @@ -1825,37 +1823,37 @@ int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16= mcam_idx, int bank_off, sb_id; =20 /* mcam_idx should be less than (2 * bank depth) */ - if (mcam_idx >=3D npc_priv.bank_depth * 2) { + if (mcam_idx >=3D npc_priv->bank_depth * 2) { dev_err(rvu->dev, "%s: Invalid mcam idx %u\n", __func__, mcam_idx); return -EINVAL; } =20 /* find mcam offset per bank */ - bank_off =3D mcam_idx & (npc_priv.bank_depth - 1); + bank_off =3D mcam_idx & (npc_priv->bank_depth - 1); =20 /* Find subbank id */ - sb_id =3D bank_off / npc_priv.subbank_depth; + sb_id =3D bank_off / npc_priv->subbank_depth; =20 /* Check if subbank id is more than maximum * number of subbanks available */ - if (sb_id >=3D npc_priv.num_subbanks) { + if (sb_id >=3D npc_priv->num_subbanks) { dev_err(rvu->dev, "%s: invalid subbank %d\n", __func__, sb_id); return -EINVAL; } =20 - *sb =3D &npc_priv.sb[sb_id]; + *sb =3D &npc_priv->sb[sb_id]; =20 /* Subbank offset per bank */ - *sb_off =3D bank_off % npc_priv.subbank_depth; + *sb_off =3D bank_off % npc_priv->subbank_depth; =20 /* Index in a subbank should add subbank depth * if it is in bank1 */ - if (mcam_idx >=3D npc_priv.bank_depth) - *sb_off +=3D npc_priv.subbank_depth; + if (mcam_idx >=3D npc_priv->bank_depth) + *sb_off +=3D npc_priv->subbank_depth; =20 return 0; } @@ -1871,9 +1869,9 @@ static int __npc_subbank_contig_alloc(struct rvu *rvu, int k, offset, delta =3D 0; int cnt =3D 0, sbd; =20 - sbd =3D npc_priv.subbank_depth; + sbd =3D npc_priv->subbank_depth; =20 - if (sidx >=3D npc_priv.bank_depth) + if (sidx >=3D npc_priv->bank_depth) delta =3D sbd; =20 switch (prio) { @@ -1940,8 +1938,8 @@ static int __npc_subbank_non_contig_alloc(struct rvu = *rvu, int cnt =3D 0, delta; int k, sbd; =20 - sbd =3D npc_priv.subbank_depth; - delta =3D sidx >=3D npc_priv.bank_depth ? sbd : 0; + sbd =3D npc_priv->subbank_depth; + delta =3D sidx >=3D npc_priv->bank_depth ? sbd : 0; =20 switch (prio) { /* Find an area of size 'count' from sidx to eidx */ @@ -2002,7 +2000,7 @@ static void __npc_subbank_sboff_2_off(struct rvu *rvu= , struct npc_subbank *sb, { int sbd; =20 - sbd =3D npc_priv.subbank_depth; + sbd =3D npc_priv->subbank_depth; =20 *off =3D sb_off & (sbd - 1); *bmap =3D (sb_off >=3D sbd) ? sb->b1map : sb->b0map; @@ -2051,20 +2049,20 @@ static int __npc_subbank_mark_free(struct rvu *rvu,= struct npc_subbank *sb) sb->flags =3D NPC_SUBBANK_FLAG_FREE; sb->key_type =3D 0; =20 - bitmap_clear(sb->b0map, 0, npc_priv.subbank_depth); - bitmap_clear(sb->b1map, 0, npc_priv.subbank_depth); + bitmap_clear(sb->b0map, 0, npc_priv->subbank_depth); + bitmap_clear(sb->b1map, 0, npc_priv->subbank_depth); =20 - if (!xa_erase(&npc_priv.xa_sb_used, sb->arr_idx)) { + if (!xa_erase(&npc_priv->xa_sb_used, sb->arr_idx)) { dev_err(rvu->dev, "%s: Error to delete from xa_sb_used array\n", __func__); return -EFAULT; } =20 - rc =3D xa_insert(&npc_priv.xa_sb_free, sb->arr_idx, + rc =3D xa_insert(&npc_priv->xa_sb_free, sb->arr_idx, xa_mk_value(sb->idx), GFP_KERNEL); if (rc) { - rc =3D xa_insert(&npc_priv.xa_sb_used, sb->arr_idx, + rc =3D xa_insert(&npc_priv->xa_sb_used, sb->arr_idx, xa_mk_value(sb->idx), GFP_KERNEL); if (rc) dev_err(rvu->dev, @@ -2093,21 +2091,21 @@ static int __npc_subbank_mark_used(struct rvu *rvu,= struct npc_subbank *sb, sb->flags =3D NPC_SUBBANK_FLAG_USED; sb->key_type =3D key_type; if (key_type =3D=3D NPC_MCAM_KEY_X4) - sb->free_cnt =3D npc_priv.subbank_depth; + sb->free_cnt =3D npc_priv->subbank_depth; else - sb->free_cnt =3D 2 * npc_priv.subbank_depth; + sb->free_cnt =3D 2 * npc_priv->subbank_depth; =20 - bitmap_clear(sb->b0map, 0, npc_priv.subbank_depth); - bitmap_clear(sb->b1map, 0, npc_priv.subbank_depth); + bitmap_clear(sb->b0map, 0, npc_priv->subbank_depth); + bitmap_clear(sb->b1map, 0, npc_priv->subbank_depth); =20 - if (!xa_erase(&npc_priv.xa_sb_free, sb->arr_idx)) { + if (!xa_erase(&npc_priv->xa_sb_free, sb->arr_idx)) { dev_err(rvu->dev, "%s: Error to delete from xa_sb_free array\n", __func__); return -EFAULT; } =20 - rc =3D xa_insert(&npc_priv.xa_sb_used, sb->arr_idx, + rc =3D xa_insert(&npc_priv->xa_sb_used, sb->arr_idx, xa_mk_value(sb->idx), GFP_KERNEL); if (rc) dev_err(rvu->dev, @@ -2131,10 +2129,10 @@ static bool __npc_subbank_free(struct rvu *rvu, str= uct npc_subbank *sb, =20 /* Check whether we can mark whole subbank as free */ if (sb->key_type =3D=3D NPC_MCAM_KEY_X4) { - if (sb->free_cnt < npc_priv.subbank_depth) + if (sb->free_cnt < npc_priv->subbank_depth) goto done; } else { - if (sb->free_cnt < 2 * npc_priv.subbank_depth) + if (sb->free_cnt < 2 * npc_priv->subbank_depth) goto done; } =20 @@ -2213,7 +2211,7 @@ static int __npc_subbank_alloc(struct rvu *rvu, struc= t npc_subbank *sb, =20 /* x4 indexes are from 0 to bank size as it combines two x2 banks */ if (key_type =3D=3D NPC_MCAM_KEY_X4 && - (ref >=3D npc_priv.bank_depth || limit >=3D npc_priv.bank_depth)) { + (ref >=3D npc_priv->bank_depth || limit >=3D npc_priv->bank_depth)) { dev_err(rvu->dev, "%s: Wrong ref_enty(%d) or limit(%d) for x4\n", __func__, ref, limit); @@ -2223,8 +2221,8 @@ static int __npc_subbank_alloc(struct rvu *rvu, struc= t npc_subbank *sb, /* This function is called either bank0 or bank1 portion of a subbank. * so ref and limit should be on same bank. */ - diffbank =3D !!((ref & npc_priv.bank_depth) ^ - (limit & npc_priv.bank_depth)); + diffbank =3D !!((ref & npc_priv->bank_depth) ^ + (limit & npc_priv->bank_depth)); if (diffbank) { dev_err(rvu->dev, "%s: request ref and limit should be from same bank\n", @@ -2248,7 +2246,7 @@ static int __npc_subbank_alloc(struct rvu *rvu, struc= t npc_subbank *sb, * or equal to mcam entries available in the subbank if contig. */ if (sb->flags & NPC_SUBBANK_FLAG_FREE) { - if (contig && count > npc_priv.subbank_depth) { + if (contig && count > npc_priv->subbank_depth) { dev_err(rvu->dev, "%s: Less number of entries\n", __func__); return -ENOSPC; @@ -2271,10 +2269,10 @@ static int __npc_subbank_alloc(struct rvu *rvu, str= uct npc_subbank *sb, } =20 process: - /* if ref or limit >=3D npc_priv.bank_depth, index are in bank1. + /* if ref or limit >=3D npc_priv->bank_depth, index are in bank1. * else bank0. */ - if (ref >=3D npc_priv.bank_depth) { + if (ref >=3D npc_priv->bank_depth) { bmap =3D sb->b1map; t =3D sb->b1t; b =3D sb->b1b; @@ -2285,8 +2283,8 @@ static int __npc_subbank_alloc(struct rvu *rvu, struc= t npc_subbank *sb, } =20 /* Calculate free slots */ - bw =3D bitmap_weight(bmap, npc_priv.subbank_depth); - bfree =3D npc_priv.subbank_depth - bw; + bw =3D bitmap_weight(bmap, npc_priv->subbank_depth); + bfree =3D npc_priv->subbank_depth - bw; =20 if (!bfree) { dev_dbg(rvu->dev, "%s: subbank is full\n", __func__); @@ -2415,7 +2413,7 @@ npc_del_from_pf_maps(struct rvu *rvu, u16 mcam_idx) int pcifunc, idx; void *map; =20 - map =3D xa_erase(&npc_priv.xa_idx2pf_map, mcam_idx); + map =3D xa_erase(&npc_priv->xa_idx2pf_map, mcam_idx); if (!map) { dev_err(rvu->dev, "%s: failed to erase mcam_idx(%u) from xa_idx2pf map\n", @@ -2424,7 +2422,7 @@ npc_del_from_pf_maps(struct rvu *rvu, u16 mcam_idx) } =20 pcifunc =3D xa_to_value(map); - map =3D xa_load(&npc_priv.xa_pf_map, pcifunc); + map =3D xa_load(&npc_priv->xa_pf_map, pcifunc); if (!map) { dev_err(rvu->dev, "%s: failed to find entry for (%u) from xa_pf_map, mcam=3D%u\n", @@ -2434,7 +2432,7 @@ npc_del_from_pf_maps(struct rvu *rvu, u16 mcam_idx) =20 idx =3D xa_to_value(map); =20 - map =3D xa_erase(&npc_priv.xa_pf2idx_map[idx], mcam_idx); + map =3D xa_erase(&npc_priv->xa_pf2idx_map[idx], mcam_idx); if (!map) { dev_err(rvu->dev, "%s: failed to erase mcam_idx(%u) from xa_pf2idx_map map\n", @@ -2454,18 +2452,18 @@ npc_add_to_pf_maps(struct rvu *rvu, u16 mcam_idx, i= nt pcifunc) "%s: add2maps mcam_idx(%u) to xa_idx2pf map pcifunc=3D%#x\n", __func__, mcam_idx, pcifunc); =20 - rc =3D xa_insert(&npc_priv.xa_idx2pf_map, mcam_idx, + rc =3D xa_insert(&npc_priv->xa_idx2pf_map, mcam_idx, xa_mk_value(pcifunc), GFP_KERNEL); =20 if (rc) { - map =3D xa_load(&npc_priv.xa_idx2pf_map, mcam_idx); + map =3D xa_load(&npc_priv->xa_idx2pf_map, mcam_idx); dev_err(rvu->dev, "%s: failed to insert mcam_idx(%u) to xa_idx2pf map, existing value=3D%= lu\n", __func__, mcam_idx, xa_to_value(map)); return -EFAULT; } =20 - map =3D xa_load(&npc_priv.xa_pf_map, pcifunc); + map =3D xa_load(&npc_priv->xa_pf_map, pcifunc); if (!map) { dev_err(rvu->dev, "%s: failed to find pf map entry for pcifunc=3D%#x, mcam=3D%u\n", @@ -2475,12 +2473,12 @@ npc_add_to_pf_maps(struct rvu *rvu, u16 mcam_idx, i= nt pcifunc) =20 idx =3D xa_to_value(map); =20 - rc =3D xa_insert(&npc_priv.xa_pf2idx_map[idx], mcam_idx, + rc =3D xa_insert(&npc_priv->xa_pf2idx_map[idx], mcam_idx, xa_mk_value(pcifunc), GFP_KERNEL); =20 if (rc) { - map =3D xa_load(&npc_priv.xa_pf2idx_map[idx], mcam_idx); - xa_erase(&npc_priv.xa_idx2pf_map, mcam_idx); + map =3D xa_load(&npc_priv->xa_pf2idx_map[idx], mcam_idx); + xa_erase(&npc_priv->xa_idx2pf_map, mcam_idx); dev_err(rvu->dev, "%s: failed to insert mcam_idx(%u) to xa_pf2idx_map map, earlier value= =3D%lu idx=3D%u\n", __func__, mcam_idx, xa_to_value(map), idx); @@ -2510,9 +2508,9 @@ npc_subbank_suits(struct npc_subbank *sb, int key_typ= e) return false; } =20 -#define SB_ALIGN_UP(val) (((val) + npc_priv.subbank_depth) & \ - ~((npc_priv.subbank_depth) - 1)) -#define SB_ALIGN_DOWN(val) ALIGN_DOWN((val), npc_priv.subbank_depth) +#define SB_ALIGN_UP(val) (((val) + npc_priv->subbank_depth) & \ + ~((npc_priv->subbank_depth) - 1)) +#define SB_ALIGN_DOWN(val) ALIGN_DOWN((val), npc_priv->subbank_depth) =20 static void npc_subbank_iter_down(struct rvu *rvu, int ref, int limit, @@ -2538,7 +2536,7 @@ static void npc_subbank_iter_down(struct rvu *rvu, } =20 *cur_ref =3D *cur_limit - 1; - align =3D *cur_ref - npc_priv.subbank_depth + 1; + align =3D *cur_ref - npc_priv->subbank_depth + 1; if (align <=3D limit) { *stop =3D true; *cur_limit =3D limit; @@ -2578,7 +2576,7 @@ static void npc_subbank_iter_up(struct rvu *rvu, } =20 *cur_ref =3D *cur_limit + 1; - align =3D *cur_ref + npc_priv.subbank_depth - 1; + align =3D *cur_ref + npc_priv->subbank_depth - 1; =20 if (align >=3D limit) { *stop =3D true; @@ -2606,17 +2604,17 @@ npc_subbank_iter(struct rvu *rvu, int key_type, =20 /* limit and ref should < bank_depth for x4 */ if (key_type =3D=3D NPC_MCAM_KEY_X4) { - if (*cur_ref >=3D npc_priv.bank_depth) + if (*cur_ref >=3D npc_priv->bank_depth) return -EINVAL; =20 - if (*cur_limit >=3D npc_priv.bank_depth) + if (*cur_limit >=3D npc_priv->bank_depth) return -EINVAL; } /* limit and ref should < 2 * bank_depth, for x2 */ - if (*cur_ref >=3D 2 * npc_priv.bank_depth) + if (*cur_ref >=3D 2 * npc_priv->bank_depth) return -EINVAL; =20 - if (*cur_limit >=3D 2 * npc_priv.bank_depth) + if (*cur_limit >=3D 2 * npc_priv->bank_depth) return -EINVAL; =20 return 0; @@ -2651,7 +2649,7 @@ static int npc_idx_free(struct rvu *rvu, u16 *mcam_id= x, int count, vidx =3D npc_idx2vidx(midx); } =20 - if (midx >=3D npc_priv.bank_depth * npc_priv.num_banks) { + if (midx >=3D npc_priv->bank_depth * npc_priv->num_banks) { dev_err(rvu->dev, "%s: Invalid mcam_idx=3D%u cannot be deleted\n", __func__, mcam_idx[i]); @@ -2846,7 +2844,7 @@ static int npc_subbank_free_cnt(struct rvu *rvu, stru= ct npc_subbank *sb, { int cnt, spd; =20 - spd =3D npc_priv.subbank_depth; + spd =3D npc_priv->subbank_depth; mutex_lock(&sb->lock); =20 if (sb->flags & NPC_SUBBANK_FLAG_FREE) @@ -3005,7 +3003,7 @@ static int npc_subbank_noref_alloc(struct rvu *rvu, i= nt key_type, bool contig, max_alloc =3D !contig; =20 /* Check used subbanks for free slots */ - xa_for_each(&npc_priv.xa_sb_used, index, val) { + xa_for_each(&npc_priv->xa_sb_used, index, val) { idx =3D xa_to_value(val); =20 /* Minimize allocation from restricted subbanks @@ -3014,7 +3012,7 @@ static int npc_subbank_noref_alloc(struct rvu *rvu, i= nt key_type, bool contig, if (npc_subbank_restrict_usage(rvu, idx)) continue; =20 - sb =3D &npc_priv.sb[idx]; + sb =3D &npc_priv->sb[idx]; =20 /* Skip if not suitable subbank */ if (!npc_subbank_suits(sb, key_type)) @@ -3071,9 +3069,9 @@ static int npc_subbank_noref_alloc(struct rvu *rvu, i= nt key_type, bool contig, } =20 /* Allocate in free subbanks */ - xa_for_each(&npc_priv.xa_sb_free, index, val) { + xa_for_each(&npc_priv->xa_sb_free, index, val) { idx =3D xa_to_value(val); - sb =3D &npc_priv.sb[idx]; + sb =3D &npc_priv->sb[idx]; =20 /* Minimize allocation from restricted subbanks * in noref allocations. @@ -3129,7 +3127,7 @@ static int npc_subbank_noref_alloc(struct rvu *rvu, i= nt key_type, bool contig, for (i =3D 0; restrict_valid && (i < ARRAY_SIZE(npc_subbank_restricted_idxs)); i++) { idx =3D npc_subbank_restricted_idxs[i]; - sb =3D &npc_priv.sb[idx]; + sb =3D &npc_priv->sb[idx]; =20 /* Skip if not suitable subbank */ if (!npc_subbank_suits(sb, key_type)) @@ -3209,7 +3207,7 @@ int npc_cn20k_ref_idx_alloc(struct rvu *rvu, int pcif= unc, int key_type, bool ref_valid; u16 vidx; =20 - bd =3D npc_priv.bank_depth; + bd =3D npc_priv->bank_depth; =20 /* Special case: ref =3D=3D 0 && limit=3D 0 && prio =3D=3D HIGH && count = =3D=3D 1 * Here user wants to allocate 0th entry @@ -3227,7 +3225,7 @@ int npc_cn20k_ref_idx_alloc(struct rvu *rvu, int pcif= unc, int key_type, ref_valid =3D !!(limit || ref); defrag_candidate =3D !ref_valid && !contig && virt; if (!ref_valid) { - if (contig && count > npc_priv.subbank_depth) + if (contig && count > npc_priv->subbank_depth) goto try_noref_multi_subbank; =20 rc =3D npc_subbank_noref_alloc(rvu, key_type, contig, @@ -3272,7 +3270,7 @@ int npc_cn20k_ref_idx_alloc(struct rvu *rvu, int pcif= unc, int key_type, return -EINVAL; } =20 - if (contig && count > npc_priv.subbank_depth) + if (contig && count > npc_priv->subbank_depth) goto try_ref_multi_subbank; =20 rc =3D npc_subbank_ref_alloc(rvu, key_type, ref, limit, @@ -3334,8 +3332,8 @@ void npc_cn20k_subbank_calc_free(struct rvu *rvu, int= *x2_free, *x4_free =3D 0; *sb_free =3D 0; =20 - for (i =3D 0; i < npc_priv.num_subbanks; i++) { - sb =3D &npc_priv.sb[i]; + for (i =3D 0; i < npc_priv->num_subbanks; i++) { + sb =3D &npc_priv->sb[i]; mutex_lock(&sb->lock); =20 /* Count number of free subbanks */ @@ -3433,11 +3431,11 @@ static void npc_subbank_init(struct rvu *rvu, struc= t npc_subbank *sb, int idx) { mutex_init(&sb->lock); =20 - sb->b0b =3D idx * npc_priv.subbank_depth; - sb->b0t =3D sb->b0b + npc_priv.subbank_depth - 1; + sb->b0b =3D idx * npc_priv->subbank_depth; + sb->b0t =3D sb->b0b + npc_priv->subbank_depth - 1; =20 - sb->b1b =3D npc_priv.bank_depth + idx * npc_priv.subbank_depth; - sb->b1t =3D sb->b1b + npc_priv.subbank_depth - 1; + sb->b1b =3D npc_priv->bank_depth + idx * npc_priv->subbank_depth; + sb->b1t =3D sb->b1b + npc_priv->subbank_depth - 1; =20 sb->flags =3D NPC_SUBBANK_FLAG_FREE; sb->idx =3D idx; @@ -3449,7 +3447,7 @@ static void npc_subbank_init(struct rvu *rvu, struct = npc_subbank *sb, int idx) /* Keep first and last subbank at end of free array; so that * it will be used at last */ - xa_store(&npc_priv.xa_sb_free, sb->arr_idx, + xa_store(&npc_priv->xa_sb_free, sb->arr_idx, xa_mk_value(sb->idx), GFP_KERNEL); } =20 @@ -3474,7 +3472,7 @@ static int npc_pcifunc_map_create(struct rvu *rvu) =20 pcifunc =3D pf << 9; =20 - xa_store(&npc_priv.xa_pf_map, (unsigned long)pcifunc, + xa_store(&npc_priv->xa_pf_map, (unsigned long)pcifunc, xa_mk_value(cnt), GFP_KERNEL); =20 cnt++; @@ -3483,7 +3481,7 @@ static int npc_pcifunc_map_create(struct rvu *rvu) for (vf =3D 0; vf < numvfs; vf++) { pcifunc =3D (pf << 9) | (vf + 1); =20 - xa_store(&npc_priv.xa_pf_map, (unsigned long)pcifunc, + xa_store(&npc_priv->xa_pf_map, (unsigned long)pcifunc, xa_mk_value(cnt), GFP_KERNEL); cnt++; } @@ -3569,7 +3567,7 @@ static int npc_defrag_alloc_free_slots(struct rvu *rv= u, int rc, sb_off, i, err; bool deleted; =20 - sb =3D &npc_priv.sb[f->idx]; + sb =3D &npc_priv->sb[f->idx]; =20 alloc_cnt1 =3D 0; alloc_cnt2 =3D 0; @@ -3639,9 +3637,9 @@ static int npc_defrag_add_2_show_list(struct rvu *rvu= , u16 old_midx, node->vidx =3D vidx; INIT_LIST_HEAD(&node->list); =20 - mutex_lock(&npc_priv.lock); - list_add_tail(&node->list, &npc_priv.defrag_lh); - mutex_unlock(&npc_priv.lock); + mutex_lock(&npc_priv->lock); + list_add_tail(&node->list, &npc_priv->defrag_lh); + mutex_unlock(&npc_priv->lock); =20 return 0; } @@ -3745,7 +3743,7 @@ int npc_defrag_move_vdx_to_free(struct rvu *rvu, } =20 /* save pcifunc */ - map =3D xa_load(&npc_priv.xa_idx2pf_map, old_midx); + map =3D xa_load(&npc_priv->xa_idx2pf_map, old_midx); pcifunc =3D xa_to_value(map); =20 /* delete from pf maps */ @@ -3904,29 +3902,29 @@ static void npc_defrag_list_clear(void) { struct npc_defrag_show_node *node, *next; =20 - mutex_lock(&npc_priv.lock); - list_for_each_entry_safe(node, next, &npc_priv.defrag_lh, list) { + mutex_lock(&npc_priv->lock); + list_for_each_entry_safe(node, next, &npc_priv->defrag_lh, list) { list_del_init(&node->list); kfree(node); } =20 - mutex_unlock(&npc_priv.lock); + mutex_unlock(&npc_priv->lock); } =20 static void npc_lock_all_subbank(void) { int i; =20 - for (i =3D 0; i < npc_priv.num_subbanks; i++) - mutex_lock(&npc_priv.sb[i].lock); + for (i =3D 0; i < npc_priv->num_subbanks; i++) + mutex_lock(&npc_priv->sb[i].lock); } =20 static void npc_unlock_all_subbank(void) { int i; =20 - for (i =3D npc_priv.num_subbanks - 1; i >=3D 0; i--) - mutex_unlock(&npc_priv.sb[i].lock); + for (i =3D npc_priv->num_subbanks - 1; i >=3D 0; i--) + mutex_unlock(&npc_priv->sb[i].lock); } =20 int npc_cn20k_search_order_set(struct rvu *rvu, @@ -3944,9 +3942,9 @@ int npc_cn20k_search_order_set(struct rvu *rvu, USED =3D 1, }; =20 - if (cnt !=3D npc_priv.num_subbanks) { + if (cnt !=3D npc_priv->num_subbanks) { dev_err(rvu->dev, "Number of entries(%u) !=3D %u\n", - cnt, npc_priv.num_subbanks); + cnt, npc_priv->num_subbanks); return -EINVAL; } =20 @@ -3954,18 +3952,18 @@ int npc_cn20k_search_order_set(struct rvu *rvu, npc_lock_all_subbank(); =20 for (sb_idx =3D 0; sb_idx < cnt; sb_idx++) { - sb =3D &npc_priv.sb[sb_idx]; + sb =3D &npc_priv->sb[sb_idx]; save[sb->idx] =3D sb->arr_idx; } =20 for (prio =3D 0; prio < cnt; prio++) { sb_idx =3D narr[prio]; - sb =3D &npc_priv.sb[sb_idx]; + sb =3D &npc_priv->sb[sb_idx]; =20 if (sb->flags & NPC_SUBBANK_FLAG_USED) - xa =3D &npc_priv.xa_sb_used; + xa =3D &npc_priv->xa_sb_used; else - xa =3D &npc_priv.xa_sb_free; + xa =3D &npc_priv->xa_sb_free; =20 rc =3D xa_err(xa_store(xa, prio, xa_mk_value(sb_idx), GFP_KERNEL)); @@ -3989,10 +3987,10 @@ int npc_cn20k_search_order_set(struct rvu *rvu, =20 for (prio =3D 0; prio < cnt; prio++) { if (rsrc[FREE][prio] =3D=3D -1) - xa_erase(&npc_priv.xa_sb_free, prio); + xa_erase(&npc_priv->xa_sb_free, prio); =20 if (rsrc[USED][prio] =3D=3D -1) - xa_erase(&npc_priv.xa_sb_used, prio); + xa_erase(&npc_priv->xa_sb_used, prio); } =20 for (int i =3D 0; i < cnt; i++) @@ -4008,20 +4006,20 @@ int npc_cn20k_search_order_set(struct rvu *rvu, fail: for (prio =3D 0; prio < cnt; prio++) { if (rsrc[FREE][prio] =3D=3D 1) - xa_erase(&npc_priv.xa_sb_free, prio); + xa_erase(&npc_priv->xa_sb_free, prio); =20 if (rsrc[USED][prio] =3D=3D 1) - xa_erase(&npc_priv.xa_sb_used, prio); + xa_erase(&npc_priv->xa_sb_used, prio); } =20 for (sb_idx =3D 0; sb_idx < cnt; sb_idx++) { - sb =3D &npc_priv.sb[sb_idx]; + sb =3D &npc_priv->sb[sb_idx]; sb->arr_idx =3D save[sb_idx]; =20 if (sb->flags & NPC_SUBBANK_FLAG_USED) - xa =3D &npc_priv.xa_sb_used; + xa =3D &npc_priv->xa_sb_used; else - xa =3D &npc_priv.xa_sb_free; + xa =3D &npc_priv->xa_sb_free; =20 /* Since the entry already exists, xa_store() replaces * the value without a kmalloc(), making failure highly unlikely. @@ -4041,7 +4039,7 @@ int npc_cn20k_search_order_set(struct rvu *rvu, const u32 *npc_cn20k_search_order_get(bool *restricted_order, u32 *sz) { *restricted_order =3D restrict_valid; - *sz =3D npc_priv.num_subbanks; + *sz =3D npc_priv->num_subbanks; return subbank_srch_order; } =20 @@ -4065,7 +4063,7 @@ int npc_cn20k_defrag(struct rvu *rvu) INIT_LIST_HEAD(&x4lh); INIT_LIST_HEAD(&x2lh); =20 - node =3D kcalloc(npc_priv.num_subbanks, sizeof(*node), GFP_KERNEL); + node =3D kcalloc(npc_priv->num_subbanks, sizeof(*node), GFP_KERNEL); if (!node) return -ENOMEM; =20 @@ -4074,13 +4072,13 @@ int npc_cn20k_defrag(struct rvu *rvu) npc_lock_all_subbank(); =20 /* Fill in node with subbank properties */ - for (i =3D 0; i < npc_priv.num_subbanks; i++) { - sb =3D &npc_priv.sb[i]; + for (i =3D 0; i < npc_priv->num_subbanks; i++) { + sb =3D &npc_priv->sb[i]; =20 node[i].idx =3D i; node[i].key_type =3D sb->key_type; node[i].free_cnt =3D sb->free_cnt; - node[i].vidx =3D kcalloc(npc_priv.subbank_depth * 2, + node[i].vidx =3D kcalloc(npc_priv->subbank_depth * 2, sizeof(*node[i].vidx), GFP_KERNEL); if (!node[i].vidx) { @@ -4110,8 +4108,8 @@ int npc_cn20k_defrag(struct rvu *rvu) } =20 /* Filling vidx[] array with all vidx in that subbank */ - xa_for_each_start(&npc_priv.xa_vidx2idx_map, index, map, - npc_priv.bank_depth * 2) { + xa_for_each_start(&npc_priv->xa_vidx2idx_map, index, map, + npc_priv->bank_depth * 2) { midx =3D xa_to_value(map); rc =3D npc_mcam_idx_2_subbank_idx(rvu, midx, &sb, &sb_off); @@ -4128,14 +4126,14 @@ int npc_cn20k_defrag(struct rvu *rvu) } =20 /* Mark all subbank which has ref allocation */ - for (i =3D 0; i < npc_priv.num_subbanks; i++) { + for (i =3D 0; i < npc_priv->num_subbanks; i++) { tnode =3D &node[i]; =20 if (!tnode->valid) continue; =20 tot =3D (tnode->key_type =3D=3D NPC_MCAM_KEY_X2) ? - npc_priv.subbank_depth * 2 : npc_priv.subbank_depth; + npc_priv->subbank_depth * 2 : npc_priv->subbank_depth; =20 if (node[i].vidx_cnt !=3D tot - tnode->free_cnt) tnode->refs =3D true; @@ -4152,7 +4150,7 @@ int npc_cn20k_defrag(struct rvu *rvu) free_vidx: npc_unlock_all_subbank(); mutex_unlock(&mcam->lock); - for (i =3D 0; i < npc_priv.num_subbanks; i++) + for (i =3D 0; i < npc_priv->num_subbanks; i++) kfree(node[i].vidx); kfree(node); return rc; @@ -4180,7 +4178,7 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 = pcifunc, u16 *bcast, *ptr[i] =3D USHRT_MAX; } =20 - if (!npc_priv.init_done) + if (!npc_priv) return 0; =20 if (is_lbk_vf(rvu, pcifunc)) { @@ -4188,7 +4186,7 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 = pcifunc, u16 *bcast, return -EINVAL; =20 idx =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_PROMISC_ID); - val =3D xa_load(&npc_priv.xa_pf2dfl_rmap, idx); + 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__, @@ -4207,7 +4205,7 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 = pcifunc, u16 *bcast, return -EINVAL; =20 idx =3D NPC_DFT_RULE_ID_MK(pcifunc, NPC_DFT_RULE_UCAST_ID); - val =3D xa_load(&npc_priv.xa_pf2dfl_rmap, idx); + 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__, @@ -4227,7 +4225,7 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 = pcifunc, u16 *bcast, continue; =20 idx =3D NPC_DFT_RULE_ID_MK(pcifunc, i); - val =3D xa_load(&npc_priv.xa_pf2dfl_rmap, idx); + 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__, @@ -4251,8 +4249,8 @@ int rvu_mbox_handler_npc_get_pfl_info(struct rvu *rvu= , struct msg_req *req, return -EOPNOTSUPP; } =20 - rsp->kw_type =3D npc_priv.kw; - rsp->x4_slots =3D npc_priv.bank_depth; + rsp->kw_type =3D npc_priv->kw; + rsp->x4_slots =3D npc_priv->bank_depth; return 0; } =20 @@ -4342,7 +4340,7 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pc= ifunc) int blkaddr, rc, i; void *map; =20 - if (!npc_priv.init_done) + if (!npc_priv) return; =20 if (!npc_is_cgx_or_lbk(rvu, pcifunc)) { @@ -4360,7 +4358,7 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pc= ifunc) /* 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); + 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", @@ -4374,7 +4372,7 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pc= ifunc) /* 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); + 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", @@ -4388,7 +4386,7 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pc= ifunc) /* 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); + 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", @@ -4448,7 +4446,7 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) struct msg_rsp free_rsp; u16 b, m, p, u; =20 - if (!npc_priv.init_done) + if (!npc_priv) return 0; =20 if (!npc_is_cgx_or_lbk(rvu, pcifunc)) { @@ -4471,7 +4469,7 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) } =20 /* Set ref index as lowest priority index */ - eidx =3D 2 * npc_priv.bank_depth - 1; + eidx =3D 2 * npc_priv->bank_depth - 1; =20 /* Install only UCAST for VF */ cnt =3D is_vf(pcifunc) ? 1 : ARRAY_SIZE(mcam_idx); @@ -4500,9 +4498,9 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) pfvf =3D rvu_get_pfvf(rvu, pcifunc); pfvf->hw_prio =3D NPC_DFT_RULE_PRIO; =20 - if (npc_priv.kw =3D=3D NPC_MCAM_KEY_X4) { + if (npc_priv->kw =3D=3D NPC_MCAM_KEY_X4) { req.kw_type =3D NPC_MCAM_KEY_X4; - req.ref_entry =3D eidx & (npc_priv.bank_depth - 1); + req.ref_entry =3D eidx & (npc_priv->bank_depth - 1); } else { req.kw_type =3D NPC_MCAM_KEY_X2; req.ref_entry =3D eidx; @@ -4543,9 +4541,9 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) req.hdr.pcifunc =3D pcifunc; req.ref_prio =3D NPC_MCAM_LOWER_PRIO; =20 - if (npc_priv.kw =3D=3D NPC_MCAM_KEY_X4) { + if (npc_priv->kw =3D=3D NPC_MCAM_KEY_X4) { req.kw_type =3D NPC_MCAM_KEY_X4; - req.ref_entry =3D eidx & (npc_priv.bank_depth - 1); + req.ref_entry =3D eidx & (npc_priv->bank_depth - 1); } else { req.kw_type =3D NPC_MCAM_KEY_X2; req.ref_entry =3D eidx; @@ -4569,7 +4567,7 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) /* 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, + ret =3D xa_insert(&npc_priv->xa_pf2dfl_rmap, index, xa_mk_value(mcam_idx[0]), GFP_KERNEL); if (ret) { dev_err(rvu->dev, @@ -4586,7 +4584,7 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) /* 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, + ret =3D xa_insert(&npc_priv->xa_pf2dfl_rmap, index, xa_mk_value(mcam_idx[0]), GFP_KERNEL); if (ret) { dev_err(rvu->dev, @@ -4604,7 +4602,7 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) 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, + ret =3D xa_insert(&npc_priv->xa_pf2dfl_rmap, index, xa_mk_value(mcam_idx[k]), GFP_KERNEL); if (ret) { dev_err(rvu->dev, @@ -4613,7 +4611,7 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pc= ifunc) 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); + xa_erase(&npc_priv->xa_pf2dfl_rmap, index); } goto err; } @@ -4687,71 +4685,79 @@ static int npc_priv_init(struct rvu *rvu) return -EINVAL; } =20 - npc_priv.num_subbanks =3D num_subbanks; - npc_priv.bank_depth =3D bank_depth; - npc_priv.subbank_depth =3D subbank_depth; + npc_priv =3D kcalloc(1, sizeof(*npc_priv), GFP_KERNEL); + if (!npc_priv) + return -ENOMEM; + + npc_priv->num_banks =3D num_banks; + npc_priv->num_subbanks =3D num_subbanks; + npc_priv->bank_depth =3D bank_depth; + npc_priv->subbank_depth =3D subbank_depth; =20 /* Get kex configured key size */ cfg =3D rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(0)); - npc_priv.kw =3D FIELD_GET(GENMASK_ULL(34, 32), cfg); + npc_priv->kw =3D FIELD_GET(GENMASK_ULL(34, 32), cfg); =20 dev_info(rvu->dev, "banks=3D%u depth=3D%u, subbanks=3D%u depth=3D%u, key type=3D%s\n", num_banks, bank_depth, num_subbanks, subbank_depth, - npc_kw_name[npc_priv.kw]); + npc_kw_name[npc_priv->kw]); =20 - npc_priv.sb =3D kcalloc(num_subbanks, sizeof(struct npc_subbank), - GFP_KERNEL); - if (!npc_priv.sb) - return -ENOMEM; + npc_priv->sb =3D kcalloc(num_subbanks, sizeof(struct npc_subbank), + GFP_KERNEL); + if (!npc_priv->sb) + goto fail1; =20 - xa_init_flags(&npc_priv.xa_sb_used, XA_FLAGS_ALLOC); - 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); - xa_init_flags(&npc_priv.xa_idx2vidx_map, XA_FLAGS_ALLOC); - xa_init_flags(&npc_priv.xa_vidx2idx_map, XA_FLAGS_ALLOC); + xa_init_flags(&npc_priv->xa_sb_used, XA_FLAGS_ALLOC); + 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); + xa_init_flags(&npc_priv->xa_idx2vidx_map, XA_FLAGS_ALLOC); + xa_init_flags(&npc_priv->xa_vidx2idx_map, XA_FLAGS_ALLOC); =20 if (npc_create_srch_order(num_subbanks)) - goto fail1; + goto fail2; =20 npc_populate_restricted_idxs(num_subbanks); =20 /* Initialize subbanks */ - for (i =3D 0, sb =3D npc_priv.sb; i < num_subbanks; i++, sb++) + for (i =3D 0, sb =3D npc_priv->sb; i < num_subbanks; i++, sb++) npc_subbank_init(rvu, sb, i); =20 /* Get number of pcifuncs in the system */ - npc_priv.pf_cnt =3D npc_pcifunc_map_create(rvu); - npc_priv.xa_pf2idx_map =3D kcalloc(npc_priv.pf_cnt, - sizeof(struct xarray), - GFP_KERNEL); - if (!npc_priv.xa_pf2idx_map) - goto fail2; + npc_priv->pf_cnt =3D npc_pcifunc_map_create(rvu); + npc_priv->xa_pf2idx_map =3D kcalloc(npc_priv->pf_cnt, + sizeof(struct xarray), + GFP_KERNEL); + if (!npc_priv->xa_pf2idx_map) + goto fail3; =20 - for (i =3D 0; i < npc_priv.pf_cnt; i++) - xa_init_flags(&npc_priv.xa_pf2idx_map[i], XA_FLAGS_ALLOC); + for (i =3D 0; i < npc_priv->pf_cnt; i++) + xa_init_flags(&npc_priv->xa_pf2idx_map[i], XA_FLAGS_ALLOC); =20 - INIT_LIST_HEAD(&npc_priv.defrag_lh); - mutex_init(&npc_priv.lock); + INIT_LIST_HEAD(&npc_priv->defrag_lh); + mutex_init(&npc_priv->lock); =20 return 0; =20 -fail2: +fail3: kfree(subbank_srch_order); subbank_srch_order =3D NULL; =20 +fail2: + xa_destroy(&npc_priv->xa_sb_used); + 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); + xa_destroy(&npc_priv->xa_idx2vidx_map); + xa_destroy(&npc_priv->xa_vidx2idx_map); + kfree(npc_priv->sb); + npc_priv->sb =3D NULL; fail1: - xa_destroy(&npc_priv.xa_sb_used); - 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); - xa_destroy(&npc_priv.xa_idx2vidx_map); - xa_destroy(&npc_priv.xa_vidx2idx_map); - kfree(npc_priv.sb); - npc_priv.sb =3D NULL; + kfree(npc_priv); + npc_priv =3D NULL; return -ENOMEM; } =20 @@ -4759,25 +4765,31 @@ void npc_cn20k_deinit(struct rvu *rvu) { int i; =20 - xa_destroy(&npc_priv.xa_sb_used); - 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); - xa_destroy(&npc_priv.xa_idx2vidx_map); - xa_destroy(&npc_priv.xa_vidx2idx_map); + if (!npc_priv) + return; =20 - for (i =3D 0; i < npc_priv.pf_cnt; i++) - xa_destroy(&npc_priv.xa_pf2idx_map[i]); + xa_destroy(&npc_priv->xa_sb_used); + 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); + xa_destroy(&npc_priv->xa_idx2vidx_map); + xa_destroy(&npc_priv->xa_vidx2idx_map); =20 - kfree(npc_priv.xa_pf2idx_map); + for (i =3D 0; i < npc_priv->pf_cnt; i++) + xa_destroy(&npc_priv->xa_pf2idx_map[i]); + + kfree(npc_priv->xa_pf2idx_map); /* No need to destroy mutex lock as it is * part of subbank structure */ - kfree(npc_priv.sb); + kfree(npc_priv->sb); kfree(subbank_srch_order); - bitmap_clear(npc_priv.en_map, 0, MAX_NUM_BANKS * MAX_NUM_SUB_BANKS * + bitmap_clear(npc_priv->en_map, 0, MAX_NUM_BANKS * MAX_NUM_SUB_BANKS * MAX_SUBBANK_DEPTH); + npc_defrag_list_clear(); + kfree(npc_priv); + npc_priv =3D NULL; } =20 static int npc_setup_mcam_section(struct rvu *rvu, int key_type) @@ -4790,7 +4802,7 @@ static int npc_setup_mcam_section(struct rvu *rvu, in= t key_type) return -ENODEV; } =20 - for (sec =3D 0; sec < npc_priv.num_subbanks; sec++) + for (sec =3D 0; sec < npc_priv->num_subbanks; sec++) rvu_write64(rvu, blkaddr, NPC_AF_MCAM_SECTIONX_CFG_EXT(sec), key_type); =20 @@ -4812,10 +4824,12 @@ int npc_cn20k_init(struct rvu *rvu) if (err) { dev_err(rvu->dev, "%s: mcam section configuration failure\n", __func__); - return err; + goto fail; } =20 - npc_priv.init_done =3D true; - return 0; + +fail: + npc_cn20k_deinit(rvu); + return err; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/npc.h index 8bf857317e49..10e5bab50f62 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h @@ -183,7 +183,6 @@ struct npc_defrag_show_node { * @xa_idx2pf_map: Mcam index to PF map. * @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. * @xa_idx2vidx_map: Mcam index to virtual index map. * @xa_vidx2idx_map: virtual index to mcam index map. @@ -195,7 +194,7 @@ struct npc_defrag_show_node { */ struct npc_priv_t { int bank_depth; - const int num_banks; + int num_banks; int num_subbanks; int subbank_depth; DECLARE_BITMAP(en_map, MAX_NUM_BANKS * @@ -214,7 +213,6 @@ struct npc_priv_t { struct list_head defrag_lh; struct mutex lock; /* protect defrag nodes */ int pf_cnt; - bool init_done; }; =20 struct npc_kpm_action0 { --=20 2.43.0