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 --- .../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..7414986c3fdd 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) ? '+' : 0, 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) ? '+' : 0, + v1 ? buf1 : " ", + idx0, pf1, + test_bit(idx0, npc_priv->en_map) ? '+' : 0, + 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) ? '+' : 0, + 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) ? '+' : 0, 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