X4 profile users won't alloc x2 entries. Allocating x2 entries would cause under utilized subbanks(X2). Avoid this in X4 kex profile, all allocations will be from x4 subbank. Fixes: 09d3b7a1403f ("octeontx2-af: npc: cn20k: Allocate default MCAM indexes") Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 27 +++++++++-- .../marvell/octeontx2/nic/otx2_flows.c | 48 +++++++++++++------ 2 files changed, 57 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 8630a6a73387..97acba77ff88 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -3589,9 +3589,10 @@ int npc_defrag_move_vdx_to_free(struct rvu *rvu, struct npc_defrag_node *v, int cnt, u16 *save) { + u16 new_midx, old_midx, vidx, target_pf; struct npc_mcam *mcam = &rvu->hw->mcam; + struct rvu_npc_mcam_rule *rule, *tmp; int i, vidx_cnt, rc, sb_off; - u16 new_midx, old_midx, vidx; struct npc_subbank *sb; bool deleted; u16 pcifunc; @@ -3710,8 +3711,22 @@ int npc_defrag_move_vdx_to_free(struct rvu *rvu, mcam->entry2pfvf_map[new_midx] = pcifunc; /* Counter is not preserved */ mcam->entry2cntr_map[new_midx] = new_midx; + + target_pf = mcam->entry2target_pffunc[old_midx]; + mcam->entry2target_pffunc[new_midx] = target_pf; + mcam->entry2target_pffunc[old_midx] = 0; + npc_mcam_set_bit(mcam, new_midx); + /* Note: list order is not functionally required for mcam_rules */ + list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) { + if (rule->entry != old_midx) + continue; + + rule->entry = new_midx; + break; + } + /* Mark as invalid */ v->vidx[vidx_cnt - i - 1] = -1; save[cnt - i - 1] = -1; @@ -4274,10 +4289,16 @@ int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc) pfvf = rvu_get_pfvf(rvu, pcifunc); pfvf->hw_prio = NPC_DFT_RULE_PRIO; + if (npc_priv.kw == NPC_MCAM_KEY_X4) { + req.kw_type = NPC_MCAM_KEY_X4; + req.ref_entry = eidx & (npc_priv.bank_depth - 1); + } else { + req.kw_type = NPC_MCAM_KEY_X2; + req.ref_entry = eidx; + } + req.contig = false; req.ref_prio = NPC_MCAM_HIGHER_PRIO; - req.ref_entry = eidx; - req.kw_type = NPC_MCAM_KEY_X2; req.count = cnt; req.hdr.pcifunc = pcifunc; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 38cc539d724d..5dd0591fed99 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -37,14 +37,13 @@ static void otx2_clear_ntuple_flow_info(struct otx2_nic *pfvf, struct otx2_flow_ flow_cfg->max_flows = 0; } -static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, bool *is_x2, - u16 *x4_slots) +static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, u16 *x4_slots, u8 *kw_type) { struct npc_get_pfl_info_rsp *rsp; struct msg_req *req; static struct { bool is_set; - bool is_x2; + u8 kw_type; u16 x4_slots; } pfl_info; @@ -53,8 +52,8 @@ static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, bool *is_x2, */ mutex_lock(&pfvf->mbox.lock); if (pfl_info.is_set) { - *is_x2 = pfl_info.is_x2; *x4_slots = pfl_info.x4_slots; + *kw_type = pfl_info.kw_type; mutex_unlock(&pfvf->mbox.lock); return 0; } @@ -79,16 +78,16 @@ static int otx2_mcam_pfl_info_get(struct otx2_nic *pfvf, bool *is_x2, return -EFAULT; } - *is_x2 = (rsp->kw_type == NPC_MCAM_KEY_X2); - if (*is_x2) - *x4_slots = 0; + pfl_info.kw_type = rsp->kw_type; + if (rsp->kw_type == NPC_MCAM_KEY_X2) + pfl_info.x4_slots = 0; else - *x4_slots = rsp->x4_slots; - - pfl_info.is_x2 = *is_x2; - pfl_info.x4_slots = *x4_slots; + pfl_info.x4_slots = rsp->x4_slots; pfl_info.is_set = true; + *x4_slots = pfl_info.x4_slots; + *kw_type = pfl_info.kw_type; + mutex_unlock(&pfvf->mbox.lock); return 0; } @@ -164,6 +163,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count) u16 dft_idx = 0, x4_slots = 0; int ent, allocated = 0, ref; bool is_x2 = false; + u8 kw_type = 0; int rc; /* Free current ones and allocate new ones with requested count */ @@ -182,12 +182,14 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count) } if (is_cn20k(pfvf->pdev)) { - rc = otx2_mcam_pfl_info_get(pfvf, &is_x2, &x4_slots); + rc = otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type); if (rc) { netdev_err(pfvf->netdev, "Error to retrieve profile info\n"); return rc; } + is_x2 = kw_type == NPC_MCAM_KEY_X2; + rc = otx2_get_dft_rl_idx(pfvf, &dft_idx); if (rc) { netdev_err(pfvf->netdev, @@ -289,6 +291,8 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf) struct npc_mcam_alloc_entry_rsp *rsp; int vf_vlan_max_flows, count; int rc, ref, prio, ent; + u8 kw_type = 0; + u16 x4_slots; u16 dft_idx; ref = 0; @@ -315,6 +319,16 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf) if (!flow_cfg->def_ent) return -ENOMEM; + kw_type = NPC_MCAM_KEY_X2; + if (is_cn20k(pfvf->pdev)) { + rc = otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type); + if (rc) { + netdev_err(pfvf->netdev, + "Error to get pfl info\n"); + return rc; + } + } + mutex_lock(&pfvf->mbox.lock); req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox); @@ -324,6 +338,10 @@ int otx2_mcam_entry_init(struct otx2_nic *pfvf) } req->kw_type = NPC_MCAM_KEY_X2; + if (is_cn20k(pfvf->pdev) && kw_type == NPC_MCAM_KEY_X4) { + req->kw_type = NPC_MCAM_KEY_X4; + ref &= (x4_slots - 1); + } req->contig = false; req->count = count; req->ref_prio = prio; @@ -1174,15 +1192,14 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow) #ifdef CONFIG_DCB int vlan_prio, qidx, pfc_rule = 0; #endif + bool modify = false, is_x2; int err, vf = 0, off, sz; - bool modify = false; u8 kw_type = 0; u8 *src, *dst; u16 x4_slots; - bool is_x2; if (is_cn20k(pfvf->pdev)) { - err = otx2_mcam_pfl_info_get(pfvf, &is_x2, &x4_slots); + err = otx2_mcam_pfl_info_get(pfvf, &x4_slots, &kw_type); if (err) { netdev_err(pfvf->netdev, "Error to retrieve NPC profile info, pcifunc=%#x\n", @@ -1190,6 +1207,7 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow) return -EFAULT; } + is_x2 = kw_type == NPC_MCAM_KEY_X2; if (!is_x2) { err = otx2_prepare_flow_request(&flow->flow_spec, &treq); -- 2.43.0