octeontx2-af: Add new devlink param to configure maximum usable NIX block LFs
On some silicon variants the number of available CAM entries are less. Reserving one entry for each NIX-LF for default DMAC based pkt forwarding rules will reduce the number of available CAM entries further. Hence add configurability via devlink to set maximum number of NIX-LFs needed which inturn frees up some CAM entries. Signed-off-by: Suman Ghosh <sumang@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3a3af3aedb
commit
dd78428786
@ -949,6 +949,8 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
|
||||
u64 bcast_mcast_val, u64 bcast_mcast_mask);
|
||||
void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx);
|
||||
bool npc_is_feature_supported(struct rvu *rvu, u64 features, u8 intf);
|
||||
int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr);
|
||||
void npc_mcam_rsrcs_deinit(struct rvu *rvu);
|
||||
|
||||
/* CPT APIs */
|
||||
int rvu_cpt_register_interrupts(struct rvu *rvu);
|
||||
|
@ -1237,6 +1237,7 @@ enum rvu_af_dl_param_id {
|
||||
RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
|
||||
RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
|
||||
RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
|
||||
RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
|
||||
};
|
||||
|
||||
static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
|
||||
@ -1354,6 +1355,79 @@ static int rvu_af_dl_npc_mcam_high_zone_percent_validate(struct devlink *devlink
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rvu_af_dl_nix_maxlf_get(struct devlink *devlink, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
|
||||
struct rvu *rvu = rvu_dl->rvu;
|
||||
|
||||
ctx->val.vu16 = (u16)rvu_get_nixlf_count(rvu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rvu_af_dl_nix_maxlf_set(struct devlink *devlink, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
|
||||
struct rvu *rvu = rvu_dl->rvu;
|
||||
struct rvu_block *block;
|
||||
int blkaddr = 0;
|
||||
|
||||
npc_mcam_rsrcs_deinit(rvu);
|
||||
blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
|
||||
while (blkaddr) {
|
||||
block = &rvu->hw->block[blkaddr];
|
||||
block->lf.max = ctx->val.vu16;
|
||||
blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
|
||||
}
|
||||
|
||||
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
|
||||
npc_mcam_rsrcs_init(rvu, blkaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rvu_af_dl_nix_maxlf_validate(struct devlink *devlink, u32 id,
|
||||
union devlink_param_value val,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
|
||||
struct rvu *rvu = rvu_dl->rvu;
|
||||
u16 max_nix0_lf, max_nix1_lf;
|
||||
struct npc_mcam *mcam;
|
||||
u64 cfg;
|
||||
|
||||
cfg = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_CONST2);
|
||||
max_nix0_lf = cfg & 0xFFF;
|
||||
cfg = rvu_read64(rvu, BLKADDR_NIX1, NIX_AF_CONST2);
|
||||
max_nix1_lf = cfg & 0xFFF;
|
||||
|
||||
/* Do not allow user to modify maximum NIX LFs while mcam entries
|
||||
* have already been assigned.
|
||||
*/
|
||||
mcam = &rvu->hw->mcam;
|
||||
if (mcam->bmap_fcnt < mcam->bmap_entries) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"mcam entries have already been assigned, can't resize");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (max_nix0_lf && val.vu16 > max_nix0_lf) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"requested nixlf is greater than the max supported nix0_lf");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (max_nix1_lf && val.vu16 > max_nix1_lf) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"requested nixlf is greater than the max supported nix1_lf");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct devlink_param rvu_af_dl_params[] = {
|
||||
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
|
||||
"dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
|
||||
@ -1375,6 +1449,12 @@ static const struct devlink_param rvu_af_dl_param_exact_match[] = {
|
||||
rvu_af_dl_npc_mcam_high_zone_percent_get,
|
||||
rvu_af_dl_npc_mcam_high_zone_percent_set,
|
||||
rvu_af_dl_npc_mcam_high_zone_percent_validate),
|
||||
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
|
||||
"nix_maxlf", DEVLINK_PARAM_TYPE_U16,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
|
||||
rvu_af_dl_nix_maxlf_get,
|
||||
rvu_af_dl_nix_maxlf_set,
|
||||
rvu_af_dl_nix_maxlf_validate),
|
||||
};
|
||||
|
||||
/* Devlink switch mode */
|
||||
|
@ -1846,7 +1846,21 @@ static void npc_parser_profile_init(struct rvu *rvu, int blkaddr)
|
||||
npc_program_kpu_profile(rvu, blkaddr, idx, &rvu->kpu.kpu[idx]);
|
||||
}
|
||||
|
||||
static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
void npc_mcam_rsrcs_deinit(struct rvu *rvu)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
|
||||
kfree(mcam->bmap);
|
||||
kfree(mcam->bmap_reverse);
|
||||
kfree(mcam->entry2pfvf_map);
|
||||
kfree(mcam->cntr2pfvf_map);
|
||||
kfree(mcam->entry2cntr_map);
|
||||
kfree(mcam->cntr_refcnt);
|
||||
kfree(mcam->entry2target_pffunc);
|
||||
kfree(mcam->counters.bmap);
|
||||
}
|
||||
|
||||
int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
{
|
||||
int nixlf_count = rvu_get_nixlf_count(rvu);
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
@ -1890,24 +1904,23 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
mcam->pf_offset = mcam->nixlf_offset + nixlf_count;
|
||||
|
||||
/* Allocate bitmaps for managing MCAM entries */
|
||||
mcam->bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(mcam->bmap_entries),
|
||||
sizeof(long), GFP_KERNEL);
|
||||
mcam->bmap = kmalloc_array(BITS_TO_LONGS(mcam->bmap_entries),
|
||||
sizeof(long), GFP_KERNEL);
|
||||
if (!mcam->bmap)
|
||||
return -ENOMEM;
|
||||
|
||||
mcam->bmap_reverse = devm_kcalloc(rvu->dev,
|
||||
BITS_TO_LONGS(mcam->bmap_entries),
|
||||
sizeof(long), GFP_KERNEL);
|
||||
mcam->bmap_reverse = kmalloc_array(BITS_TO_LONGS(mcam->bmap_entries),
|
||||
sizeof(long), GFP_KERNEL);
|
||||
if (!mcam->bmap_reverse)
|
||||
return -ENOMEM;
|
||||
goto free_bmap;
|
||||
|
||||
mcam->bmap_fcnt = mcam->bmap_entries;
|
||||
|
||||
/* Alloc memory for saving entry to RVU PFFUNC allocation mapping */
|
||||
mcam->entry2pfvf_map = devm_kcalloc(rvu->dev, mcam->bmap_entries,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
mcam->entry2pfvf_map = kmalloc_array(mcam->bmap_entries,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!mcam->entry2pfvf_map)
|
||||
return -ENOMEM;
|
||||
goto free_bmap_reverse;
|
||||
|
||||
/* Reserve 1/8th of MCAM entries at the bottom for low priority
|
||||
* allocations and another 1/8th at the top for high priority
|
||||
@ -1926,31 +1939,31 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
*/
|
||||
err = rvu_alloc_bitmap(&mcam->counters);
|
||||
if (err)
|
||||
return err;
|
||||
goto free_entry_map;
|
||||
|
||||
mcam->cntr2pfvf_map = devm_kcalloc(rvu->dev, mcam->counters.max,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
mcam->cntr2pfvf_map = kmalloc_array(mcam->counters.max,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!mcam->cntr2pfvf_map)
|
||||
goto free_mem;
|
||||
goto free_cntr_bmap;
|
||||
|
||||
/* Alloc memory for MCAM entry to counter mapping and for tracking
|
||||
* counter's reference count.
|
||||
*/
|
||||
mcam->entry2cntr_map = devm_kcalloc(rvu->dev, mcam->bmap_entries,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
mcam->entry2cntr_map = kmalloc_array(mcam->bmap_entries,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!mcam->entry2cntr_map)
|
||||
goto free_mem;
|
||||
goto free_cntr_map;
|
||||
|
||||
mcam->cntr_refcnt = devm_kcalloc(rvu->dev, mcam->counters.max,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
mcam->cntr_refcnt = kmalloc_array(mcam->counters.max,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!mcam->cntr_refcnt)
|
||||
goto free_mem;
|
||||
goto free_entry_cntr_map;
|
||||
|
||||
/* Alloc memory for saving target device of mcam rule */
|
||||
mcam->entry2target_pffunc = devm_kcalloc(rvu->dev, mcam->total_entries,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
mcam->entry2target_pffunc = kmalloc_array(mcam->total_entries,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!mcam->entry2target_pffunc)
|
||||
goto free_mem;
|
||||
goto free_cntr_refcnt;
|
||||
|
||||
for (index = 0; index < mcam->bmap_entries; index++) {
|
||||
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
|
||||
@ -1964,8 +1977,21 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
|
||||
return 0;
|
||||
|
||||
free_mem:
|
||||
free_cntr_refcnt:
|
||||
kfree(mcam->cntr_refcnt);
|
||||
free_entry_cntr_map:
|
||||
kfree(mcam->entry2cntr_map);
|
||||
free_cntr_map:
|
||||
kfree(mcam->cntr2pfvf_map);
|
||||
free_cntr_bmap:
|
||||
kfree(mcam->counters.bmap);
|
||||
free_entry_map:
|
||||
kfree(mcam->entry2pfvf_map);
|
||||
free_bmap_reverse:
|
||||
kfree(mcam->bmap_reverse);
|
||||
free_bmap:
|
||||
kfree(mcam->counters.bmap);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -2173,6 +2199,7 @@ void rvu_npc_freemem(struct rvu *rvu)
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
|
||||
kfree(pkind->rsrc.bmap);
|
||||
npc_mcam_rsrcs_deinit(rvu);
|
||||
kfree(mcam->counters.bmap);
|
||||
if (rvu->kpu_prfl_addr)
|
||||
iounmap(rvu->kpu_prfl_addr);
|
||||
|
Loading…
Reference in New Issue
Block a user