]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
octeontx2-af: npc: cn20k: Add new mailboxes for CN20K silicon
authorSuman Ghosh <sumang@marvell.com>
Tue, 24 Feb 2026 08:00:04 +0000 (13:30 +0530)
committerJakub Kicinski <kuba@kernel.org>
Sat, 28 Feb 2026 18:29:26 +0000 (10:29 -0800)
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>
drivers/net/ethernet/marvell/octeontx2/af/cn20k/mbox_init.c
drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h
drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/npc.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c

index bd3aab7770ddf5e8ef1855d16b6bc1c1f6e0f4db..71401dec0d776ba71f49f2a85133673e88dc5ca7 100644 (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;
 }
index cb8a37a2756a6a88a4b847346b433245e895c51e..7c3fdccbce2a4f1234f500df7ab2c5143af8aea1 100644 (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 @@ read_action:
        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) {
index 861622741174c8c75a5a533a691286187a841938..4b5cdbef334cb6aae437677f4ed8982843183b46 100644 (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);
index bf50d999528b1ca309f87cb9e189c05d4bdc4579..8bfaa507ee502eedad41925cc635f6c677d66fdb 100644 (file)
 #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)
index a4e79828a84c2af003e7d714e126ec512182c9aa..e004271124df7d853eafdefc742eb309d7426b1c 100644 (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 {
index cb05ec69e0b3e98b78ca8c81dd6bbee76e52d3a3..cefc5d70f3e492ab9640cb268edb175ba61fd144 100644 (file)
@@ -644,6 +644,7 @@ struct rvu_npc_mcam_rule {
        u16 chan;
        u16 chan_mask;
        u8 lxmb;
+       u8 hw_prio;
 };
 
 #endif /* NPC_H */
index 40591134cb1c5cbfccf8f9f8f94986b36418254f..1c8f657719b2f8d262fb6d29a3281f7becadf3c7 100644 (file)
@@ -600,6 +600,7 @@ check_pf:
 
 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 @@ setup_vfmsix:
        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;
 
index a53bb5c924ef6dc3f064346f72b4161b651ae61a..f811d6b5c5452f500305fc2a2c5f6cc8a535833b 100644 (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 */
index 425d3a43c0b81e3719f214079a39dcc3691cc78e..620724dad0936d60828d62a02ebae0957b2a02d8 100644 (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;
index 5208cd0840552a116ef048a491c0a696024db412..a7e84c8624750236a62d8be63b15df97577245f3 100644 (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;
index 117038c793ea67463da81494e2f3ea5f16e0f491..802b68cf228c1bf0d42fc2d7dcb9a1c173202151 100644 (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 @@ skip_cn10k_config:
                         * 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 @@ find_rule:
                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 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);
+       if (!is_cn20k(rvu->pdev)) {
+               write_req.hdr.pcifunc = owner;
+
+               /* 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 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;
+
+               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;
+       }
 
-       write_req.hdr.pcifunc = owner;
+       cn20k_wreq.hdr.pcifunc = owner;
 
-       /* 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;
+               cn20k_wreq.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;
-       }
+       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 @@ find_rule:
                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);