mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
octeontx2: cn20k: Respect NPC MCAM X2/X4 profile in flows and DFT alloc
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 <rkannoth@marvell.com> Link: https://patch.msgid.link/20260609040453.711932-9-rkannoth@marvell.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
c0c9ac8815
commit
ad804b3250
|
|
@ -4496,10 +4496,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;
|
||||
|
||||
|
|
@ -4529,11 +4535,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,
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user