From: Ratheesh Kannoth <rkannoth@marvell.com>
To: <netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <sgoutham@marvell.com>, <davem@davemloft.net>,
<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
<horms@kernel.org>, <donald.hunter@gmail.com>, <jiri@resnulli.us>,
<chuck.lever@oracle.com>, <matttbe@kernel.org>,
<cjubran@nvidia.com>, <shshitrit@nvidia.com>,
<dtatulea@nvidia.com>, <tariqt@nvidia.com>,
Ratheesh Kannoth <rkannoth@marvell.com>
Subject: [PATCH v7 net-next 1/5] octeontx2-af: npc: cn20k: debugfs enhancements
Date: Mon, 23 Mar 2026 09:21:06 +0530 [thread overview]
Message-ID: <20260323035110.3908741-2-rkannoth@marvell.com> (raw)
In-Reply-To: <20260323035110.3908741-1-rkannoth@marvell.com>
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: reports recently hit MCAM indices with
packet counts; stats are cleared on read so each read shows deltas.
- Add "mismatch" debugfs entry: lists MCAM entries that are enabled
but not explicitly allocated, helping diagnose allocation/field issues.
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../marvell/octeontx2/af/cn20k/debugfs.c | 126 +++++++++++++++++-
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 16 ++-
.../ethernet/marvell/octeontx2/af/cn20k/npc.h | 7 +
3 files changed, 135 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c
index 3debf2fae1a4..e8f85ed5ead7 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"
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);
}
- 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, void *unused)
vidx1);
}
- 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 : " ");
continue;
}
@@ -120,8 +126,9 @@ static int npc_mcam_layout_show(struct seq_file *s, void *unused)
vidx0);
}
- 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;
}
@@ -134,7 +141,8 @@ static int npc_mcam_layout_show(struct seq_file *s, void *unused)
snprintf(buf1, sizeof(buf1), "v:%05u", vidx1);
}
- 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,100 @@ static int npc_mcam_layout_show(struct seq_file *s, void *unused)
DEFINE_SHOW_ATTRIBUTE(npc_mcam_layout);
+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;
+ int blkaddr, pf, mcam_idx;
+ u64 stats, delta;
+ struct rvu *rvu;
+ u8 key_type;
+ void *map;
+
+ npc_priv = npc_priv_get();
+ rvu = s->private;
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+ if (blkaddr < 0)
+ return 0;
+
+ seq_puts(s, "idx\tpfunc\tstats\n");
+ for (int bank = npc_priv->num_banks - 1; bank >= 0; bank--) {
+ for (int idx = npc_priv->bank_depth - 1; idx >= 0; idx--) {
+ mcam_idx = bank * npc_priv->bank_depth + idx;
+
+ npc_mcam_idx_2_key_type(rvu, mcam_idx, &key_type);
+ if (key_type == NPC_MCAM_KEY_X4 && bank != 0)
+ continue;
+
+ if (!test_bit(mcam_idx, npc_priv->en_map))
+ continue;
+
+ stats = rvu_read64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(idx, bank));
+ if (!stats)
+ continue;
+ if (stats == dstats[bank][idx])
+ continue;
+
+ if (stats < dstats[bank][idx])
+ dstats[bank][idx] = 0;
+
+ pf = 0xFFFF;
+ map = xa_load(&npc_priv->xa_idx2pf_map, mcam_idx);
+ if (map)
+ pf = xa_to_value(map);
+
+ if (stats > dstats[bank][idx])
+ delta = stats - dstats[bank][idx];
+ else
+ delta = stats;
+
+ seq_printf(s, "%u\t%#04x\t%llu\n",
+ mcam_idx, pf, delta);
+ dstats[bank][idx] = stats;
+ }
+ }
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(npc_mcam_dstats);
+
+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;
+ void *map;
+ int rc;
+
+ npc_priv = npc_priv_get();
+ rvu = s->private;
+
+ seq_puts(s, "index\tsb idx\tkw type\n");
+ for (int bank = npc_priv->num_banks - 1; bank >= 0; bank--) {
+ for (int idx = npc_priv->bank_depth - 1; idx >= 0; idx--) {
+ mcam_idx = bank * npc_priv->bank_depth + idx;
+
+ if (!test_bit(mcam_idx, npc_priv->en_map))
+ continue;
+
+ map = xa_load(&npc_priv->xa_idx2pf_map, mcam_idx);
+ if (map)
+ continue;
+
+ rc = npc_mcam_idx_2_subbank_idx(rvu, mcam_idx,
+ &sb, &sb_off);
+ if (rc)
+ continue;
+
+ seq_printf(s, "%u\t%d\t%u\n", mcam_idx, sb->idx,
+ sb->key_type);
+ }
+ }
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(npc_mcam_mismatch);
+
static int npc_mcam_default_show(struct seq_file *s, void *unused)
{
struct npc_priv_t *npc_priv;
@@ -257,6 +359,16 @@ int npc_cn20k_debugfs_init(struct rvu *rvu)
if (!npc_dentry)
return -EFAULT;
+ npc_dentry = debugfs_create_file("dstats", 0444, rvu->rvu_dbg.npc, rvu,
+ &npc_mcam_dstats_fops);
+ if (!npc_dentry)
+ return -EFAULT;
+
+ npc_dentry = debugfs_create_file("mismatch", 0444, rvu->rvu_dbg.npc, rvu,
+ &npc_mcam_mismatch_fops);
+ if (!npc_dentry)
+ return -EFAULT;
+
npc_dentry = debugfs_create_file("mcam_default", 0444, rvu->rvu_dbg.npc,
rvu, &npc_mcam_default_fops);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 7291fdb89b03..e854b85ced9e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -808,6 +808,9 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
u64 cfg, hw_prio;
u8 kw_type;
+ enable ? set_bit(index, npc_priv.en_map) :
+ clear_bit(index, npc_priv.en_map);
+
npc_mcam_idx_2_key_type(rvu, index, &kw_type);
if (kw_type == NPC_MCAM_KEY_X2) {
cfg = rvu_read64(rvu, blkaddr,
@@ -1016,14 +1019,12 @@ static void npc_cn20k_config_kw_x4(struct rvu *rvu, struct npc_mcam *mcam,
static void
npc_cn20k_set_mcam_bank_cfg(struct rvu *rvu, int blkaddr, int mcam_idx,
- int bank, u8 kw_type, bool enable, u8 hw_prio)
+ int bank, u8 kw_type, u8 hw_prio)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
u64 bank_cfg;
bank_cfg = (u64)hw_prio << 24;
- if (enable)
- bank_cfg |= 0x1;
if (kw_type == NPC_MCAM_KEY_X2) {
rvu_write64(rvu, blkaddr,
@@ -1119,7 +1120,8 @@ void npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
/* TODO: */
/* PF installing VF rule */
npc_cn20k_set_mcam_bank_cfg(rvu, blkaddr, mcam_idx, bank,
- kw_type, enable, hw_prio);
+ kw_type, hw_prio);
+ npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable);
}
void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
@@ -1735,9 +1737,9 @@ static int npc_subbank_idx_2_mcam_idx(struct rvu *rvu, struct npc_subbank *sb,
return 0;
}
-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;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
index 815d0b257a7e..004a556c7b90 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
@@ -170,6 +170,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 +194,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 +340,8 @@ int npc_mcam_idx_2_key_type(struct rvu *rvu, u16 mcam_idx, u8 *key_type);
u16 npc_cn20k_vidx2idx(u16 index);
u16 npc_cn20k_idx2vidx(u16 idx);
int npc_cn20k_defrag(struct rvu *rvu);
+int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx,
+ struct npc_subbank **sb,
+ int *sb_off);
#endif /* NPC_CN20K_H */
--
2.43.0
next prev parent reply other threads:[~2026-03-23 3:51 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-23 3:51 [PATCH v7 net-next 0/5] octeontx2-af: npc: Enhancements Ratheesh Kannoth
2026-03-23 3:51 ` Ratheesh Kannoth [this message]
2026-03-23 3:51 ` [PATCH v7 net-next 2/5] devlink: Implement devlink param multi attribute nested data values Ratheesh Kannoth
2026-03-24 16:09 ` Simon Horman
2026-03-23 3:51 ` [PATCH v7 net-next 3/5] octeontx2-af: npc: cn20k: add subbank search order control Ratheesh Kannoth
2026-03-23 3:51 ` [PATCH v7 net-next 4/5] octeontx2-af: npc: cn20k: dynamically allocate and free default MCAM entries Ratheesh Kannoth
2026-03-23 3:51 ` [PATCH v7 net-next 5/5] octeontx2-af: npc: Support for custom KPU profile from filesystem Ratheesh Kannoth
2026-03-24 16:36 ` Simon Horman
2026-03-25 3:14 ` Ratheesh Kannoth
2026-03-25 16:42 ` Simon Horman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260323035110.3908741-2-rkannoth@marvell.com \
--to=rkannoth@marvell.com \
--cc=chuck.lever@oracle.com \
--cc=cjubran@nvidia.com \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=dtatulea@nvidia.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matttbe@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sgoutham@marvell.com \
--cc=shshitrit@nvidia.com \
--cc=tariqt@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox