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 --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 21 ++++++-- .../marvell/octeontx2/af/rvu_npc_fs.c | 12 ++++- .../marvell/octeontx2/nic/otx2_flows.c | 48 +++++++++++++------ 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c index 88cfa6c67266..ff5baedbc122 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -4438,10 +4438,16 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc) pfvf = rvu_get_pfvf(rvu, pcifunc); pfvf->hw_prio = NPC_DFT_RULE_PRIO; + if (npc_priv.kw == NPC_MCAM_KEY_X4) { + req.kw_type = NPC_MCAM_KEY_X4; + req.ref_entry = eidx & (npc_priv.bank_depth - 1); + } else { + req.kw_type = NPC_MCAM_KEY_X2; + req.ref_entry = eidx; + } + req.contig = false; req.ref_prio = NPC_MCAM_HIGHER_PRIO; - req.ref_entry = eidx; - req.kw_type = NPC_MCAM_KEY_X2; req.count = cnt; req.hdr.pcifunc = pcifunc; @@ -4471,11 +4477,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