octeontx2-af: npc: cn20k: Add new mailboxes for CN20K silicon

To enable enhanced MCAM capabilities for CN20K, the struct mcam_entry
has been extended to support expanded keyword requirements.
Specifically, the kw and kw_mask arrays have been increased from
a size of 7 to 8 to accommodate the additional keyword field
introduced for CN20K.

To ensure seamless integration while preserving compatibility
with existing platforms, dedicated CN20K-specific mailboxes
have been introduced that leverage the updated struct mcam_entry.
This approach allows CN20K to utilize the extended structure
without impacting current implementations.

This patch identifies the relevant mailboxes and introduces the
following CN20K-specific additions:

New mailboxes added:
1. `NPC_CN20K_MCAM_WRITE_ENTRY`
2. `NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY`
3. `NPC_CN20K_MCAM_READ_ENTRY`
4. `NPC_CN20K_MCAM_READ_BASE_RULE`

Signed-off-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Link: https://patch.msgid.link/20260224080009.4147301-9-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Suman Ghosh
2026-02-24 13:30:04 +05:30
committed by Jakub Kicinski
parent de3f88b465
commit 4e527f1e5c
11 changed files with 600 additions and 106 deletions

View File

@@ -397,6 +397,12 @@ int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf,
if (is_rvu_otx2(rvu) || is_cn20k(rvu->pdev))
return 0;
/* sanity check */
cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_NIXX_CFG(0) |
(RVU_AFPF << 16));
if (!cfg)
return 0;
ctx_cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST3);
/* Alloc memory for CQINT's HW contexts */
cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
@@ -420,5 +426,16 @@ int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf,
rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_BASE(nixlf),
(u64)pfvf->nix_qints_ctx->iova);
rvu_write64(rvu, BLKADDR_NIX0, RVU_AF_BAR2_SEL, RVU_AF_BAR2_PFID);
rvu_write64(rvu, BLKADDR_NIX0,
AF_BAR2_ALIASX(0, NIX_GINT_INT_W1S), ALTAF_RDY);
/* wait for ack */
err = rvu_poll_reg(rvu, BLKADDR_NIX0,
AF_BAR2_ALIASX(0, NIX_GINT_INT), ALTAF_RDY, true);
if (err)
rvu->altaf_ready = false;
else
rvu->altaf_ready = true;
return 0;
}

View File

@@ -637,9 +637,13 @@ npc_cn20k_clear_mcam_entry(struct rvu *rvu, int blkaddr, int bank, int index)
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 1), 0);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 0), 0);
/* Clear corresponding stats register */
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, bank), 0);
}
static void npc_cn20k_get_keyword(struct mcam_entry *entry, int idx,
static void npc_cn20k_get_keyword(struct cn20k_mcam_entry *entry, int idx,
u64 *cam0, u64 *cam1)
{
u64 kw_mask;
@@ -679,7 +683,7 @@ static void npc_cn20k_get_keyword(struct mcam_entry *entry, int idx,
*/
static void npc_cn20k_config_kw_x2(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, u8 intf,
struct mcam_entry *entry,
struct cn20k_mcam_entry *entry,
int bank, u8 kw_type, int kw)
{
u64 intf_ext = 0, intf_ext_mask = 0;
@@ -751,7 +755,8 @@ static void npc_cn20k_config_kw_x2(struct rvu *rvu, struct npc_mcam *mcam,
static void npc_cn20k_config_kw_x4(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, u8 intf,
struct mcam_entry *entry, u8 kw_type)
struct cn20k_mcam_entry *entry,
u8 kw_type)
{
int kw = 0, bank;
@@ -789,9 +794,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 mcam_entry *entry, bool enable, u8 hw_prio)
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)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int mcam_idx = index % mcam->banksize;
@@ -906,7 +911,7 @@ void npc_cn20k_copy_mcam_entry(struct rvu *rvu, int blkaddr, u16 src, u16 dest)
}
}
static void npc_cn20k_fill_entryword(struct mcam_entry *entry, int idx,
static void npc_cn20k_fill_entryword(struct cn20k_mcam_entry *entry, int idx,
u64 cam0, u64 cam1)
{
entry->kw[idx] = cam1;
@@ -914,8 +919,8 @@ static void npc_cn20k_fill_entryword(struct mcam_entry *entry, int idx,
}
void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
struct mcam_entry *entry, u8 *intf, u8 *ena,
u8 *hw_prio)
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;
@@ -1034,6 +1039,172 @@ void npc_cn20k_read_mcam_entry(struct rvu *rvu, int blkaddr, u16 index,
entry->vtag_action = cfg;
}
int rvu_mbox_handler_npc_cn20k_mcam_write_entry(struct rvu *rvu,
struct npc_cn20k_mcam_write_entry_req *req,
struct msg_rsp *rsp)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 pcifunc = req->hdr.pcifunc;
int blkaddr, rc;
u8 nix_intf;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
mutex_lock(&mcam->lock);
rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
if (rc)
goto exit;
if (!is_npc_interface_valid(rvu, req->intf)) {
rc = NPC_MCAM_INVALID_REQ;
goto exit;
}
if (is_npc_intf_tx(req->intf))
nix_intf = pfvf->nix_tx_intf;
else
nix_intf = pfvf->nix_rx_intf;
/* For AF installed rules, the nix_intf should be set to target NIX */
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);
rc = 0;
exit:
mutex_unlock(&mcam->lock);
return rc;
}
int rvu_mbox_handler_npc_cn20k_mcam_read_entry(struct rvu *rvu,
struct npc_mcam_read_entry_req *req,
struct npc_cn20k_mcam_read_entry_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 pcifunc = req->hdr.pcifunc;
int blkaddr, rc;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
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);
mutex_unlock(&mcam->lock);
return rc;
}
int rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry(struct rvu *rvu,
struct npc_cn20k_mcam_alloc_and_write_entry_req *req,
struct npc_mcam_alloc_and_write_entry_rsp *rsp)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
struct npc_mcam_alloc_entry_req entry_req;
struct npc_mcam_alloc_entry_rsp entry_rsp;
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 entry = NPC_MCAM_ENTRY_INVALID;
int blkaddr, rc;
u8 nix_intf;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
if (!is_npc_interface_valid(rvu, req->intf))
return NPC_MCAM_INVALID_REQ;
/* Try to allocate a MCAM entry */
entry_req.hdr.pcifunc = req->hdr.pcifunc;
entry_req.contig = true;
entry_req.ref_prio = req->ref_prio;
entry_req.ref_entry = req->ref_entry;
entry_req.count = 1;
rc = rvu_mbox_handler_npc_mcam_alloc_entry(rvu,
&entry_req, &entry_rsp);
if (rc)
return rc;
if (!entry_rsp.count)
return NPC_MCAM_ALLOC_FAILED;
/* entry_req.count is 1, so single entry is allocated */
entry = entry_rsp.entry;
mutex_lock(&mcam->lock);
if (is_npc_intf_tx(req->intf))
nix_intf = pfvf->nix_tx_intf;
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);
mutex_unlock(&mcam->lock);
rsp->entry = entry;
return 0;
}
int rvu_mbox_handler_npc_cn20k_read_base_steer_rule(struct rvu *rvu,
struct msg_req *req,
struct npc_cn20k_mcam_read_base_rule_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int index, blkaddr, nixlf, rc = 0;
u16 pcifunc = req->hdr.pcifunc;
u8 intf, enable, hw_prio;
struct rvu_pfvf *pfvf;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
/* Return the channel number in case of PF */
if (!(pcifunc & RVU_PFVF_FUNC_MASK)) {
pfvf = rvu_get_pfvf(rvu, pcifunc);
rsp->entry.kw[0] = pfvf->rx_chan_base;
rsp->entry.kw_mask[0] = 0xFFFULL;
goto out;
}
/* Find the pkt steering rule installed by PF to this VF */
mutex_lock(&mcam->lock);
for (index = 0; index < mcam->bmap_entries; index++) {
if (mcam->entry2target_pffunc[index] == pcifunc)
goto read_entry;
}
rc = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
if (rc < 0) {
mutex_unlock(&mcam->lock);
goto out;
}
/* Read the default ucast entry if there is no pkt steering rule */
index = npc_get_nixlf_mcam_index(mcam, pcifunc, nixlf,
NIXLF_UCAST_ENTRY);
read_entry:
/* Read the mcam entry */
npc_cn20k_read_mcam_entry(rvu, blkaddr, index,
&rsp->entry, &intf,
&enable, &hw_prio);
mutex_unlock(&mcam->lock);
out:
return rc;
}
static u8 npc_map2cn20k_flag(u8 flag)
{
switch (flag) {

View File

@@ -296,15 +296,16 @@ 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 mcam_entry *entry,
u8 intf,
struct cn20k_mcam_entry *entry,
bool enable, u8 hw_prio);
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 mcam_entry *entry, u8 *intf, u8 *ena,
u8 *hw_prio);
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);

View File

@@ -78,6 +78,13 @@
#define RVU_MBOX_VF_INT_ENA_W1C (0x38)
#define RVU_MBOX_VF_VFAF_TRIGX(a) (0x2000 | (a) << 3)
#define NIX_GINT_INT (0x200)
#define NIX_GINT_INT_W1S (0x208)
#define ALTAF_FLR BIT_ULL(0)
#define ALTAF_RDY BIT_ULL(1)
/* NPC registers */
#define NPC_AF_INTFX_EXTRACTORX_CFG(a, b) \
(0x20c000ull | (a) << 16 | (b) << 8)

View File

@@ -287,6 +287,17 @@ M(NPC_CN20K_MCAM_GET_FREE_COUNT, 0x6015, npc_cn20k_get_fcnt, \
msg_req, npc_cn20k_get_fcnt_rsp) \
M(NPC_CN20K_GET_KEX_CFG, 0x6016, npc_cn20k_get_kex_cfg, \
msg_req, npc_cn20k_get_kex_cfg_rsp) \
M(NPC_CN20K_MCAM_WRITE_ENTRY, 0x6017, npc_cn20k_mcam_write_entry, \
npc_cn20k_mcam_write_entry_req, msg_rsp) \
M(NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY, 0x6018, \
npc_cn20k_mcam_alloc_and_write_entry, \
npc_cn20k_mcam_alloc_and_write_entry_req, \
npc_mcam_alloc_and_write_entry_rsp) \
M(NPC_CN20K_MCAM_READ_ENTRY, 0x6019, npc_cn20k_mcam_read_entry, \
npc_mcam_read_entry_req, \
npc_cn20k_mcam_read_entry_rsp) \
M(NPC_CN20K_MCAM_READ_BASE_RULE, 0x601a, npc_cn20k_read_base_steer_rule, \
msg_req, npc_cn20k_mcam_read_base_rule_rsp) \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, \
nix_lf_alloc_req, nix_lf_alloc_rsp) \
@@ -1570,13 +1581,32 @@ struct mcam_entry_mdata {
};
struct mcam_entry {
#define NPC_MAX_KWS_IN_KEY 8 /* Number of keywords in max keywidth */
#define NPC_MAX_KWS_IN_KEY 7 /* Number of keywords in max keywidth */
u64 kw[NPC_MAX_KWS_IN_KEY];
u64 kw_mask[NPC_MAX_KWS_IN_KEY];
u64 action;
u64 vtag_action;
};
struct cn20k_mcam_entry {
#define NPC_CN20K_MAX_KWS_IN_KEY 8
u64 kw[NPC_CN20K_MAX_KWS_IN_KEY];
u64 kw_mask[NPC_CN20K_MAX_KWS_IN_KEY];
u64 action;
u64 vtag_action;
};
struct npc_cn20k_mcam_write_entry_req {
struct mbox_msghdr hdr;
struct cn20k_mcam_entry entry_data;
u16 entry; /* MCAM entry to write this match key */
u16 cntr; /* Counter for this MCAM entry */
u8 intf; /* Rx or Tx interface */
u8 enable_entry;/* Enable this MCAM entry ? */
u8 hw_prio; /* hardware priority, valid for cn20k */
u64 reserved; /* reserved for future use */
};
struct npc_mcam_write_entry_req {
struct mbox_msghdr hdr;
struct mcam_entry entry_data;
@@ -1649,8 +1679,30 @@ struct npc_mcam_alloc_and_write_entry_req {
u8 intf; /* Rx or Tx interface */
u8 enable_entry;/* Enable this MCAM entry ? */
u8 alloc_cntr; /* Allocate counter and map ? */
/* hardware priority, supported for cn20k */
u8 hw_prio;
};
struct npc_cn20k_mcam_alloc_and_write_entry_req {
struct mbox_msghdr hdr;
struct cn20k_mcam_entry entry_data;
u16 ref_entry;
u8 ref_prio; /* Lower or higher w.r.t ref_entry */
u8 intf; /* Rx or Tx interface */
u8 enable_entry;/* Enable this MCAM entry ? */
u8 hw_prio; /* hardware priority, valid for cn20k */
u16 reserved[4]; /* reserved for future use */
};
struct npc_cn20k_mcam_read_entry_rsp {
struct mbox_msghdr hdr;
struct cn20k_mcam_entry entry_data;
u8 intf;
u8 enable;
u8 hw_prio; /* valid for cn20k */
};
struct npc_cn20k_mcam_read_base_rule_rsp {
struct mbox_msghdr hdr;
struct cn20k_mcam_entry entry;
};
struct npc_mcam_alloc_and_write_entry_rsp {

View File

@@ -644,6 +644,7 @@ struct rvu_npc_mcam_rule {
u16 chan;
u16 chan_mask;
u8 lxmb;
u8 hw_prio;
};
#endif /* NPC_H */

View File

@@ -600,6 +600,7 @@ static void rvu_check_min_msix_vec(struct rvu *rvu, int nvecs, int pf, int vf)
static int rvu_setup_msix_resources(struct rvu *rvu)
{
struct altaf_intr_notify *altaf_intr_data;
struct rvu_hwinfo *hw = rvu->hw;
int pf, vf, numvfs, hwvf, err;
int nvecs, offset, max_msix;
@@ -706,7 +707,30 @@ static int rvu_setup_msix_resources(struct rvu *rvu)
rvu->msix_base_iova = iova;
rvu->msixtr_base_phy = phy_addr;
if (is_rvu_otx2(rvu) || is_cn20k(rvu->pdev))
return 0;
if (!rvu->fwdata)
goto fail;
altaf_intr_data = &rvu->fwdata->altaf_intr_info;
if (altaf_intr_data->gint_paddr) {
iova = dma_map_resource(rvu->dev, altaf_intr_data->gint_paddr,
PCI_MSIX_ENTRY_SIZE,
DMA_BIDIRECTIONAL, 0);
if (dma_mapping_error(rvu->dev, iova))
goto fail;
altaf_intr_data->gint_iova_addr = iova;
}
return 0;
fail:
dma_unmap_resource(rvu->dev, phy_addr, max_msix * PCI_MSIX_ENTRY_SIZE,
DMA_BIDIRECTIONAL, 0);
return -EFAULT;
}
static void rvu_reset_msix(struct rvu *rvu)
@@ -1397,7 +1421,6 @@ static void rvu_detach_block(struct rvu *rvu, int pcifunc, int blktype)
if (blkaddr < 0)
return;
block = &hw->block[blkaddr];
num_lfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
@@ -2203,6 +2226,33 @@ int rvu_mbox_handler_ndc_sync_op(struct rvu *rvu,
return 0;
}
static void rvu_notify_altaf(struct rvu *rvu, u16 pcifunc, u64 op)
{
int pf, vf;
if (!rvu->fwdata)
return;
if (op == ALTAF_FLR) {
pf = rvu_get_pf(rvu->pdev, pcifunc);
set_bit(pf, rvu->fwdata->altaf_intr_info.flr_pf_bmap);
if (pcifunc & RVU_PFVF_FUNC_MASK) {
vf = pcifunc & RVU_PFVF_FUNC_MASK;
if (vf >= 128) {
WARN(1,
"flr_vf_bmap size is 128 bits, vf=%u\n",
vf);
return;
}
set_bit(vf, rvu->fwdata->altaf_intr_info.flr_vf_bmap);
}
}
rvu_write64(rvu, BLKADDR_NIX0, AF_BAR2_ALIASX(0, NIX_GINT_INT_W1S), op);
usleep_range(5000, 6000);
}
static int rvu_process_mbox_msg(struct otx2_mbox *mbox, int devid,
struct mbox_msghdr *req)
{
@@ -2286,7 +2336,8 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
offset = mbox->rx_start + ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
if (req_hdr->sig && !(is_rvu_otx2(rvu) || is_cn20k(rvu->pdev))) {
if (req_hdr->sig && rvu->altaf_ready &&
!(is_rvu_otx2(rvu) || is_cn20k(rvu->pdev))) {
req_hdr->opt_msg = mw->mbox_wrk[devid].num_msgs;
rvu_write64(rvu, BLKADDR_NIX0, RVU_AF_BAR2_SEL,
RVU_AF_BAR2_PFID);
@@ -2795,6 +2846,16 @@ static void rvu_blklf_teardown(struct rvu *rvu, u16 pcifunc, u8 blkaddr)
block = &rvu->hw->block[blkaddr];
num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, pcifunc),
block->addr);
if (block->addr == BLKADDR_TIM && rvu->altaf_ready) {
rvu_notify_altaf(rvu, pcifunc, ALTAF_FLR);
return;
}
if ((block->addr == BLKADDR_SSO || block->addr == BLKADDR_SSOW) &&
rvu->altaf_ready)
return;
if (!num_lfs)
return;
for (slot = 0; slot < num_lfs; slot++) {
@@ -3078,12 +3139,12 @@ static int rvu_afvf_msix_vectors_num_ok(struct rvu *rvu)
static int rvu_register_interrupts(struct rvu *rvu)
{
int ret, offset, pf_vec_start;
int i, ret, offset, pf_vec_start;
rvu->num_vec = pci_msix_vec_count(rvu->pdev);
rvu->irq_name = devm_kmalloc_array(rvu->dev, rvu->num_vec,
NAME_SIZE, GFP_KERNEL);
rvu->irq_name = devm_kcalloc(rvu->dev, rvu->num_vec,
NAME_SIZE, GFP_KERNEL);
if (!rvu->irq_name)
return -ENOMEM;
@@ -3269,6 +3330,13 @@ static int rvu_register_interrupts(struct rvu *rvu)
if (ret)
goto fail;
for (i = 0; i < rvu->num_vec; i++) {
if (strstr(&rvu->irq_name[i * NAME_SIZE], "Mbox") ||
strstr(&rvu->irq_name[i * NAME_SIZE], "FLR"))
irq_set_affinity(pci_irq_vector(rvu->pdev, i),
cpumask_of(0));
}
return 0;
fail:
@@ -3297,8 +3365,8 @@ static int rvu_flr_init(struct rvu *rvu)
cfg | BIT_ULL(22));
}
rvu->flr_wq = alloc_ordered_workqueue("rvu_afpf_flr",
WQ_HIGHPRI | WQ_MEM_RECLAIM);
rvu->flr_wq = alloc_workqueue("rvu_afpf_flr",
WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
if (!rvu->flr_wq)
return -ENOMEM;

View File

@@ -197,7 +197,7 @@ struct npc_key_field {
/* Masks where all set bits indicate position
* of a field in the key
*/
u64 kw_mask[NPC_MAX_KWS_IN_KEY];
u64 kw_mask[NPC_CN20K_MAX_KWS_IN_KEY];
/* Number of words in the key a field spans. If a field is
* of 16 bytes and key offset is 4 then the field will use
* 4 bytes in KW0, 8 bytes in KW1 and 4 bytes in KW2 and
@@ -1191,4 +1191,5 @@ int rvu_rep_pf_init(struct rvu *rvu);
int rvu_rep_install_mcam_rules(struct rvu *rvu);
void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable);
int npc_mcam_verify_entry(struct npc_mcam *mcam, u16 pcifunc, int entry);
#endif /* RVU_H */

View File

@@ -21,6 +21,7 @@
#include "rvu_npc_hash.h"
#include "mcs.h"
#include "cn20k/reg.h"
#include "cn20k/debugfs.h"
#define DEBUGFS_DIR_NAME "octeontx2"
@@ -3506,11 +3507,11 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
struct rvu_npc_mcam_rule *iter;
struct rvu *rvu = s->private;
struct npc_mcam *mcam;
int pf, vf = -1;
int pf, vf = -1, bank;
u16 target, index;
bool enabled;
u64 hits, off;
int blkaddr;
u16 target;
u64 hits;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
@@ -3554,6 +3555,15 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
enabled = is_mcam_entry_enabled(rvu, mcam, blkaddr, iter->entry);
seq_printf(s, "\tenabled: %s\n", enabled ? "yes" : "no");
if (is_cn20k(rvu->pdev)) {
seq_printf(s, "\tpriority: %u\n", iter->hw_prio);
index = iter->entry & (mcam->banksize - 1);
bank = npc_get_bank(mcam, iter->entry);
off = NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, bank);
hits = rvu_read64(rvu, blkaddr, off);
seq_printf(s, "\thits: %lld\n", hits);
continue;
}
if (!iter->has_cntr)
continue;
@@ -3698,9 +3708,9 @@ static int rvu_dbg_npc_exact_drop_cnt(struct seq_file *s, void *unused)
struct npc_exact_table *table;
struct rvu *rvu = s->private;
struct npc_key_field *field;
u64 cfg, cam1, off;
u16 chan, pcifunc;
int blkaddr, i;
u64 cfg, cam1;
char *str;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
@@ -3721,11 +3731,17 @@ static int rvu_dbg_npc_exact_drop_cnt(struct seq_file *s, void *unused)
chan = field->kw_mask[0] & cam1;
str = (cfg & 1) ? "enabled" : "disabled";
if (is_cn20k(rvu->pdev)) {
off = NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(i, 0);
seq_printf(s, "0x%x\t%d\t\t%llu\t0x%x\t%s\n", pcifunc,
i, rvu_read64(rvu, blkaddr, off), chan, str);
} else {
off = NPC_AF_MATCH_STATX(table->counter_idx[i]);
seq_printf(s, "0x%x\t%d\t\t%llu\t0x%x\t%s\n", pcifunc,
i, rvu_read64(rvu, blkaddr, off),
chan, str);
}
seq_printf(s, "0x%x\t%d\t\t%llu\t0x%x\t%s\n", pcifunc, i,
rvu_read64(rvu, blkaddr,
NPC_AF_MATCH_STATX(table->counter_idx[i])),
chan, str);
}
return 0;

View File

@@ -2397,8 +2397,8 @@ void rvu_npc_get_mcam_counter_alloc_info(struct rvu *rvu, u16 pcifunc,
}
}
static int npc_mcam_verify_entry(struct npc_mcam *mcam,
u16 pcifunc, int entry)
int npc_mcam_verify_entry(struct npc_mcam *mcam,
u16 pcifunc, int entry)
{
/* verify AF installed entries */
if (is_pffunc_af(pcifunc))
@@ -2943,6 +2943,10 @@ int npc_config_cntr_default_entries(struct rvu *rvu, bool enable)
struct rvu_npc_mcam_rule *rule;
int blkaddr;
/* Counter is set for each rule by default */
if (is_cn20k(rvu->pdev))
return -EINVAL;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return -EINVAL;
@@ -3123,10 +3127,13 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
if (rc)
goto exit;
if (req->set_cntr &&
npc_mcam_verify_counter(mcam, pcifunc, req->cntr)) {
rc = NPC_MCAM_INVALID_REQ;
goto exit;
if (!is_cn20k(rvu->pdev)) {
/* Verify counter in SoCs other than cn20k */
if (req->set_cntr &&
npc_mcam_verify_counter(mcam, pcifunc, req->cntr)) {
rc = NPC_MCAM_INVALID_REQ;
goto exit;
}
}
if (!is_npc_interface_valid(rvu, req->intf)) {
@@ -3338,6 +3345,10 @@ int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu,
struct npc_mcam *mcam = &rvu->hw->mcam;
int err;
/* Counter is not supported for CN20K */
if (is_cn20k(rvu->pdev))
return NPC_MCAM_INVALID_REQ;
mutex_lock(&mcam->lock);
err = __npc_mcam_alloc_counter(rvu, req, rsp);
@@ -3392,6 +3403,10 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,
struct npc_mcam *mcam = &rvu->hw->mcam;
int err;
/* Counter is not supported for CN20K */
if (is_cn20k(rvu->pdev))
return NPC_MCAM_INVALID_REQ;
mutex_lock(&mcam->lock);
err = __npc_mcam_free_counter(rvu, req, rsp);
@@ -3450,6 +3465,10 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
u16 index, entry = 0;
int blkaddr, rc;
/* Counter is not supported for CN20K */
if (is_cn20k(rvu->pdev))
return NPC_MCAM_INVALID_REQ;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
@@ -3494,12 +3513,23 @@ int rvu_mbox_handler_npc_mcam_clear_counter(struct rvu *rvu,
struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int blkaddr, err;
int blkaddr, err, index, bank;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
/* For cn20k, npc mcam index is passed as cntr, as each
* mcam entry has corresponding counter.
*/
if (is_cn20k(rvu->pdev)) {
index = req->cntr & (mcam->banksize - 1);
bank = npc_get_bank(mcam, req->cntr);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, bank), 0);
return 0;
}
mutex_lock(&mcam->lock);
err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
mutex_unlock(&mcam->lock);
@@ -3516,12 +3546,26 @@ int rvu_mbox_handler_npc_mcam_counter_stats(struct rvu *rvu,
struct npc_mcam_oper_counter_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int blkaddr, err;
int blkaddr, err, index, bank;
u64 regval;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
/* In CN20K, mcam index is passed cntr. Each cn20k mcam entry
* has its own counter. No need to verify the counter index.
*/
if (is_cn20k(rvu->pdev)) {
index = req->cntr & (mcam->banksize - 1);
bank = npc_get_bank(mcam, req->cntr);
regval = rvu_read64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index,
bank));
rsp->stat = regval;
return 0;
}
mutex_lock(&mcam->lock);
err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
mutex_unlock(&mcam->lock);
@@ -3816,13 +3860,24 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu,
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
mutex_lock(&mcam->lock);
index = req->entry & (mcam->banksize - 1);
bank = npc_get_bank(mcam, req->entry);
mutex_lock(&mcam->lock);
if (is_cn20k(rvu->pdev)) {
regval = rvu_read64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index,
bank));
rsp->stat_ena = 1;
rsp->stat = regval;
mutex_unlock(&mcam->lock);
return 0;
}
/* read MCAM entry STAT_ACT register */
regval = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank));
regval = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_STAT_ACT(index,
bank));
if (!(regval & rvu->hw->npc_stat_ena)) {
rsp->stat_ena = 0;

View File

@@ -227,10 +227,11 @@ static bool npc_check_overlap(struct rvu *rvu, int blkaddr,
input = &mcam->tx_key_fields[type];
}
kws = NPC_MAX_KWS_IN_KEY;
if (is_cn20k(rvu->pdev))
goto skip_cn10k_config;
kws = NPC_MAX_KWS_IN_KEY - 1;
for (lid = start_lid; lid < NPC_MAX_LID; lid++) {
for (lt = 0; lt < NPC_MAX_LT; lt++) {
for (ld = 0; ld < NPC_MAX_LD; ld++) {
@@ -255,8 +256,7 @@ static bool npc_check_overlap(struct rvu *rvu, int blkaddr,
/* check any input field bits falls in any
* other field bits.
*/
if (npc_check_overlap_fields(dummy, input,
kws))
if (npc_check_overlap_fields(dummy, input, kws))
return true;
}
}
@@ -289,7 +289,7 @@ static bool npc_check_overlap(struct rvu *rvu, int blkaddr,
* field bits
*/
if (npc_check_overlap_fields(dummy, input,
NPC_MAX_KWS_IN_KEY))
NPC_CN20K_MAX_KWS_IN_KEY))
return true;
}
}
@@ -460,9 +460,9 @@ static void npc_handle_multi_layer_fields(struct rvu *rvu, int blkaddr, u8 intf)
u8 start_lid;
if (is_cn20k(rvu->pdev))
max_kw = NPC_MAX_KWS_IN_KEY;
max_kw = NPC_CN20K_MAX_KWS_IN_KEY;
else
max_kw = NPC_MAX_KWS_IN_KEY - 1;
max_kw = NPC_MAX_KWS_IN_KEY;
key_fields = mcam->rx_key_fields;
features = &mcam->rx_features;
@@ -906,6 +906,7 @@ void npc_update_entry(struct rvu *rvu, enum key_fields type,
struct mcam_entry_mdata *mdata, u64 val_lo,
u64 val_hi, u64 mask_lo, u64 mask_hi, u8 intf)
{
struct cn20k_mcam_entry cn20k_dummy = { {0} };
struct npc_mcam *mcam = &rvu->hw->mcam;
struct mcam_entry dummy = { {0} };
u64 *kw, *kw_mask, *val, *mask;
@@ -921,9 +922,15 @@ void npc_update_entry(struct rvu *rvu, enum key_fields type,
if (!field->nr_kws)
return;
max_kw = NPC_MAX_KWS_IN_KEY;
kw = dummy.kw;
kw_mask = dummy.kw_mask;
if (is_cn20k(rvu->pdev)) {
max_kw = NPC_CN20K_MAX_KWS_IN_KEY;
kw = cn20k_dummy.kw;
kw_mask = cn20k_dummy.kw_mask;
} else {
max_kw = NPC_MAX_KWS_IN_KEY;
kw = dummy.kw;
kw_mask = dummy.kw_mask;
}
for (i = 0; i < max_kw; i++) {
if (!field->kw_mask[i])
@@ -1247,6 +1254,10 @@ static void rvu_mcam_remove_counter_from_rule(struct rvu *rvu, u16 pcifunc,
{
struct npc_mcam *mcam = &rvu->hw->mcam;
/* There is no counter allotted for cn20k */
if (is_cn20k(rvu->pdev))
return;
mutex_lock(&mcam->lock);
__rvu_mcam_remove_counter_from_rule(rvu, pcifunc, rule);
@@ -1296,8 +1307,17 @@ static int npc_mcast_update_action_index(struct rvu *rvu, struct npc_install_flo
static void
npc_populate_mcam_mdata(struct rvu *rvu,
struct mcam_entry_mdata *mdata,
struct cn20k_mcam_entry *cn20k_entry,
struct mcam_entry *entry)
{
if (is_cn20k(rvu->pdev)) {
mdata->kw = cn20k_entry->kw;
mdata->kw_mask = cn20k_entry->kw_mask;
mdata->action = &cn20k_entry->action;
mdata->vtag_action = &cn20k_entry->vtag_action;
mdata->max_kw = NPC_CN20K_MAX_KWS_IN_KEY;
return;
}
mdata->kw = entry->kw;
mdata->kw_mask = entry->kw_mask;
mdata->action = &entry->action;
@@ -1417,9 +1437,11 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
bool pf_set_vfs_mac)
{
struct rvu_npc_mcam_rule *def_ucast_rule = pfvf->def_ucast_rule;
struct npc_cn20k_mcam_write_entry_req cn20k_wreq = { 0 };
u64 features, installed_features, missing_features = 0;
struct npc_mcam_write_entry_req write_req = { 0 };
struct npc_mcam *mcam = &rvu->hw->mcam;
struct cn20k_mcam_entry *cn20k_entry;
struct mcam_entry_mdata mdata = { };
struct rvu_npc_mcam_rule dummy = { 0 };
struct rvu_npc_mcam_rule *rule;
@@ -1432,11 +1454,12 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
installed_features = req->features;
features = req->features;
entry = &write_req.entry_data;
entry_index = req->entry;
npc_populate_mcam_mdata(rvu, &mdata,
&write_req.entry_data);
cn20k_entry = &cn20k_wreq.entry_data;
entry = &write_req.entry_data;
npc_populate_mcam_mdata(rvu, &mdata, cn20k_entry, entry);
npc_update_flow(rvu, &mdata, features, &req->packet, &req->mask, &dummy,
req->intf, blkaddr);
@@ -1484,51 +1507,90 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
new = true;
}
/* allocate new counter if rule has no counter */
if (!req->default_rule && req->set_cntr && !rule->has_cntr)
rvu_mcam_add_counter_to_rule(rvu, owner, rule, rsp);
if (!is_cn20k(rvu->pdev)) {
write_req.hdr.pcifunc = owner;
/* if user wants to delete an existing counter for a rule then
* free the counter
*/
if (!req->set_cntr && rule->has_cntr)
rvu_mcam_remove_counter_from_rule(rvu, owner, rule);
/* allocate new counter if rule has no counter */
if (!req->default_rule && req->set_cntr && !rule->has_cntr)
rvu_mcam_add_counter_to_rule(rvu, owner, rule, rsp);
write_req.hdr.pcifunc = owner;
/* if user wants to delete an existing counter for a rule then
* free the counter
*/
if (!req->set_cntr && rule->has_cntr)
rvu_mcam_remove_counter_from_rule(rvu, owner, rule);
/* AF owns the default rules so change the owner just to relax
* the checks in rvu_mbox_handler_npc_mcam_write_entry
*/
if (req->default_rule)
write_req.hdr.pcifunc = 0;
/* AF owns the default rules so change the owner just to relax
* the checks in rvu_mbox_handler_npc_mcam_write_entry
*/
if (req->default_rule)
write_req.hdr.pcifunc = 0;
write_req.entry = entry_index;
write_req.intf = req->intf;
write_req.enable_entry = (u8)enable;
/* if counter is available then clear and use it */
if (req->set_cntr && rule->has_cntr) {
rvu_write64(rvu, blkaddr, NPC_AF_MATCH_STATX(rule->cntr), req->cntr_val);
write_req.set_cntr = 1;
write_req.cntr = rule->cntr;
write_req.entry = entry_index;
write_req.intf = req->intf;
write_req.enable_entry = (u8)enable;
/* if counter is available then clear and use it */
if (req->set_cntr && rule->has_cntr) {
rvu_write64(rvu, blkaddr,
NPC_AF_MATCH_STATX(rule->cntr),
req->cntr_val);
write_req.set_cntr = 1;
write_req.cntr = rule->cntr;
}
goto update_rule;
}
cn20k_wreq.hdr.pcifunc = owner;
if (req->default_rule)
cn20k_wreq.hdr.pcifunc = 0;
cn20k_wreq.entry = entry_index;
cn20k_wreq.intf = req->intf;
cn20k_wreq.enable_entry = (u8)enable;
cn20k_wreq.hw_prio = req->hw_prio;
update_rule:
/* update rule */
memcpy(&rule->packet, &dummy.packet, sizeof(rule->packet));
memcpy(&rule->mask, &dummy.mask, sizeof(rule->mask));
rule->entry = entry_index;
memcpy(&rule->rx_action, &entry->action, sizeof(struct nix_rx_action));
if (is_npc_intf_tx(req->intf))
memcpy(&rule->tx_action, &entry->action,
sizeof(struct nix_tx_action));
rule->vtag_action = entry->vtag_action;
if (is_cn20k(rvu->pdev)) {
memcpy(&rule->rx_action, &cn20k_entry->action,
sizeof(struct nix_rx_action));
if (is_npc_intf_tx(req->intf))
memcpy(&rule->tx_action, &cn20k_entry->action,
sizeof(struct nix_tx_action));
rule->vtag_action = cn20k_entry->vtag_action;
} else {
memcpy(&rule->rx_action, &entry->action,
sizeof(struct nix_rx_action));
if (is_npc_intf_tx(req->intf))
memcpy(&rule->tx_action, &entry->action,
sizeof(struct nix_tx_action));
rule->vtag_action = entry->vtag_action;
}
rule->features = installed_features;
rule->default_rule = req->default_rule;
rule->owner = owner;
rule->enable = enable;
rule->chan_mask = write_req.entry_data.kw_mask[0] & NPC_KEX_CHAN_MASK;
rule->chan = write_req.entry_data.kw[0] & NPC_KEX_CHAN_MASK;
if (is_cn20k(rvu->pdev)) {
rule->chan_mask = cn20k_wreq.entry_data.kw_mask[0] &
NPC_KEX_CHAN_MASK;
rule->chan = cn20k_wreq.entry_data.kw[0] &
NPC_KEX_CHAN_MASK;
} else {
rule->chan_mask = write_req.entry_data.kw_mask[0] &
NPC_KEX_CHAN_MASK;
rule->chan = write_req.entry_data.kw[0] & NPC_KEX_CHAN_MASK;
}
rule->chan &= rule->chan_mask;
rule->lxmb = dummy.lxmb;
rule->hw_prio = req->hw_prio;
if (is_npc_intf_tx(req->intf))
rule->intf = pfvf->nix_tx_intf;
else
@@ -1540,8 +1602,14 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
pfvf->def_ucast_rule = rule;
/* write to mcam entry registers */
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req,
&write_rsp);
if (is_cn20k(rvu->pdev))
err = rvu_mbox_handler_npc_cn20k_mcam_write_entry(rvu,
&cn20k_wreq,
&write_rsp);
else
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req,
&write_rsp);
if (err) {
rvu_mcam_remove_counter_from_rule(rvu, owner, rule);
if (new) {
@@ -1782,23 +1850,25 @@ static int npc_update_dmac_value(struct rvu *rvu, int npcblkaddr,
struct rvu_npc_mcam_rule *rule,
struct rvu_pfvf *pfvf)
{
struct npc_cn20k_mcam_write_entry_req cn20k_wreq = { 0 };
struct npc_mcam_write_entry_req write_req = { 0 };
struct npc_mcam *mcam = &rvu->hw->mcam;
struct mcam_entry_mdata mdata = { };
struct npc_mcam *mcam = &rvu->hw->mcam;
struct cn20k_mcam_entry *cn20k_entry;
struct mcam_entry *entry;
u8 intf, enable, hw_prio;
struct msg_rsp rsp;
int err;
cn20k_entry = &cn20k_wreq.entry_data;
entry = &write_req.entry_data;
npc_populate_mcam_mdata(rvu, &mdata, entry);
npc_populate_mcam_mdata(rvu, &mdata, cn20k_entry, entry);
ether_addr_copy(rule->packet.dmac, pfvf->mac_addr);
if (is_cn20k(rvu->pdev))
npc_cn20k_read_mcam_entry(rvu, npcblkaddr, rule->entry,
entry, &intf,
cn20k_entry, &intf,
&enable, &hw_prio);
else
npc_read_mcam_entry(rvu, mcam, npcblkaddr, rule->entry,
@@ -1808,12 +1878,21 @@ static int npc_update_dmac_value(struct rvu *rvu, int npcblkaddr,
ether_addr_to_u64(pfvf->mac_addr), 0,
0xffffffffffffull, 0, intf);
write_req.hdr.pcifunc = rule->owner;
write_req.entry = rule->entry;
write_req.intf = pfvf->nix_rx_intf;
mutex_unlock(&mcam->lock);
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req, &rsp);
if (is_cn20k(rvu->pdev)) {
cn20k_wreq.hdr.pcifunc = rule->owner;
cn20k_wreq.entry = rule->entry;
cn20k_wreq.intf = pfvf->nix_rx_intf;
err = rvu_mbox_handler_npc_cn20k_mcam_write_entry(rvu,
&cn20k_wreq,
&rsp);
} else {
write_req.hdr.pcifunc = rule->owner;
write_req.entry = rule->entry;
write_req.intf = pfvf->nix_rx_intf;
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req,
&rsp);
}
mutex_lock(&mcam->lock);
return err;
@@ -1901,6 +1980,7 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask,
u64 bcast_mcast_val, u64 bcast_mcast_mask)
{
struct npc_cn20k_mcam_write_entry_req cn20k_req = { 0 };
struct npc_mcam_alloc_counter_req cntr_req = { 0 };
struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 };
struct npc_mcam_write_entry_req req = { 0 };
@@ -1949,19 +2029,24 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
/* Reserve slot 0 */
npc_mcam_rsrcs_reserve(rvu, blkaddr, mcam_idx);
/* Allocate counter for this single drop on non hit rule */
cntr_req.hdr.pcifunc = 0; /* AF request */
cntr_req.contig = true;
cntr_req.count = 1;
err = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp);
if (err) {
dev_err(rvu->dev, "%s: Err to allocate cntr for drop rule (err=%d)\n",
__func__, err);
return -EFAULT;
if (!is_cn20k(rvu->pdev)) {
/* Allocate counter for this single drop on non hit rule */
cntr_req.hdr.pcifunc = 0; /* AF request */
cntr_req.contig = true;
cntr_req.count = 1;
err = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req,
&cntr_rsp);
if (err) {
dev_err(rvu->dev,
"%s: Err to allocate cntr for drop rule (err=%d)\n",
__func__, err);
return -EFAULT;
}
*counter_idx = cntr_rsp.cntr;
}
*counter_idx = cntr_rsp.cntr;
npc_populate_mcam_mdata(rvu, &mdata,
&cn20k_req.entry_data,
&req.entry_data);
/* Fill in fields for this mcam entry */
@@ -1972,6 +2057,23 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
npc_update_entry(rvu, NPC_LXMB, &mdata, bcast_mcast_val, 0,
bcast_mcast_mask, 0, NIX_INTF_RX);
if (is_cn20k(rvu->pdev)) {
cn20k_req.intf = NIX_INTF_RX;
cn20k_req.entry = mcam_idx;
err = rvu_mbox_handler_npc_cn20k_mcam_write_entry(rvu,
&cn20k_req,
&rsp);
if (err) {
dev_err(rvu->dev,
"%s: Installation of single drop on non hit rule at %d failed\n",
__func__, mcam_idx);
return err;
}
goto enable_entry;
}
req.intf = NIX_INTF_RX;
req.set_cntr = true;
req.cntr = cntr_rsp.cntr;
@@ -1979,14 +2081,17 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &req, &rsp);
if (err) {
dev_err(rvu->dev, "%s: Installation of single drop on non hit rule at %d failed\n",
dev_err(rvu->dev,
"%s: Installation of single drop on non hit rule at %d failed\n",
__func__, mcam_idx);
return err;
}
dev_err(rvu->dev, "%s: Installed single drop on non hit rule at %d, cntr=%d\n",
dev_err(rvu->dev,
"%s: Installed single drop on non hit rule at %d, cntr=%d\n",
__func__, mcam_idx, req.cntr);
enable_entry:
/* disable entry at Bank 0, index 0 */
npc_enable_mcam_entry(rvu, mcam, blkaddr, mcam_idx, false);