Default CN20K NPC rule allocation now keys off the active MCAM keyword
width: use X4 with a bank-masked reference index when the silicon uses
X4 keys, and X2 with the raw index otherwise (replacing the previous
always-X2 / eidx + 1 behaviour).

In the AF flow-install path, flows that need more than 256 key bits
query the NPC profile; if the platform is fixed to X2 entries, fail
with -EOPNOTSUPP instead of requesting X4. Otherwise select X4 for the
MCAM alloc.

On the PF, cache and pass the profile kw_type from npc_get_pfl_info
through otx2_mcam_pfl_info_get(), and use it when allocating MCAM
entries for RSS/defaults and when installing ethtool flows on CN20K,
including masking the reference index for X4 slot layout.

Signed-off-by: Ratheesh Kannoth <[email protected]>
---
 .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 11 ++++-
 .../marvell/octeontx2/af/rvu_npc_fs.c         | 12 ++++-
 .../marvell/octeontx2/nic/otx2_flows.c        | 48 +++++++++++++------
 3 files changed, 53 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 67dfbe5ca903..15b3f29d60ee 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -4467,11 +4467,18 @@ 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 & (npc_priv.bank_depth - 1);
+       } else {
+               req.kw_type = NPC_MCAM_KEY_X2;
+               req.ref_entry = eidx;
+       }
+
        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 6ae9cdcb608b..d20eb0e47d7d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -1671,9 +1671,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)) {
@@ -1697,8 +1699,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));
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

Reply via email to