* [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes
@ 2026-04-20 2:34 Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k Ratheesh Kannoth
` (11 more replies)
0 siblings, 12 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth
This series tightens Marvell OcteonTX2 AF NPC support for CN20K
silicon around MCAM key typing, optional debugfs setup, defrag
allocation rollback, x2 versus x4 KEX profiles and default-rule
allocation, logical MCAM clear and configuration, default-rule index
bookkeeping and explicit teardown, and NIXLF reserved-slot lookup when
default rules are missing.
Patches 1 through 3 focus on AF error handling: propagate
npc_mcam_idx_2_key_type() failures through cn20k MCAM enable, config,
copy, and read paths; treat cn20k NPC debugfs files as optional so
probe does not fail when debugfs is unavailable; and fix defrag MCAM
allocation rollback so allocation errno is not overwritten by subbank
index resolution.
Patches 4 and 5 align default-rule and flow-install behaviour with the
loaded mkex profile: prefer x4 default entries when the profile is x4,
and reject x4 flow keys when the profile is strictly x2.
Patches 6 through 8 refine cn20k MCAM programming: clear entries by
logical index and resolved key width, fix bank and CFG sequencing in
npc_cn20k_config_mcam_entry(), and read action metadata from the
correct bank in npc_cn20k_read_mcam_entry().
Patches 9 through 11 complete default-rule lifecycle handling:
initialize all default-rule index outputs up front, tear down default
MCAM rules explicitly (coordinated with npc_mcam_free_all_entries()),
and reject USHRT_MAX sentinel indices in npc_get_nixlf_mcam_index()
for cn20k.
Ratheesh Kannoth (11):
octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in
init
octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc
rollback
octeontx2-af: npc: cn20k: Make default entries as x4.
octeontx2-af: npc: cn20k: Reject request for x4 entries in x2
profile.
octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width
octeontx2-af: npc: cn20k: Fix bank value.
octeontx2-af: npc: cn20k: Fix MCAM actions read
octeontx2-af: npc: cn20k: Initialize default-rule index outputs up
front
octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on
free
octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
--
v1 -> v2: Addressed simon comments. Added more patch fixes to this series.
https://lore.kernel.org/netdev/20260418162013.GG280379@horms.kernel.org/
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-23 9:38 ` [v2,net,01/11] " Paolo Abeni
2026-04-23 10:01 ` [PATCH v2 net 01/11] " Simon Horman
2026-04-20 2:34 ` [PATCH v2 net 02/11] octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in init Ratheesh Kannoth
` (10 subsequent siblings)
11 siblings, 2 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Suman Ghosh, Dan Carpenter
npc_mcam_idx_2_key_type() can fail; callers used to ignore it and still
used kw_type when enabling, configuring, copying, and reading MCAM
entries. That could program or decode hardware with an undefined key
type.
Return -EINVAL when key-type lookup fails. Return -EINVAL from
npc_cn20k_copy_mcam_entry() when src and dest key types differ instead
of failing silently.
Change npc_cn20k_{enable,config,copy,read}_mcam_entry() to return int on
success or error. Thread those errors through the cn20k MCAM write and
read mbox handlers, the cn20k baseline steer read path, NPC defrag
move (disable/copy/enable with dev_err and -EFAULT), and the DMAC
update path in rvu_npc_fs.c.
Make npc_copy_mcam_entry() return int so the cn20k branch can return
npc_cn20k_copy_mcam_entry() without a void/int mismatch, and fail
NPC_MCAM_SHIFT_ENTRY when copy fails.
Cc: Suman Ghosh <sumang@marvell.com>
Cc: Dan Carpenter <error27@gmail.com>
Fixes: 6d1e70282f76 ("octeontx2-af: npc: cn20k: Use common APIs")
Link: https://lore.kernel.org/netdev/adiQJvuKlEhq2ILx@stanley.mountain/
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 107 ++++++++++++------
.../ethernet/marvell/octeontx2/af/cn20k/npc.h | 20 ++--
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 13 ++-
.../marvell/octeontx2/af/rvu_npc_fs.c | 12 +-
4 files changed, 100 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 7291fdb89b03..18d70f4527d1 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -798,7 +798,7 @@ void npc_cn20k_load_mkex_profile(struct rvu *rvu, int blkaddr,
iounmap(mkex_prfl_addr);
}
-void
+int
npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
int index, bool enable)
{
@@ -808,7 +808,9 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
u64 cfg, hw_prio;
u8 kw_type;
- npc_mcam_idx_2_key_type(rvu, index, &kw_type);
+ if (npc_mcam_idx_2_key_type(rvu, index, &kw_type))
+ return -EINVAL;
+
if (kw_type == NPC_MCAM_KEY_X2) {
cfg = rvu_read64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx,
@@ -819,7 +821,7 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
cfg);
- return;
+ return 0;
}
/* For NPC_CN20K_MCAM_KEY_X4 keys, both the banks
@@ -836,6 +838,8 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
cfg);
}
+
+ return 0;
}
void
@@ -1042,9 +1046,9 @@ npc_cn20k_set_mcam_bank_cfg(struct rvu *rvu, int blkaddr, int mcam_idx,
}
}
-void npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
- u8 intf, struct cn20k_mcam_entry *entry,
- bool enable, u8 hw_prio, u8 req_kw_type)
+int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
+ u8 intf, struct cn20k_mcam_entry *entry,
+ bool enable, u8 hw_prio, u8 req_kw_type)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int mcam_idx = index % mcam->banksize;
@@ -1052,10 +1056,13 @@ void npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
int kw = 0;
u8 kw_type;
+ if (npc_mcam_idx_2_key_type(rvu, index, &kw_type))
+ return -EINVAL;
+
/* Disable before mcam entry update */
- npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, false);
+ if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, false))
+ return -EINVAL;
- npc_mcam_idx_2_key_type(rvu, index, &kw_type);
/* CAM1 takes the comparison value and
* CAM0 specifies match for a bit in key being '0' or '1' or 'dontcare'.
* CAM1<n> = 0 & CAM0<n> = 1 => match if key<n> = 0
@@ -1120,9 +1127,11 @@ void npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
/* PF installing VF rule */
npc_cn20k_set_mcam_bank_cfg(rvu, blkaddr, mcam_idx, bank,
kw_type, enable, hw_prio);
+
+ return 0;
}
-void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
+int npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
u64 cfg, sreg, dreg, soff, doff;
@@ -1132,10 +1141,15 @@ void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
dbank = npc_get_bank(mcam, dest);
sbank = npc_get_bank(mcam, src);
- npc_mcam_idx_2_key_type(rvu, src, &src_kwtype);
- npc_mcam_idx_2_key_type(rvu, dest, &dest_kwtype);
+
+ if (npc_mcam_idx_2_key_type(rvu, src, &src_kwtype))
+ return -EINVAL;
+
+ if (npc_mcam_idx_2_key_type(rvu, dest, &dest_kwtype))
+ return -EINVAL;
+
if (src_kwtype != dest_kwtype)
- return;
+ return -EINVAL;
src &= (mcam->banksize - 1);
dest &= (mcam->banksize - 1);
@@ -1170,6 +1184,8 @@ void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
if (src_kwtype == NPC_MCAM_KEY_X2)
break;
}
+
+ return 0;
}
static void npc_cn20k_fill_entryword(struct cn20k_mcam_entry *entry, int idx,
@@ -1179,16 +1195,17 @@ static void npc_cn20k_fill_entryword(struct cn20k_mcam_entry *entry, int idx,
entry->kw_mask[idx] = cam1 ^ cam0;
}
-void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
- struct cn20k_mcam_entry *entry,
- u8 *intf, u8 *ena, u8 *hw_prio)
+int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
+ struct cn20k_mcam_entry *entry,
+ u8 *intf, u8 *ena, u8 *hw_prio)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
u64 cam0, cam1, bank_cfg, cfg;
int kw = 0, bank;
u8 kw_type;
- npc_mcam_idx_2_key_type(rvu, index, &kw_type);
+ if (npc_mcam_idx_2_key_type(rvu, index, &kw_type))
+ return -EINVAL;
bank = npc_get_bank(mcam, index);
index &= (mcam->banksize - 1);
@@ -1298,6 +1315,8 @@ void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
cfg = rvu_read64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, 0, 1));
entry->vtag_action = cfg;
+
+ return 0;
}
int rvu_mbox_handler_npc_cn20k_mcam_write_entry(struct rvu *rvu,
@@ -1335,11 +1354,10 @@ int rvu_mbox_handler_npc_cn20k_mcam_write_entry(struct rvu *rvu,
if (is_pffunc_af(req->hdr.pcifunc))
nix_intf = req->intf;
- npc_cn20k_config_mcam_entry(rvu, blkaddr, req->entry, nix_intf,
- &req->entry_data, req->enable_entry,
- req->hw_prio, req->req_kw_type);
+ rc = npc_cn20k_config_mcam_entry(rvu, blkaddr, req->entry, nix_intf,
+ &req->entry_data, req->enable_entry,
+ req->hw_prio, req->req_kw_type);
- rc = 0;
exit:
mutex_unlock(&mcam->lock);
return rc;
@@ -1361,11 +1379,13 @@ int rvu_mbox_handler_npc_cn20k_mcam_read_entry(struct rvu *rvu,
mutex_lock(&mcam->lock);
rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
- if (!rc)
- npc_cn20k_read_mcam_entry(rvu, blkaddr, req->entry,
- &rsp->entry_data, &rsp->intf,
- &rsp->enable, &rsp->hw_prio);
+ if (rc)
+ goto fail;
+ rc = npc_cn20k_read_mcam_entry(rvu, blkaddr, req->entry,
+ &rsp->entry_data, &rsp->intf,
+ &rsp->enable, &rsp->hw_prio);
+fail:
mutex_unlock(&mcam->lock);
return rc;
}
@@ -1415,9 +1435,9 @@ int rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry(struct rvu *rvu,
else
nix_intf = pfvf->nix_rx_intf;
- npc_cn20k_config_mcam_entry(rvu, blkaddr, entry, nix_intf,
- &req->entry_data, req->enable_entry,
- req->hw_prio, req->req_kw_type);
+ rc = npc_cn20k_config_mcam_entry(rvu, blkaddr, entry, nix_intf,
+ &req->entry_data, req->enable_entry,
+ req->hw_prio, req->req_kw_type);
mutex_unlock(&mcam->lock);
@@ -1480,9 +1500,9 @@ int rvu_mbox_handler_npc_cn20k_read_base_steer_rule(struct rvu *rvu,
read_entry:
/* Read the mcam entry */
- npc_cn20k_read_mcam_entry(rvu, blkaddr, index,
- &rsp->entry, &intf,
- &enable, &hw_prio);
+ rc = npc_cn20k_read_mcam_entry(rvu, blkaddr, index,
+ &rsp->entry, &intf,
+ &enable, &hw_prio);
mutex_unlock(&mcam->lock);
out:
return rc;
@@ -3607,9 +3627,30 @@ int npc_defrag_move_vdx_to_free(struct rvu *rvu,
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(midx,
bank));
- npc_cn20k_enable_mcam_entry(rvu, blkaddr, old_midx, false);
- npc_cn20k_copy_mcam_entry(rvu, blkaddr, old_midx, new_midx);
- npc_cn20k_enable_mcam_entry(rvu, blkaddr, new_midx, true);
+ /* If bug happened during copy/enable mcam, then there is a bug in allocation
+ * algorithm itself. There is no point in rewinding and returning, as it
+ * will face further issue. Return error after printing error
+ */
+ if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, old_midx, false)) {
+ dev_err(rvu->dev,
+ "%s: Error happened while disabling old_mid=%u\n",
+ __func__, old_midx);
+ return -EFAULT;
+ }
+
+ if (npc_cn20k_copy_mcam_entry(rvu, blkaddr, old_midx, new_midx)) {
+ dev_err(rvu->dev,
+ "%s: Error happened to while copying old_midx=%u new_midx=%u\n",
+ __func__, old_midx, new_midx);
+ return -EFAULT;
+ }
+
+ if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, new_midx, true)) {
+ dev_err(rvu->dev,
+ "%s: Error happened while enabling new_mid=%u\n",
+ __func__, new_midx);
+ return -EFAULT;
+ }
midx = new_midx % mcam->banksize;
bank = new_midx / mcam->banksize;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
index 815d0b257a7e..8f3eea9cfb1d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
@@ -320,16 +320,16 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc);
int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
u16 *mcast, u16 *promisc, u16 *ucast);
-void npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
- u8 intf, struct cn20k_mcam_entry *entry,
- bool enable, u8 hw_prio, u8 req_kw_type);
-void npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
- int index, bool enable);
-void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr,
- u16 src, u16 dest);
-void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
- struct cn20k_mcam_entry *entry, u8 *intf,
- u8 *ena, u8 *hw_prio);
+int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
+ u8 intf, struct cn20k_mcam_entry *entry,
+ bool enable, u8 hw_prio, u8 req_kw_type);
+int npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
+ int index, bool enable);
+int npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr,
+ u16 src, u16 dest);
+int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
+ struct cn20k_mcam_entry *entry, u8 *intf,
+ u8 *ena, u8 *hw_prio);
void npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr,
int bank, int index);
int npc_mcam_idx_2_key_type(struct rvu *rvu, u16 mcam_idx, u8 *key_type);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index c2ca5ed1d028..762fafd4ccb7 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -241,7 +241,8 @@ void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
if (index < 0 || index >= mcam->banksize * mcam->banks)
return;
- return npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable);
+ npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable);
+ return;
}
index &= (mcam->banksize - 1);
@@ -589,8 +590,8 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
NPC_AF_MCAMEX_BANKX_CFG(src, sbank)) & 1;
}
-static void npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
- int blkaddr, u16 src, u16 dest)
+static int npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
+ int blkaddr, u16 src, u16 dest)
{
int dbank = npc_get_bank(mcam, dest);
int sbank = npc_get_bank(mcam, src);
@@ -630,6 +631,7 @@ static void npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
NPC_AF_MCAMEX_BANKX_CFG(src, sbank));
rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CFG(dest, dbank), cfg);
+ return 0;
}
u64 npc_get_mcam_action(struct rvu *rvu, struct npc_mcam *mcam,
@@ -3266,7 +3268,10 @@ int rvu_mbox_handler_npc_mcam_shift_entry(struct rvu *rvu,
npc_enable_mcam_entry(rvu, mcam, blkaddr, new_entry, false);
/* Copy rule from old entry to new entry */
- npc_copy_mcam_entry(rvu, mcam, blkaddr, old_entry, new_entry);
+ if (npc_copy_mcam_entry(rvu, mcam, blkaddr, old_entry, new_entry)) {
+ rc = NPC_MCAM_INVALID_REQ;
+ break;
+ }
/* Copy counter mapping, if any */
cntr = mcam->entry2cntr_map[old_entry];
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
index b45798d9fdab..bd1488fe1611 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -1980,13 +1980,15 @@ static int npc_update_dmac_value(struct rvu *rvu, int npcblkaddr,
ether_addr_copy(rule->packet.dmac, pfvf->mac_addr);
- if (is_cn20k(rvu->pdev))
- npc_cn20k_read_mcam_entry(rvu, npcblkaddr, rule->entry,
- cn20k_entry, &intf,
- &enable, &hw_prio);
- else
+ if (is_cn20k(rvu->pdev)) {
+ if (npc_cn20k_read_mcam_entry(rvu, npcblkaddr, rule->entry,
+ cn20k_entry, &intf,
+ &enable, &hw_prio))
+ return -EINVAL;
+ } else {
npc_read_mcam_entry(rvu, mcam, npcblkaddr, rule->entry,
entry, &intf, &enable);
+ }
npc_update_entry(rvu, NPC_DMAC, &mdata,
ether_addr_to_u64(pfvf->mac_addr), 0,
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 02/11] octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in init
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 03/11] octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback Ratheesh Kannoth
` (9 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Dan Carpenter, Simon Horman
debugfs is not intended to be checked for allocation failures the way
other kernel APIs are: callers should not fail probe or subsystem init
because a debugfs node could not be created, including when debugfs is
disabled in Kconfig. Replacing NULL checks with IS_ERR() checks is
similarly wrong for optional debugfs.
Remove dentry checks and -EFAULT returns from npc_cn20k_debugfs_init().
https://staticthinking.wordpress.com/2023/07/24/debugfs-functions-are-not-supposed-to-be-checked/
Cc: Dan Carpenter <error27@gmail.com>
Fixes: 528530dff56b ("octeontx2-af: npc: cn20k: add debugfs support")
Link: https://lore.kernel.org/netdev/adjNGPWKMOk3KgWL@stanley.mountain/
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../marvell/octeontx2/af/cn20k/debugfs.c | 33 ++++++-------------
1 file changed, 10 insertions(+), 23 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..6f13296303cb 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c
@@ -249,34 +249,21 @@ DEFINE_SHOW_ATTRIBUTE(npc_defrag);
int npc_cn20k_debugfs_init(struct rvu *rvu)
{
struct npc_priv_t *npc_priv = npc_priv_get();
- struct dentry *npc_dentry;
- npc_dentry = debugfs_create_file("mcam_layout", 0444, rvu->rvu_dbg.npc,
- npc_priv, &npc_mcam_layout_fops);
+ debugfs_create_file("mcam_layout", 0444, rvu->rvu_dbg.npc,
+ npc_priv, &npc_mcam_layout_fops);
- if (!npc_dentry)
- return -EFAULT;
+ debugfs_create_file("mcam_default", 0444, rvu->rvu_dbg.npc,
+ rvu, &npc_mcam_default_fops);
- npc_dentry = debugfs_create_file("mcam_default", 0444, rvu->rvu_dbg.npc,
- rvu, &npc_mcam_default_fops);
+ debugfs_create_file("vidx2idx", 0444, rvu->rvu_dbg.npc,
+ npc_priv, &npc_vidx2idx_map_fops);
- if (!npc_dentry)
- return -EFAULT;
+ debugfs_create_file("idx2vidx", 0444, rvu->rvu_dbg.npc,
+ npc_priv, &npc_idx2vidx_map_fops);
- npc_dentry = debugfs_create_file("vidx2idx", 0444, rvu->rvu_dbg.npc,
- npc_priv, &npc_vidx2idx_map_fops);
- if (!npc_dentry)
- return -EFAULT;
-
- npc_dentry = debugfs_create_file("idx2vidx", 0444, rvu->rvu_dbg.npc,
- npc_priv, &npc_idx2vidx_map_fops);
- if (!npc_dentry)
- return -EFAULT;
-
- npc_dentry = debugfs_create_file("defrag", 0444, rvu->rvu_dbg.npc,
- npc_priv, &npc_defrag_fops);
- if (!npc_dentry)
- return -EFAULT;
+ debugfs_create_file("defrag", 0444, rvu->rvu_dbg.npc,
+ npc_priv, &npc_defrag_fops);
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 03/11] octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 02/11] octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in init Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-23 11:13 ` Simon Horman
2026-04-20 2:34 ` [PATCH v2 net 04/11] octeontx2-af: npc: cn20k: Make default entries as x4 Ratheesh Kannoth
` (8 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Dan Carpenter
npc_defrag_alloc_free_slots() allocates MCAM indexes in up to two passes
on bank0 then bank1. On failure it rolls back by freeing entries already
placed in save[].
__npc_subbank_alloc() can return a negative errno while only part of the
indexes are valid. The rollback loop used rc for
npc_mcam_idx_2_subbank_idx() as well, so a successful lookup stored zero
in rc and a later __npc_subbank_free() failure could still end with
return 0 when the allocation path had also left rc at zero
(for example shortfall after zero return values from the alloc helpers).
Jump to the rollback path immediately when either __npc_subbank_alloc()
call fails, preserving its errno. If both calls succeed but the total
allocated count is still less than cnt, set rc to -ENOSPC before rollback.
Use a separate err variable for npc_mcam_idx_2_subbank_idx() so a
successful lookup no longer clears a non-zero rc from the allocation
phase.
Cc: Dan Carpenter <error27@gmail.com>
Fixes: 645c6e3c1999 ("octeontx2-af: npc: cn20k: virtual index support")
Link: https://lore.kernel.org/netdev/adjNJEpILRZATB2N@stanley.mountain/
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../net/ethernet/marvell/octeontx2/af/cn20k/npc.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 18d70f4527d1..7f897ce0d17d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -3502,7 +3502,7 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
{
int alloc_cnt1, alloc_cnt2;
struct npc_subbank *sb;
- int rc, sb_off, i;
+ int rc, sb_off, i, err;
bool deleted;
sb = &npc_priv.sb[f->idx];
@@ -3516,6 +3516,9 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
NPC_MCAM_LOWER_PRIO,
false, cnt, save, cnt, true,
&alloc_cnt1);
+ if (rc)
+ goto fail_free_alloc;
+
if (alloc_cnt1 < cnt) {
rc = __npc_subbank_alloc(rvu, sb,
NPC_MCAM_KEY_X2, sb->b1b,
@@ -3525,21 +3528,25 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
save + alloc_cnt1,
cnt - alloc_cnt1,
true, &alloc_cnt2);
+ if (rc)
+ goto fail_free_alloc;
}
if (alloc_cnt1 + alloc_cnt2 != cnt) {
dev_err(rvu->dev,
"%s: Failed to alloc cnt=%u alloc_cnt1=%u alloc_cnt2=%u\n",
__func__, cnt, alloc_cnt1, alloc_cnt2);
+ rc = -ENOSPC;
goto fail_free_alloc;
}
+
return 0;
fail_free_alloc:
for (i = 0; i < alloc_cnt1 + alloc_cnt2; i++) {
- rc = npc_mcam_idx_2_subbank_idx(rvu, save[i],
- &sb, &sb_off);
- if (rc) {
+ err = npc_mcam_idx_2_subbank_idx(rvu, save[i],
+ &sb, &sb_off);
+ if (err) {
dev_err(rvu->dev,
"%s: Error to find subbank for mcam idx=%u\n",
__func__, save[i]);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 04/11] octeontx2-af: npc: cn20k: Make default entries as x4.
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (2 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 03/11] octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 05/11] octeontx2-af: npc: cn20k: Reject request for x4 entries in x2 profile Ratheesh Kannoth
` (7 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth
X4 profile users won't alloc x2 entries. Allocating x2 entries
would cause under utilized subbanks(X2). Avoid this in X4 kex
profile, all allocations will be from x4 subbank.
Fixes: 09d3b7a1403f ("octeontx2-af: npc: cn20k: Allocate default MCAM indexes")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 26 ++++++++--
.../marvell/octeontx2/nic/otx2_flows.c | 48 +++++++++++++------
2 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 7f897ce0d17d..108998b6d832 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -3592,9 +3592,10 @@ int npc_defrag_move_vdx_to_free(struct rvu *rvu,
struct npc_defrag_node *v,
int cnt, u16 *save)
{
+ u16 new_midx, old_midx, vidx, target_pf;
struct npc_mcam *mcam = &rvu->hw->mcam;
+ struct rvu_npc_mcam_rule *rule, *tmp;
int i, vidx_cnt, rc, sb_off;
- u16 new_midx, old_midx, vidx;
struct npc_subbank *sb;
bool deleted;
u16 pcifunc;
@@ -3713,8 +3714,21 @@ int npc_defrag_move_vdx_to_free(struct rvu *rvu,
mcam->entry2pfvf_map[new_midx] = pcifunc;
/* Counter is not preserved */
mcam->entry2cntr_map[new_midx] = new_midx;
+
+ target_pf = mcam->entry2target_pffunc[old_midx];
+ mcam->entry2target_pffunc[new_midx] = target_pf;
+ mcam->entry2target_pffunc[old_midx] = 0;
+
npc_mcam_set_bit(mcam, new_midx);
+ list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
+ if (rule->entry != old_midx)
+ continue;
+
+ rule->entry = new_midx;
+ break;
+ }
+
/* Mark as invalid */
v->vidx[vidx_cnt - i - 1] = -1;
save[cnt - i - 1] = -1;
@@ -4277,10 +4291,16 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc)
pfvf = rvu_get_pfvf(rvu, pcifunc);
pfvf->hw_prio = NPC_DFT_RULE_PRIO;
+ if (npc_priv.kw == NPC_MCAM_KEY_X4) {
+ req.kw_type = NPC_MCAM_KEY_X4;
+ req.ref_entry = eidx & (npc_priv.bank_depth - 1);
+ } else {
+ req.kw_type = NPC_MCAM_KEY_X2;
+ req.ref_entry = eidx;
+ }
+
req.contig = false;
req.ref_prio = NPC_MCAM_HIGHER_PRIO;
- req.ref_entry = eidx;
- req.kw_type = NPC_MCAM_KEY_X2;
req.count = cnt;
req.hdr.pcifunc = pcifunc;
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/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 = 0;
}
-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;
@@ -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 = pfl_info.is_x2;
*x4_slots = pfl_info.x4_slots;
+ *kw_type = 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;
}
- *is_x2 = (rsp->kw_type == NPC_MCAM_KEY_X2);
- if (*is_x2)
- *x4_slots = 0;
+ pfl_info.kw_type = rsp->kw_type;
+ if (rsp->kw_type == NPC_MCAM_KEY_X2)
+ pfl_info.x4_slots = 0;
else
- *x4_slots = rsp->x4_slots;
-
- pfl_info.is_x2 = *is_x2;
- pfl_info.x4_slots = *x4_slots;
+ pfl_info.x4_slots = rsp->x4_slots;
pfl_info.is_set = true;
+ *x4_slots = pfl_info.x4_slots;
+ *kw_type = 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 = 0, x4_slots = 0;
int ent, allocated = 0, ref;
bool is_x2 = false;
+ u8 kw_type = 0;
int rc;
/* Free current ones and allocate new ones with requested count */
@@ -182,12 +182,14 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)
}
if (is_cn20k(pfvf->pdev)) {
- rc = otx2_mcam_pfl_info_get(pfvf, &is_x2, &x4_slots);
+ rc = otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type);
if (rc) {
netdev_err(pfvf->netdev, "Error to retrieve profile info\n");
return rc;
}
+ is_x2 = kw_type == NPC_MCAM_KEY_X2;
+
rc = 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 = 0;
+ u16 x4_slots;
u16 dft_idx;
ref = 0;
@@ -315,6 +319,16 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf)
if (!flow_cfg->def_ent)
return -ENOMEM;
+ kw_type = NPC_MCAM_KEY_X2;
+ if (is_cn20k(pfvf->pdev)) {
+ rc = 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);
req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox);
@@ -324,6 +338,10 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf)
}
req->kw_type = NPC_MCAM_KEY_X2;
+ if (is_cn20k(pfvf->pdev) && kw_type == NPC_MCAM_KEY_X4) {
+ req->kw_type = NPC_MCAM_KEY_X4;
+ ref &= (x4_slots - 1);
+ }
req->contig = false;
req->count = count;
req->ref_prio = 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 = 0;
#endif
+ bool modify = false, is_x2;
int err, vf = 0, off, sz;
- bool modify = false;
u8 kw_type = 0;
u8 *src, *dst;
u16 x4_slots;
- bool is_x2;
if (is_cn20k(pfvf->pdev)) {
- err = otx2_mcam_pfl_info_get(pfvf, &is_x2, &x4_slots);
+ err = otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type);
if (err) {
netdev_err(pfvf->netdev,
"Error to retrieve NPC profile info, pcifunc=%#x\n",
@@ -1190,6 +1207,7 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow)
return -EFAULT;
}
+ is_x2 = kw_type == NPC_MCAM_KEY_X2;
if (!is_x2) {
err = otx2_prepare_flow_request(&flow->flow_spec,
&treq);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 05/11] octeontx2-af: npc: cn20k: Reject request for x4 entries in x2 profile.
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (3 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 04/11] octeontx2-af: npc: cn20k: Make default entries as x4 Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 06/11] octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width Ratheesh Kannoth
` (6 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth
Flow install mbox can alloc x2/x4 npc mcam entry based on
the flow entry size. If global kex profile is x2, x4 entries
won't work. Return error upon request for x4 entry in
x2 profile.
Fixes: 9000cada7aa9 ("octeontx2-af: npc: cn20k: Allocate MCAM entry for flow installation")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../net/ethernet/marvell/octeontx2/af/cn20k/npc.c | 10 ++++++++--
.../net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c | 12 +++++++++++-
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 108998b6d832..705fe7a877e6 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -4330,11 +4330,17 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc)
* as NPC_DFT_RULE_PRIO - 1 (higher hw priority)
*/
req.contig = false;
- req.kw_type = NPC_MCAM_KEY_X2;
req.count = cnt;
req.hdr.pcifunc = pcifunc;
req.ref_prio = NPC_MCAM_LOWER_PRIO;
- req.ref_entry = eidx + 1;
+ if (npc_priv.kw == NPC_MCAM_KEY_X4) {
+ req.kw_type = NPC_MCAM_KEY_X4;
+ req.ref_entry = (eidx + 1) & (npc_priv.bank_depth - 1);
+ } else {
+ req.kw_type = NPC_MCAM_KEY_X2;
+ req.ref_entry = eidx + 1;
+ }
+
ret = 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/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
index bd1488fe1611..d8945823e202 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -1663,9 +1663,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 = { 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;
if (!is_cn20k(rvu->pdev)) {
@@ -1689,8 +1691,16 @@ rvu_npc_alloc_entry_for_flow_install(struct rvu *rvu,
kw_bits = kws_rsp.kws * 64;
*kw_type = 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 == NPC_MCAM_KEY_X2) {
+ dev_err(rvu->dev,
+ "Only X2 entries are supported in X2 profile\n");
+ return -EOPNOTSUPP;
+ }
+
*kw_type = NPC_MCAM_KEY_X4;
+ }
memset(&entry_req, 0, sizeof(entry_req));
memset(&entry_rsp, 0, sizeof(entry_rsp));
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 06/11] octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (4 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 05/11] octeontx2-af: npc: cn20k: Reject request for x4 entries in x2 profile Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-23 9:39 ` [v2,net,06/11] " Paolo Abeni
2026-04-20 2:34 ` [PATCH v2 net 07/11] octeontx2-af: npc: cn20k: Fix bank value Ratheesh Kannoth
` (5 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Suman Ghosh
Replace the old four-argument CN20K MCAM clear with a per-bank static
helper and npc_cn20k_clear_mcam_entry() that takes a logical MCAM index,
resolves the key width via npc_mcam_idx_2_key_type(), and clears either
one bank (X2) or every bank (X4).
Call it from npc_clear_mcam_entry() on cn20k and log when key-type lookup
fails. Use the per-bank helper from npc_cn20k_config_mcam_entry() for
pre-program clears.
For loopback VFs, use the promisc MCAM index as ucast_idx when copying
RSS action for promisc, matching cn20k default-rule layout.
Cc: Suman Ghosh <sumang@marvell.com>
Fixes: 6d1e70282f76 ("octeontx2-af: npc: cn20k: Use common APIs")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 36 ++++++++++++++++---
.../ethernet/marvell/octeontx2/af/cn20k/npc.h | 3 +-
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 17 +++++++--
3 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 705fe7a877e6..7bfd39fe0f5e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -842,8 +842,8 @@ npc_cn20k_enable_mcam_entry(struct rvu *rvu, int blkaddr,
return 0;
}
-void
-npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int bank, int index)
+static void
+npc_clear_x2_entry(struct rvu *rvu, int blkaddr, int bank, int index)
{
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index, bank, 1),
@@ -877,6 +877,32 @@ npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int bank, int index)
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, bank), 0);
}
+int
+npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int mcam_idx)
+{
+ struct npc_mcam *mcam = &rvu->hw->mcam;
+ int bank = npc_get_bank(mcam, mcam_idx);
+ u8 kw_type, index;
+
+ if (npc_mcam_idx_2_key_type(rvu, mcam_idx, &kw_type))
+ return -EINVAL;
+
+ index = mcam_idx & (mcam->banksize - 1);
+
+ if (kw_type == NPC_MCAM_KEY_X2) {
+ npc_clear_x2_entry(rvu, blkaddr, bank, index);
+ return 0;
+ }
+
+ /* For NPC_MCAM_KEY_X4 keys, both the banks
+ * need to be programmed with the same value.
+ */
+ for (bank = 0; bank < mcam->banks_per_entry; bank++)
+ npc_clear_x2_entry(rvu, blkaddr, bank, index);
+
+ return 0;
+}
+
static void npc_cn20k_get_keyword(struct cn20k_mcam_entry *entry, int idx,
u64 *cam0, u64 *cam1)
{
@@ -1071,7 +1097,7 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
*/
if (kw_type == NPC_MCAM_KEY_X2) {
/* Clear mcam entry to avoid writes being suppressed by NPC */
- npc_cn20k_clear_mcam_entry(rvu, blkaddr, bank, mcam_idx);
+ npc_clear_x2_entry(rvu, blkaddr, bank, mcam_idx);
npc_cn20k_config_kw_x2(rvu, mcam, blkaddr,
mcam_idx, intf, entry,
bank, kw_type, kw, req_kw_type);
@@ -1096,8 +1122,8 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
}
/* Clear mcam entry to avoid writes being suppressed by NPC */
- npc_cn20k_clear_mcam_entry(rvu, blkaddr, 0, mcam_idx);
- npc_cn20k_clear_mcam_entry(rvu, blkaddr, 1, mcam_idx);
+ npc_clear_x2_entry(rvu, blkaddr, 0, mcam_idx);
+ npc_clear_x2_entry(rvu, blkaddr, 1, mcam_idx);
npc_cn20k_config_kw_x4(rvu, mcam, blkaddr,
mcam_idx, intf, entry,
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
index 8f3eea9cfb1d..2f761b97f91b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
@@ -330,8 +330,7 @@ int npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr,
int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
struct cn20k_mcam_entry *entry, u8 *intf,
u8 *ena, u8 *hw_prio);
-void npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr,
- int bank, int index);
+int npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int index);
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);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index 762fafd4ccb7..0a2191fda614 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -259,6 +259,13 @@ static void npc_clear_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int bank = npc_get_bank(mcam, index);
int actbank = bank;
+ if (is_cn20k(rvu->pdev)) {
+ if (npc_cn20k_clear_mcam_entry(rvu, blkaddr, index))
+ dev_err(rvu->dev, "%s Failed to enable mcam %u\n",
+ __func__, index);
+ return;
+ }
+
index &= (mcam->banksize - 1);
for (; bank < (actbank + mcam->banks_per_entry); bank++) {
rvu_write64(rvu, blkaddr,
@@ -753,9 +760,15 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
/* If the corresponding PF's ucast action is RSS,
* use the same action for promisc also
+ * Please note that for lbk(s) "index" and "ucast_idx"
+ * will be same.
*/
- ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc,
- nixlf, NIXLF_UCAST_ENTRY);
+ if (is_lbk_vf(rvu, pcifunc))
+ ucast_idx = index;
+ else
+ ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc,
+ nixlf, NIXLF_UCAST_ENTRY);
+
if (is_mcam_entry_enabled(rvu, mcam, blkaddr, ucast_idx))
*(u64 *)&action = npc_get_mcam_action(rvu, mcam,
blkaddr, ucast_idx);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 07/11] octeontx2-af: npc: cn20k: Fix bank value.
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (5 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 06/11] octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 08/11] octeontx2-af: npc: cn20k: Fix MCAM actions read Ratheesh Kannoth
` (4 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Suman Ghosh
or X4 keys its loop reused the bank parameter as the loop counter,
so bank no longer reflected the caller's bank after the loop and
the control flow was hard to follow.
Program NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT directly in
npc_cn20k_config_mcam_entry(): one CFG write for X2 using the computed
bank, and one CFG write per bank inside the X4 action loop. Enable the
entry at the end with npc_cn20k_enable_mcam_entry(..., true) instead of
embedding the enable bit in bank_cfg via the removed helper.
Cc: Suman Ghosh <sumang@marvell.com>
Fixes: 4e527f1e5c15 ("octeontx2-af: npc: cn20k: Add new mailboxes for CN20K silicon")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 92 ++++++++-----------
1 file changed, 37 insertions(+), 55 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 7bfd39fe0f5e..4b37d471f118 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -1044,34 +1044,6 @@ static void npc_cn20k_config_kw_x4(struct rvu *rvu, struct npc_mcam *mcam,
kw, req_kw_type);
}
-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)
-{
- 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,
- NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
- bank_cfg);
- return;
- }
-
- /* For NPC_MCAM_KEY_X4 keys, both the banks
- * need to be programmed with the same value.
- */
- for (bank = 0; bank < mcam->banks_per_entry; bank++) {
- rvu_write64(rvu, blkaddr,
- NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
- bank_cfg);
- }
-}
-
int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
u8 intf, struct cn20k_mcam_entry *entry,
bool enable, u8 hw_prio, u8 req_kw_type)
@@ -1079,6 +1051,7 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
struct npc_mcam *mcam = &rvu->hw->mcam;
int mcam_idx = index % mcam->banksize;
int bank = index / mcam->banksize;
+ u64 bank_cfg = (u64)hw_prio << 24;
int kw = 0;
u8 kw_type;
@@ -1118,41 +1091,50 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
bank, 1),
entry->vtag_action);
- goto set_cfg;
- }
- /* Clear mcam entry to avoid writes being suppressed by NPC */
- npc_clear_x2_entry(rvu, blkaddr, 0, mcam_idx);
- npc_clear_x2_entry(rvu, blkaddr, 1, mcam_idx);
-
- npc_cn20k_config_kw_x4(rvu, mcam, blkaddr,
- mcam_idx, intf, entry,
- kw_type, req_kw_type);
- for (bank = 0; bank < mcam->banks_per_entry; bank++) {
- /* Set 'action' */
+ /* Set HW priority */
rvu_write64(rvu, blkaddr,
- NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
- bank, 0),
- entry->action);
+ NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
+ bank_cfg);
- /* Set TAG 'action' */
- rvu_write64(rvu, blkaddr,
- NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
- bank, 1),
- entry->vtag_action);
+ } else {
+ /* Clear mcam entry to avoid writes being suppressed by NPC */
+ npc_clear_x2_entry(rvu, blkaddr, 0, mcam_idx);
+ npc_clear_x2_entry(rvu, blkaddr, 1, mcam_idx);
- /* Set 'action2' for inline receive */
- rvu_write64(rvu, blkaddr,
- NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
- bank, 2),
- entry->action2);
+ npc_cn20k_config_kw_x4(rvu, mcam, blkaddr,
+ mcam_idx, intf, entry,
+ kw_type, req_kw_type);
+ for (bank = 0; bank < mcam->banks_per_entry; bank++) {
+ /* Set 'action' */
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
+ bank, 0),
+ entry->action);
+
+ /* Set TAG 'action' */
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
+ bank, 1),
+ entry->vtag_action);
+
+ /* Set 'action2' for inline receive */
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
+ bank, 2),
+ entry->action2);
+
+ /* Set HW priority */
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(mcam_idx, bank),
+ bank_cfg);
+ }
}
-set_cfg:
/* TODO: */
/* PF installing VF rule */
- npc_cn20k_set_mcam_bank_cfg(rvu, blkaddr, mcam_idx, bank,
- kw_type, enable, hw_prio);
+ if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable))
+ return -EINVAL;
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 08/11] octeontx2-af: npc: cn20k: Fix MCAM actions read
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (6 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 07/11] octeontx2-af: npc: cn20k: Fix bank value Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 09/11] octeontx2-af: npc: cn20k: Initialize default-rule index outputs up front Ratheesh Kannoth
` (3 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Suman Ghosh
npc_cn20k_read_mcam_entry() always reloaded action and vtag_action from
bank 0 after programming the CAM words. Use the bank returned by
npc_get_bank() for the ACTION reads as well, and read those registers
once up front so both X2 and X4 paths share the same metadata.
Return directly from the X2 keyword path now that the action fields are
already populated.
Cc: Suman Ghosh <sumang@marvell.com>
Fixes: 6d1e70282f76 ("octeontx2-af: npc: cn20k: Use common APIs")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 22 ++++++++-----------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 4b37d471f118..752dbcede90f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -1218,6 +1218,14 @@ int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
bank = npc_get_bank(mcam, index);
index &= (mcam->banksize - 1);
+ cfg = rvu_read64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, bank, 0));
+ entry->action = cfg;
+
+ cfg = rvu_read64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, bank, 1));
+ entry->vtag_action = cfg;
+
cfg = rvu_read64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_INTF_EXT(index,
bank, 1)) & 3;
@@ -1267,7 +1275,7 @@ int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
bank,
0));
npc_cn20k_fill_entryword(entry, kw + 3, cam0, cam1);
- goto read_action;
+ return 0;
}
for (bank = 0; bank < mcam->banks_per_entry; bank++, kw = kw + 4) {
@@ -1312,18 +1320,6 @@ int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
npc_cn20k_fill_entryword(entry, kw + 3, cam0, cam1);
}
-read_action:
- /* 'action' is set to same value for both bank '0' and '1'.
- * Hence, reading bank '0' should be enough.
- */
- cfg = rvu_read64(rvu, blkaddr,
- NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, 0, 0));
- entry->action = cfg;
-
- cfg = rvu_read64(rvu, blkaddr,
- NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, 0, 1));
- entry->vtag_action = cfg;
-
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 09/11] octeontx2-af: npc: cn20k: Initialize default-rule index outputs up front
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (7 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 08/11] octeontx2-af: npc: cn20k: Fix MCAM actions read Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 10/11] octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free Ratheesh Kannoth
` (2 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth
npc_cn20k_dft_rules_idx_get() wrote USHRT_MAX into individual outputs
only on some error paths (lbk promisc lookup, VF ucast lookup, and the
PF rule walk), which could leave other caller slots stale across
retries.
Set every non-NULL bcast/mcast/promisc/ucast pointer to USHRT_MAX once
at entry, then drop the duplicate assignments on failure. Successful
lookups still overwrite the relevant slot before returning.
Fixes: 09d3b7a1403f ("octeontx2-af: npc: cn20k: Allocate default MCAM indexes")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 752dbcede90f..0714734c6af7 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -4001,6 +4001,13 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
void *val;
int i, j;
+ for (i = 0; i < ARRAY_SIZE(ptr); i++) {
+ if (!ptr[i])
+ continue;
+
+ *ptr[i] = USHRT_MAX;
+ }
+
if (!npc_priv.init_done)
return 0;
@@ -4016,7 +4023,6 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
npc_dft_rule_name[NPC_DFT_RULE_PROMISC_ID],
pcifunc);
- *ptr[0] = USHRT_MAX;
return -ESRCH;
}
@@ -4036,7 +4042,6 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
npc_dft_rule_name[NPC_DFT_RULE_UCAST_ID],
pcifunc);
- *ptr[3] = USHRT_MAX;
return -ESRCH;
}
@@ -4056,7 +4061,6 @@ int npc_cn20k_dft_rules_idx_get(struct rvu *rvu, u16 pcifunc, u16 *bcast,
__func__,
npc_dft_rule_name[i], pcifunc);
- *ptr[j] = USHRT_MAX;
continue;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 10/11] octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (8 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 09/11] octeontx2-af: npc: cn20k: Initialize default-rule index outputs up front Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 11/11] octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices Ratheesh Kannoth
2026-04-23 9:44 ` [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Paolo Abeni
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth
npc_cn20k_dft_rules_free() used the NPC MCAM mbox "free all" path, which
does not match how cn20k tracks default-rule MCAM slots indexes.
Resolve the default-rule indices, then for each valid slot clear the
bitmap entry, drop the PF/VF map, disable the MCAM line, clear the
target function, and npc_cn20k_idx_free(). Remove any
matching software mcam_rules nodes. On hard failure from idx_free, WARN
and stop so the box stays up for analysis.
In npc_mcam_free_all_entries(), prefetch the same default-rule indices
and, on cn20k, skip bitmap clear and idx_free when the scanned entry is
one of those reserved defaults (they are released by
npc_cn20k_dft_rules_free). Still disable the entry and tear down counter
mapping for every matching index.
Fixes: 09d3b7a1403f ("octeontx2-af: npc: cn20k: Allocate default MCAM indexes")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 51 ++++++++++++----
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 59 +++++++++++++------
2 files changed, 82 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 0714734c6af7..cb2fc21e0583 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -4163,11 +4163,11 @@ static bool npc_is_cgx_or_lbk(struct rvu *rvu, u16 pcifunc)
void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc)
{
- struct npc_mcam_free_entry_req free_req = { 0 };
+ struct npc_mcam *mcam = &rvu->hw->mcam;
+ u16 ptr[4] = {[0 ... 3] = USHRT_MAX};
+ struct rvu_npc_mcam_rule *rule, *tmp;
unsigned long index;
- struct msg_rsp rsp;
- u16 ptr[4];
- int rc, i;
+ int blkaddr, rc, i;
void *map;
if (!npc_priv.init_done)
@@ -4225,14 +4225,43 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc)
}
free_rules:
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+ if (blkaddr < 0)
+ return;
+ for (int i = 0; i < 4; i++) {
+ if (ptr[i] == USHRT_MAX)
+ continue;
- free_req.hdr.pcifunc = pcifunc;
- free_req.all = 1;
- rc = rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp);
- if (rc)
- dev_err(rvu->dev,
- "%s: Error deleting default entries (pcifunc=%#x\n",
- __func__, pcifunc);
+ mutex_lock(&mcam->lock);
+ npc_mcam_clear_bit(mcam, ptr[i]);
+ mcam->entry2pfvf_map[ptr[i]] = NPC_MCAM_INVALID_MAP;
+ npc_cn20k_enable_mcam_entry(rvu, blkaddr, ptr[i], false);
+ mcam->entry2target_pffunc[ptr[i]] = 0x0;
+ mutex_unlock(&mcam->lock);
+
+ rc = npc_cn20k_idx_free(rvu, &ptr[i], 1);
+ if (rc) {
+ /* Non recoverable error. Let us WARN and return. Keep system alive to
+ * enable debugging
+ */
+ WARN(1, "%s Error deleting default entries (pcifunc=%#x) mcam_idx=%u\n",
+ __func__, pcifunc, ptr[i]);
+ return;
+ }
+ }
+
+ mutex_lock(&mcam->lock);
+ list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
+ for (int i = 0; i < 4; i++) {
+ if (ptr[i] != rule->entry)
+ continue;
+
+ list_del(&rule->list);
+ kfree(rule);
+ break;
+ }
+ }
+ mutex_unlock(&mcam->lock);
}
int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index 0a2191fda614..b2a9c8d0075b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -2519,33 +2519,58 @@ void npc_mcam_clear_bit(struct npc_mcam *mcam, u16 index)
static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 pcifunc)
{
+ u16 dft_idxs[NPC_DFT_RULE_MAX_ID];
+ bool cn20k_dft_rl;
u16 index, cntr;
int rc;
+ npc_cn20k_dft_rules_idx_get(rvu, pcifunc,
+ &dft_idxs[NPC_DFT_RULE_BCAST_ID],
+ &dft_idxs[NPC_DFT_RULE_MCAST_ID],
+ &dft_idxs[NPC_DFT_RULE_PROMISC_ID],
+ &dft_idxs[NPC_DFT_RULE_UCAST_ID]);
+
/* Scan all MCAM entries and free the ones mapped to 'pcifunc' */
for (index = 0; index < mcam->bmap_entries; index++) {
- if (mcam->entry2pfvf_map[index] == pcifunc) {
+ if (mcam->entry2pfvf_map[index] != pcifunc)
+ continue;
+
+ cn20k_dft_rl = false;
+
+ if (is_cn20k(rvu->pdev)) {
+ if (dft_idxs[NPC_DFT_RULE_BCAST_ID] == index ||
+ dft_idxs[NPC_DFT_RULE_MCAST_ID] == index ||
+ dft_idxs[NPC_DFT_RULE_PROMISC_ID] == index ||
+ dft_idxs[NPC_DFT_RULE_UCAST_ID] == index) {
+ cn20k_dft_rl = true;
+ }
+ }
+
+ /* Disable the entry */
+ npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
+
+ if (!cn20k_dft_rl) {
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
/* Free the entry in bitmap */
npc_mcam_clear_bit(mcam, index);
- /* Disable the entry */
- npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
-
- /* Update entry2counter mapping */
- cntr = mcam->entry2cntr_map[index];
- if (cntr != NPC_MCAM_INVALID_MAP)
- npc_unmap_mcam_entry_and_cntr(rvu, mcam,
- blkaddr, index,
- cntr);
mcam->entry2target_pffunc[index] = 0x0;
- if (is_cn20k(rvu->pdev)) {
- rc = npc_cn20k_idx_free(rvu, &index, 1);
- if (rc)
- dev_err(rvu->dev,
- "Failed to free mcam idx=%u pcifunc=%#x\n",
- index, pcifunc);
- }
}
+
+ /* Update entry2counter mapping */
+ cntr = mcam->entry2cntr_map[index];
+ if (cntr != NPC_MCAM_INVALID_MAP)
+ npc_unmap_mcam_entry_and_cntr(rvu, mcam,
+ blkaddr, index,
+ cntr);
+
+ if (!is_cn20k(rvu->pdev) || cn20k_dft_rl)
+ continue;
+
+ rc = npc_cn20k_idx_free(rvu, &index, 1);
+ if (rc)
+ dev_err(rvu->dev,
+ "Failed to free mcam idx=%u pcifunc=%#x\n",
+ index, pcifunc);
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net 11/11] octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (9 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 10/11] octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free Ratheesh Kannoth
@ 2026-04-20 2:34 ` Ratheesh Kannoth
2026-04-23 9:44 ` [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Paolo Abeni
11 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-20 2:34 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, pabeni, andrew+netdev,
dan.carpenter, Ratheesh Kannoth, Suman Ghosh
npc_get_nixlf_mcam_index() returned USHRT_MAX from npc_cn20k_dft_rules_idx_get()
for broadcast, multicast, promiscuous, and unicast default-rule slots when no
rule was installed. Callers could use that sentinel as a real MCAM index.
Return -EINVAL from the cn20k cases when the reserved entry is still USHRT_MAX.
Teach rvu_npc_update_flowkey_alg_idx() to handle negative indices and skip RSS
action updates when the lookup fails. Add range checks to cn20k NPC MCAM helpers
so bogus indices are rejected before touching hardware.
Cc: Suman Ghosh <sumang@marvell.com>
Fixes: 6d1e70282f76 ("octeontx2-af: npc: cn20k: Use common APIs")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 12 ++++++++++
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 23 ++++++++++++-------
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index cb2fc21e0583..59d22511b742 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;
+ if (index < 0 || index >= mcam->total_entries)
+ return -EINVAL;
+
if (npc_mcam_idx_2_key_type(rvu, index, &kw_type))
return -EINVAL;
@@ -1055,6 +1058,9 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
int kw = 0;
u8 kw_type;
+ if (index < 0 || index >= mcam->total_entries)
+ return -EINVAL;
+
if (npc_mcam_idx_2_key_type(rvu, index, &kw_type))
return -EINVAL;
@@ -1147,6 +1153,9 @@ int npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
int bank, i, sb, db;
int dbank, sbank;
+ if (src >= mcam->total_entries || dest >= mcam->total_entries)
+ return -EINVAL;
+
dbank = npc_get_bank(mcam, dest);
sbank = npc_get_bank(mcam, src);
@@ -1212,6 +1221,9 @@ int npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
int kw = 0, bank;
u8 kw_type;
+ if (index >= mcam->total_entries)
+ return -EINVAL;
+
if (npc_mcam_idx_2_key_type(rvu, index, &kw_type))
return -EINVAL;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index b2a9c8d0075b..be79a51b4b48 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -165,12 +165,20 @@ int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
switch (type) {
case NIXLF_BCAST_ENTRY:
+ if (bcast == USHRT_MAX)
+ return -EINVAL;
return bcast;
case NIXLF_ALLMULTI_ENTRY:
+ if (mcast == USHRT_MAX)
+ return -EINVAL;
return mcast;
case NIXLF_PROMISC_ENTRY:
+ if (promisc == USHRT_MAX)
+ return -EINVAL;
return promisc;
case NIXLF_UCAST_ENTRY:
+ if (ucast == USHRT_MAX)
+ return -EINVAL;
return ucast;
default:
return -EINVAL;
@@ -238,9 +246,6 @@ void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int actbank = bank;
if (is_cn20k(rvu->pdev)) {
- if (index < 0 || index >= mcam->banksize * mcam->banks)
- return;
-
npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable);
return;
}
@@ -1128,7 +1133,7 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
index = mcam_index;
}
- if (index >= mcam->total_entries)
+ if (index < 0 || index >= mcam->total_entries)
return;
bank = npc_get_bank(mcam, index);
@@ -1173,16 +1178,18 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
/* If PF's promiscuous entry is enabled,
* Set RSS action for that entry as well
*/
- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
- blkaddr, alg_idx);
+ if (index >= 0)
+ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
+ blkaddr, alg_idx);
index = npc_get_nixlf_mcam_index(mcam, pcifunc,
nixlf, NIXLF_ALLMULTI_ENTRY);
/* If PF's allmulti entry is enabled,
* Set RSS action for that entry as well
*/
- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
- blkaddr, alg_idx);
+ if (index >= 0)
+ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
+ blkaddr, alg_idx);
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [v2,net,01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
2026-04-20 2:34 ` [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k Ratheesh Kannoth
@ 2026-04-23 9:38 ` Paolo Abeni
2026-04-23 10:01 ` [PATCH v2 net 01/11] " Simon Horman
1 sibling, 0 replies; 18+ messages in thread
From: Paolo Abeni @ 2026-04-23 9:38 UTC (permalink / raw)
To: rkannoth
Cc: davem, sgoutham, pabeni, sumang, dan.carpenter, error27,
andrew+netdev, kuba, horms, linux-kernel, edumazet, netdev
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
This patch converts several cn20k NPC functions from void to int return
types to propagate MCAM key-type lookup errors. It adds error checking
for npc_mcam_idx_2_key_type() and threads these errors through the
cn20k MCAM handlers.
Link: https://lore.kernel.org/netdev/adiQJvuKlEhq2ILx@stanley.mountain/
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> index 7291fdb89b03..18d70f4527d1 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
[ ... ]
> @@ -1415,9 +1435,9 @@ int rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry(struct rvu *rvu,
> else
> nix_intf = pfvf->nix_rx_intf;
>
> - npc_cn20k_config_mcam_entry(rvu, blkaddr, entry, nix_intf,
> - &req->entry_data, req->enable_entry,
> - req->hw_prio, req->req_kw_type);
> + rc = npc_cn20k_config_mcam_entry(rvu, blkaddr, entry, nix_intf,
> + &req->entry_data, req->enable_entry,
> + req->hw_prio, req->req_kw_type);
>
> mutex_unlock(&mcam->lock);
>
> rsp->entry = entry_rsp.entry;
> return 0;
Does this function need to return rc instead of 0? If
npc_cn20k_config_mcam_entry() fails (for example, due to an invalid key
type), the function still returns success to the caller. The mailbox
response indicates the entry was successfully allocated and configured,
but the hardware entry may be in an undefined state.
[ ... ]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [v2,net,06/11] octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width
2026-04-20 2:34 ` [PATCH v2 net 06/11] octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width Ratheesh Kannoth
@ 2026-04-23 9:39 ` Paolo Abeni
0 siblings, 0 replies; 18+ messages in thread
From: Paolo Abeni @ 2026-04-23 9:39 UTC (permalink / raw)
To: rkannoth
Cc: davem, sgoutham, pabeni, sumang, dan.carpenter, error27,
andrew+netdev, kuba, horms, linux-kernel, edumazet, netdev
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width
Replace the old four-argument CN20K MCAM clear with a per-bank static
helper and npc_cn20k_clear_mcam_entry() that takes a logical MCAM index,
resolves the key width via npc_mcam_idx_2_key_type(), and clears either
one bank (X2) or every bank (X4). Call it from npc_clear_mcam_entry() on
cn20k and log when key-type lookup fails. Use the per-bank helper from
npc_cn20k_config_mcam_entry() for pre-program clears. For loopback VFs,
use the promisc MCAM index as ucast_idx when copying RSS action for
promisc, matching cn20k default-rule layout.
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> index 705fe7a877e6..7bfd39fe0f5e 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
[ ... ]
> @@ -877,6 +877,32 @@ npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int bank, int index)
> NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, bank), 0);
> }
>
> +int
> +npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int mcam_idx)
> +{
> + struct npc_mcam *mcam = &rvu->hw->mcam;
> + int bank = npc_get_bank(mcam, mcam_idx);
> + u8 kw_type, index;
> +
> + if (npc_mcam_idx_2_key_type(rvu, mcam_idx, &kw_type))
> + return -EINVAL;
> +
> + index = mcam_idx & (mcam->banksize - 1);
Can the index calculation overflow a u8 when banksize exceeds 256?
The mcam->banksize field is u16 and can be up to 65535, with typical
values like 512 or 1024 for NPC MCAM hardware. When computing 'mcam_idx &
(mcam->banksize - 1)', the result will be truncated to 8 bits if it
exceeds 255, causing the wrong MCAM entry to be cleared.
Other code in this driver uses u16 or int for the same calculation:
drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c:npc_cn20k_copy_mcam_entry()
u16 src, dest;
...
src = src_idx & (mcam->banksize - 1);
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c:npc_clear_mcam_entry()
index &= (mcam->banksize - 1);
where index is int.
> +
> + if (kw_type == NPC_MCAM_KEY_X2) {
> + npc_clear_x2_entry(rvu, blkaddr, bank, index);
> + return 0;
> + }
> +
> + /* For NPC_MCAM_KEY_X4 keys, both the banks
> + * need to be programmed with the same value.
> + */
> + for (bank = 0; bank < mcam->banks_per_entry; bank++)
> + npc_clear_x2_entry(rvu, blkaddr, bank, index);
> +
> + return 0;
> +}
[ ... ]
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
> index 762fafd4ccb7..0a2191fda614 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
> @@ -259,6 +259,13 @@ static void npc_clear_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
> int bank = npc_get_bank(mcam, index);
> int actbank = bank;
>
> + if (is_cn20k(rvu->pdev)) {
> + if (npc_cn20k_clear_mcam_entry(rvu, blkaddr, index))
> + dev_err(rvu->dev, "%s Failed to enable mcam %u\n",
> + __func__, index);
This isn't a bug, but the error message says "Failed to enable mcam"
when the operation is clearing the entry. Should this be "Failed to clear
mcam"?
> + return;
> + }
> +
> index &= (mcam->banksize - 1);
> for (; bank < (actbank + mcam->banks_per_entry); bank++) {
> rvu_write64(rvu, blkaddr,
[ ... ]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
` (10 preceding siblings ...)
2026-04-20 2:34 ` [PATCH v2 net 11/11] octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices Ratheesh Kannoth
@ 2026-04-23 9:44 ` Paolo Abeni
2026-04-23 10:20 ` Ratheesh Kannoth
11 siblings, 1 reply; 18+ messages in thread
From: Paolo Abeni @ 2026-04-23 9:44 UTC (permalink / raw)
To: Ratheesh Kannoth, netdev, linux-kernel
Cc: sgoutham, davem, edumazet, kuba, andrew+netdev, dan.carpenter
On 4/20/26 4:34 AM, Ratheesh Kannoth wrote:
> This series tightens Marvell OcteonTX2 AF NPC support for CN20K
> silicon around MCAM key typing, optional debugfs setup, defrag
> allocation rollback, x2 versus x4 KEX profiles and default-rule
> allocation, logical MCAM clear and configuration, default-rule index
> bookkeeping and explicit teardown, and NIXLF reserved-slot lookup when
> default rules are missing.
>
> Patches 1 through 3 focus on AF error handling: propagate
> npc_mcam_idx_2_key_type() failures through cn20k MCAM enable, config,
> copy, and read paths; treat cn20k NPC debugfs files as optional so
> probe does not fail when debugfs is unavailable; and fix defrag MCAM
> allocation rollback so allocation errno is not overwritten by subbank
> index resolution.
>
> Patches 4 and 5 align default-rule and flow-install behaviour with the
> loaded mkex profile: prefer x4 default entries when the profile is x4,
> and reject x4 flow keys when the profile is strictly x2.
>
> Patches 6 through 8 refine cn20k MCAM programming: clear entries by
> logical index and resolved key width, fix bank and CFG sequencing in
> npc_cn20k_config_mcam_entry(), and read action metadata from the
> correct bank in npc_cn20k_read_mcam_entry().
>
> Patches 9 through 11 complete default-rule lifecycle handling:
> initialize all default-rule index outputs up front, tear down default
> MCAM rules explicitly (coordinated with npc_mcam_free_all_entries()),
> and reject USHRT_MAX sentinel indices in npc_get_nixlf_mcam_index()
> for cn20k.
>
> Ratheesh Kannoth (11):
> octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
> octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in
> init
> octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc
> rollback
> octeontx2-af: npc: cn20k: Make default entries as x4.
> octeontx2-af: npc: cn20k: Reject request for x4 entries in x2
> profile.
> octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width
> octeontx2-af: npc: cn20k: Fix bank value.
> octeontx2-af: npc: cn20k: Fix MCAM actions read
> octeontx2-af: npc: cn20k: Initialize default-rule index outputs up
> front
> octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on
> free
> octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices
>
> Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
>
> --
> v1 -> v2: Addressed simon comments. Added more patch fixes to this series.
> https://lore.kernel.org/netdev/20260418162013.GG280379@horms.kernel.org/
I strongly suggest avoid extending a series to address issues found by
the AI review, unless such issues are actual regressions/problems
introduced by the new code. Sashiko tends to find a lot of collateral
problem and the series could easily expand beyond any hope of merging.
Instead you should reply on the ML, commenting on sashiko's review,
explain why or why not the outlined problems are valid and/or should be
handled separately.
Thanks,
Paolo
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
2026-04-20 2:34 ` [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k Ratheesh Kannoth
2026-04-23 9:38 ` [v2,net,01/11] " Paolo Abeni
@ 2026-04-23 10:01 ` Simon Horman
1 sibling, 0 replies; 18+ messages in thread
From: Simon Horman @ 2026-04-23 10:01 UTC (permalink / raw)
To: rkannoth
Cc: Simon Horman, davem, edumazet, linux-kernel, andrew+netdev,
sumang, netdev, dan.carpenter, sgoutham, error27, kuba, pabeni
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
This patch converts several cn20k NPC functions from void to int return
types to propagate MCAM key-type lookup errors. It adds error checking
for npc_mcam_idx_2_key_type() and threads these errors through the
cn20k MCAM handlers.
Link: https://lore.kernel.org/netdev/adiQJvuKlEhq2ILx@stanley.mountain/
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> index 7291fdb89b03..18d70f4527d1 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
[ ... ]
> @@ -1415,9 +1435,9 @@ int rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry(struct rvu *rvu,
> else
> nix_intf = pfvf->nix_rx_intf;
>
> - npc_cn20k_config_mcam_entry(rvu, blkaddr, entry, nix_intf,
> - &req->entry_data, req->enable_entry,
> - req->hw_prio, req->req_kw_type);
> + rc = npc_cn20k_config_mcam_entry(rvu, blkaddr, entry, nix_intf,
> + &req->entry_data, req->enable_entry,
> + req->hw_prio, req->req_kw_type);
>
> mutex_unlock(&mcam->lock);
>
> rsp->entry = entry_rsp.entry;
> return 0;
Does this function need to return rc instead of 0? If
npc_cn20k_config_mcam_entry() fails (for example, due to an invalid key
type), the function still returns success to the caller. The mailbox
response indicates the entry was successfully allocated and configured,
but the hardware entry may be in an undefined state.
[ ... ]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes
2026-04-23 9:44 ` [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Paolo Abeni
@ 2026-04-23 10:20 ` Ratheesh Kannoth
0 siblings, 0 replies; 18+ messages in thread
From: Ratheesh Kannoth @ 2026-04-23 10:20 UTC (permalink / raw)
To: Paolo Abeni
Cc: netdev, linux-kernel, sgoutham, davem, edumazet, kuba,
andrew+netdev, dan.carpenter
On 2026-04-23 at 15:14:10, Paolo Abeni (pabeni@redhat.com) wrote:
> On 4/20/26 4:34 AM, Ratheesh Kannoth wrote:
> > This series tightens Marvell OcteonTX2 AF NPC support for CN20K
> > silicon around MCAM key typing, optional debugfs setup, defrag
> > allocation rollback, x2 versus x4 KEX profiles and default-rule
> > allocation, logical MCAM clear and configuration, default-rule index
> > bookkeeping and explicit teardown, and NIXLF reserved-slot lookup when
> > default rules are missing.
> >
> > Patches 1 through 3 focus on AF error handling: propagate
> > npc_mcam_idx_2_key_type() failures through cn20k MCAM enable, config,
> > copy, and read paths; treat cn20k NPC debugfs files as optional so
> > probe does not fail when debugfs is unavailable; and fix defrag MCAM
> > allocation rollback so allocation errno is not overwritten by subbank
> > index resolution.
> >
> > Patches 4 and 5 align default-rule and flow-install behaviour with the
> > loaded mkex profile: prefer x4 default entries when the profile is x4,
> > and reject x4 flow keys when the profile is strictly x2.
> >
> > Patches 6 through 8 refine cn20k MCAM programming: clear entries by
> > logical index and resolved key width, fix bank and CFG sequencing in
> > npc_cn20k_config_mcam_entry(), and read action metadata from the
> > correct bank in npc_cn20k_read_mcam_entry().
> >
> > Patches 9 through 11 complete default-rule lifecycle handling:
> > initialize all default-rule index outputs up front, tear down default
> > MCAM rules explicitly (coordinated with npc_mcam_free_all_entries()),
> > and reject USHRT_MAX sentinel indices in npc_get_nixlf_mcam_index()
> > for cn20k.
> >
> > Ratheesh Kannoth (11):
> > octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
> > octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in
> > init
> > octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc
> > rollback
> > octeontx2-af: npc: cn20k: Make default entries as x4.
> > octeontx2-af: npc: cn20k: Reject request for x4 entries in x2
> > profile.
> > octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width
> > octeontx2-af: npc: cn20k: Fix bank value.
> > octeontx2-af: npc: cn20k: Fix MCAM actions read
> > octeontx2-af: npc: cn20k: Initialize default-rule index outputs up
> > front
> > octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on
> > free
> > octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices
> >
> > Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
> >
> > --
> > v1 -> v2: Addressed simon comments. Added more patch fixes to this series.
> > https://lore.kernel.org/netdev/20260418162013.GG280379@horms.kernel.org/
>
> I strongly suggest avoid extending a series to address issues found by
> the AI review, unless such issues are actual regressions/problems
> introduced by the new code. Sashiko tends to find a lot of collateral
> problem and the series could easily expand beyond any hope of merging.
>
> Instead you should reply on the ML, commenting on sashiko's review,
> explain why or why not the outlined problems are valid and/or should be
> handled separately.
>
> Thanks,
>
> Paolo
>
Patch 1: [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k
>Is it intentional to discard the return value of npc_cn20k_enable_mcam_entry()
>here?
>If disabling an entry fails during teardown (e.g., in
>rvu_npc_disable_mcam_entries()), this could silently leave stale, active packet
>steering rules in the hardware.
Yes, the return value of npc_cn20k_enable_mcam_entry() is
intentionally discarded in this context.
The primary reason is that the validity of the MCAM index is
already verified prior to this call, so the function is not
expected to fail under normal conditions.
Additionally, during
rvu_npc_disable_mcam_entries()), failure handling is
best-effort. At this stage, the system is already
transitioning state, and retrying or propagating errors
does not provide meaningful recovery.
Introducing strict error handling here would require
propagating return values through multiple call sites,
which would significantly increase the scope and
complexity of this change.
Any modification to the return type or contract of
npc_enable_mcam_entry() would involve a broader refactor
across the driver and is therefore intentionally deferred
to a separate, dedicated change.
Given these constraints, ignoring the return value here is
a deliberate design decision and does not introduce
functional risk beyond what is already accepted in
teardown scenarios.
>If npc_update_dmac_value() returns an error, its caller in rvu_npc_fs.c seems
>to ignore it:
> if (rule->vfvlan_cfg)
> npc_update_dmac_value(rvu, blkaddr, rule, pfvf);
> if (rule->rx_action.op == NIX_RX_ACTION_DEFAULT) {
> ...
> }
> npc_enable_mcam_entry(rvu, mcam, blkaddr,
> rule->entry, true);
>Could this lead to the code continuing and activating the rule in hardware with
>an invalid or outdated MAC address?
Handling the error returned by npc_update_dmac_value() only
at this call site would not be sufficient.
For correctness, the error would need to be propagated to
higher-level callers, which would require changes across
multiple layers of the call chain. This significantly
increases the scope and complexity of the change.
Such propagation would also introduce additional handling
requirements in several paths, potentially leading to more
issues being flagged by static analysis tools.
Given that this patch is focused on a specific fix,
extending it to include broader error-handling changes is
out of scope.
Therefore, this is being treated as a separate enhancement
and is intentionally not addressed here.
Patch 4: [PATCH v2 net 04/11] octeontx2-af: npc: cn20k: Make default entries as x4.
>Does this in-place modification break the sorting invariant of the mcam_rules
>list?
>In rvu_mcam_add_rule(), the mcam->mcam_rules list appears to be strictly
>maintained in ascending order by entry. Modifying rule->entry in-place
>without removing and correctly re-inserting the node could leave the list
>unsorted.
>Could this cause subsequent rule insertions or debug routines that rely on
>the list order to behave incorrectly?
The mcam_rules list is not required to maintain a strict
sorting invariant for correctness.
Although rvu_mcam_add_rule() inserts entries in ascending
order, there is no functional dependency on this ordering
in subsequent operations.
All lookups and operations on the mcam_rules list iterate
over the entire list rather than relying on ordering.
Therefore, modifying rule->entry in place does not impact
correctness, even if the list becomes unsorted.
As a result, leaving the list temporarily or permanently
unsorted does not lead to incorrect behavior in rule
insertion, lookup, or debug routines.
>While this static structure predates this patch, can this design cause state
>contamination across multiple devices?
>Because pfl_info is static, it is shared globally across all network
>interfaces and physical NICs on the host. However, it is protected by
>mutex_lock(&pfvf->mbox.lock), which is a per-NIC lock.
>If multiple interfaces probe concurrently, they could acquire their own locks
>and race on this global struct. Additionally, if the host has multiple cards
>configured with different hardware profiles (such as one X2 and one X4), the
>first card to query the hardware will permanently cache its profile for all
>subsequent cards.
>Would it be safer to cache this hardware profile data in a device-private
> + */
> + WARN(1, "%s Error deleting default entries (pcifunc=%#x) mcam_idx=%u\n",
> + __func__, pcifunc, ptr[i]);
> + return;
> + }
AF processes mailbox (mbox) requests from PFs and VFs
serially. This guarantees that initialization of pfl_info
is not performed concurrently by multiple devices.
The profile information is populated once by AF during NPC
initialization and remains constant for the lifetime of the
DUT. There are no subsequent writes or updates to this data
after initialization.
As a result, pfl_info effectively becomes read-only after
being set. All later accesses from different PFs or VFs are
only reading the same stable value.
Even if multiple interfaces probe concurrently, they only
perform reads after initialization is complete. Concurrent
reads of immutable data do not introduce race conditions.
Regarding systems with multiple NICs or different hardware
profiles, the AF provides a consistent hardware view per
system. The profile data exposed through mbox is not
expected to vary dynamically per device after init.
Therefore, using a static structure here does not lead to
state contamination or incorrect behavior, and no
additional per-device storage is required in this context.
Patch 10: [PATCH v2 net 10/11] octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free
>> + rc = npc_cn20k_idx_free(rvu, &ptr[i], 1);
>> + if (rc) {
>> + /* Non recoverable error. Let us WARN and return. Keep system alive to
>> + * enable debugging
>> + */
>> + WARN(1, "%s Error deleting default entries (pcifunc=%#x) mcam_idx=%u\n",
>> + __func__, pcifunc, ptr[i]);
>> + return;
>> + }
>Does this early return on failure skip the software list cleanup and leak
>the rvu_npc_mcam_rule list nodes for both this index and any successfully
>freed indices?
>Since the final list cleanup loop is bypassed, it appears these software
>rules remain permanently. Also, does this skip hardware cleanup for any
>remaining default rules in the array?
Default MCAM rules are allocated upfront during
initialization, and their presence is required for correct
system operation. A failure during allocation itself would
already indicate a critical issue.
If npc_cn20k_idx_free() fails, it indicates that freeing of
previously allocated indices has failed. This suggests a
serious inconsistency in the allocation/free logic rather
than a recoverable runtime error.
In such a scenario, attempting partial cleanup (either
software list or remaining hardware entries) is unsafe, as
it can further corrupt the allocation state and make
debugging significantly harder.
Therefore, the function intentionally emits a WARN and
returns early to preserve the current state for debugging
purposes. This avoids masking the underlying issue.
While this does skip subsequent cleanup of software list
nodes and remaining hardware entries, continuing execution
after such a failure is not considered safe or meaningful.
This condition is treated as a non-recoverable error and
indicates a deeper issue in the allocation/free algorithm
that must be investigated separately.
>+ }
>x_handler_npc_cn20k_mcam_alloc_and_write_entry
>> +
>> + mutex_lock(&mcam->lock);
>> + list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
>> + for (int i = 0; i < 4; i++) {
>> + if (ptr[i] != rule->entry)
>> + continue;
>> +
>> + list_del(&rule->list);
>> + kfree(rule);
>> + break;
>> + }
>> + }
>> + mutex_unlock(&mcam->lock);
>Can dropping mcam->lock during npc_cn20k_idx_free() lead to a race
>condition? When the hardware index is freed, a concurrent thread could
>immediately allocate it and insert a new rule into mcam->mcam_rules with
>the same entry ID.
>Later, when this thread re-acquires the lock to clean up the software
>rules, the inner loop break only exits the for loop, meaning the list
>traversal continues. Would this cause both the old rule and the newly
>allocated concurrent rule to be deleted and freed, leading to a
>use-after-free for the active thread?
No. There is no concurrent threads;
default indexes are allocated thru mbox messages to AF.
AF process mbox messages processed one by one. So there is no chance of concurrency.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net 03/11] octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback
2026-04-20 2:34 ` [PATCH v2 net 03/11] octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback Ratheesh Kannoth
@ 2026-04-23 11:13 ` Simon Horman
0 siblings, 0 replies; 18+ messages in thread
From: Simon Horman @ 2026-04-23 11:13 UTC (permalink / raw)
To: Ratheesh Kannoth
Cc: netdev, linux-kernel, sgoutham, davem, edumazet, kuba, pabeni,
andrew+netdev, dan.carpenter, Dan Carpenter
On Mon, Apr 20, 2026 at 08:04:34AM +0530, Ratheesh Kannoth wrote:
> npc_defrag_alloc_free_slots() allocates MCAM indexes in up to two passes
> on bank0 then bank1. On failure it rolls back by freeing entries already
> placed in save[].
>
> __npc_subbank_alloc() can return a negative errno while only part of the
> indexes are valid. The rollback loop used rc for
> npc_mcam_idx_2_subbank_idx() as well, so a successful lookup stored zero
> in rc and a later __npc_subbank_free() failure could still end with
> return 0 when the allocation path had also left rc at zero
> (for example shortfall after zero return values from the alloc helpers).
>
> Jump to the rollback path immediately when either __npc_subbank_alloc()
> call fails, preserving its errno. If both calls succeed but the total
> allocated count is still less than cnt, set rc to -ENOSPC before rollback.
> Use a separate err variable for npc_mcam_idx_2_subbank_idx() so a
> successful lookup no longer clears a non-zero rc from the allocation
> phase.
>
> Cc: Dan Carpenter <error27@gmail.com>
> Fixes: 645c6e3c1999 ("octeontx2-af: npc: cn20k: virtual index support")
> Link: https://lore.kernel.org/netdev/adjNJEpILRZATB2N@stanley.mountain/
> Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Sashiko has generated a review of this patch. I believe that the concerns
raised there are all pre-existing issues that can be looked at in the
context of potential follow-up; I do not believe they should block
progress of this patchset.
...
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-04-23 11:13 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 2:34 [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 01/11] octeontx2-af: npc: cn20k: Propagate MCAM key-type errors on cn20k Ratheesh Kannoth
2026-04-23 9:38 ` [v2,net,01/11] " Paolo Abeni
2026-04-23 10:01 ` [PATCH v2 net 01/11] " Simon Horman
2026-04-20 2:34 ` [PATCH v2 net 02/11] octeontx2-af: npc: cn20k: Drop debugfs_create_file() error checks in init Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 03/11] octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback Ratheesh Kannoth
2026-04-23 11:13 ` Simon Horman
2026-04-20 2:34 ` [PATCH v2 net 04/11] octeontx2-af: npc: cn20k: Make default entries as x4 Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 05/11] octeontx2-af: npc: cn20k: Reject request for x4 entries in x2 profile Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 06/11] octeontx2-af: npc: cn20k: Clear MCAM entries by index and key width Ratheesh Kannoth
2026-04-23 9:39 ` [v2,net,06/11] " Paolo Abeni
2026-04-20 2:34 ` [PATCH v2 net 07/11] octeontx2-af: npc: cn20k: Fix bank value Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 08/11] octeontx2-af: npc: cn20k: Fix MCAM actions read Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 09/11] octeontx2-af: npc: cn20k: Initialize default-rule index outputs up front Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 10/11] octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free Ratheesh Kannoth
2026-04-20 2:34 ` [PATCH v2 net 11/11] octeontx2-af: npc: cn20k: Reject missing default-rule MCAM indices Ratheesh Kannoth
2026-04-23 9:44 ` [PATCH v2 net 0/11] octeontx2-af: npc: cn20k: MCAM fixes Paolo Abeni
2026-04-23 10:20 ` Ratheesh Kannoth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox