mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
octeontx2-af: support for coalescing KPU profiles
Adding support to load a new type of KPU image, known as coalesced/ consolidated KPU image via firmware database. This image is a consolidation of multiple KPU profiles into a single image. During kernel bootup this coalesced image will be read via firmware database and only the relevant KPU profile will be loaded. Existing functionality of loading single KPU/MKEX profile is intact as the images are differentiated based on the image signature. Signed-off-by: Harman Kalra <hkalra@marvell.com> Signed-off-by: Sunil Kovvuri Goutham <Sunil.Goutham@marvell.com> Signed-off-by: George Cherian <george.cherian@marvell.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
c87e6b1395
commit
11c730bfbf
2 changed files with 79 additions and 15 deletions
|
@ -427,6 +427,17 @@ struct nix_tx_action {
|
||||||
#define NIXLF_BCAST_ENTRY 1
|
#define NIXLF_BCAST_ENTRY 1
|
||||||
#define NIXLF_PROMISC_ENTRY 2
|
#define NIXLF_PROMISC_ENTRY 2
|
||||||
|
|
||||||
|
struct npc_coalesced_kpu_prfl {
|
||||||
|
#define NPC_SIGN 0x00666f727063706e
|
||||||
|
#define NPC_PRFL_NAME "npc_prfls_array"
|
||||||
|
#define NPC_NAME_LEN 32
|
||||||
|
__le64 signature; /* "npcprof\0" (8 bytes/ASCII characters) */
|
||||||
|
u8 name[NPC_NAME_LEN]; /* KPU Profile name */
|
||||||
|
u64 version; /* KPU firmware/profile version */
|
||||||
|
u8 num_prfl; /* No of NPC profiles. */
|
||||||
|
u16 prfl_sz[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct npc_mcam_kex {
|
struct npc_mcam_kex {
|
||||||
/* MKEX Profle Header */
|
/* MKEX Profle Header */
|
||||||
u64 mkex_sign; /* "mcam-kex-profile" (8 bytes/ASCII characters) */
|
u64 mkex_sign; /* "mcam-kex-profile" (8 bytes/ASCII characters) */
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#define NPC_KEX_CHAN_MASK 0xFFFULL
|
#define NPC_KEX_CHAN_MASK 0xFFFULL
|
||||||
#define NPC_KEX_PF_FUNC_MASK 0xFFFFULL
|
#define NPC_KEX_PF_FUNC_MASK 0xFFFFULL
|
||||||
|
|
||||||
|
#define ALIGN_8B_CEIL(__a) (((__a) + 7) & (-8))
|
||||||
|
|
||||||
static const char def_pfl_name[] = "default";
|
static const char def_pfl_name[] = "default";
|
||||||
|
|
||||||
static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
|
static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
|
||||||
|
@ -1417,28 +1419,78 @@ static int npc_apply_custom_kpu(struct rvu *rvu,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int npc_load_kpu_prfl_img(struct rvu *rvu, void __iomem *prfl_addr,
|
||||||
|
u64 prfl_sz, const char *kpu_profile)
|
||||||
|
{
|
||||||
|
struct npc_kpu_profile_fwdata *kpu_data = NULL;
|
||||||
|
int rc = -EINVAL;
|
||||||
|
|
||||||
|
kpu_data = (struct npc_kpu_profile_fwdata __force *)prfl_addr;
|
||||||
|
if (le64_to_cpu(kpu_data->signature) == KPU_SIGN &&
|
||||||
|
!strncmp(kpu_data->name, kpu_profile, KPU_NAME_LEN)) {
|
||||||
|
dev_info(rvu->dev, "Loading KPU profile from firmware db: %s\n",
|
||||||
|
kpu_profile);
|
||||||
|
rvu->kpu_fwdata = kpu_data;
|
||||||
|
rvu->kpu_fwdata_sz = prfl_sz;
|
||||||
|
rvu->kpu_prfl_addr = prfl_addr;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int npc_fwdb_detect_load_prfl_img(struct rvu *rvu, uint64_t prfl_sz,
|
||||||
|
const char *kpu_profile)
|
||||||
|
{
|
||||||
|
struct npc_coalesced_kpu_prfl *img_data = NULL;
|
||||||
|
int i = 0, rc = -EINVAL;
|
||||||
|
void __iomem *kpu_prfl_addr;
|
||||||
|
u16 offset;
|
||||||
|
|
||||||
|
img_data = (struct npc_coalesced_kpu_prfl __force *)rvu->kpu_prfl_addr;
|
||||||
|
if (le64_to_cpu(img_data->signature) == KPU_SIGN &&
|
||||||
|
!strncmp(img_data->name, kpu_profile, KPU_NAME_LEN)) {
|
||||||
|
/* Loaded profile is a single KPU profile. */
|
||||||
|
rc = npc_load_kpu_prfl_img(rvu, rvu->kpu_prfl_addr,
|
||||||
|
prfl_sz, kpu_profile);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loaded profile is coalesced image, offset of first KPU profile.*/
|
||||||
|
offset = offsetof(struct npc_coalesced_kpu_prfl, prfl_sz) +
|
||||||
|
(img_data->num_prfl * sizeof(uint16_t));
|
||||||
|
/* Check if mapped image is coalesced image. */
|
||||||
|
while (i < img_data->num_prfl) {
|
||||||
|
/* Profile image offsets are rounded up to next 8 multiple.*/
|
||||||
|
offset = ALIGN_8B_CEIL(offset);
|
||||||
|
kpu_prfl_addr = (void __iomem *)((uintptr_t)rvu->kpu_prfl_addr +
|
||||||
|
offset);
|
||||||
|
rc = npc_load_kpu_prfl_img(rvu, kpu_prfl_addr,
|
||||||
|
img_data->prfl_sz[i], kpu_profile);
|
||||||
|
if (!rc)
|
||||||
|
break;
|
||||||
|
/* Calculating offset of profile image based on profile size.*/
|
||||||
|
offset += img_data->prfl_sz[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int npc_load_kpu_profile_fwdb(struct rvu *rvu, const char *kpu_profile)
|
static int npc_load_kpu_profile_fwdb(struct rvu *rvu, const char *kpu_profile)
|
||||||
{
|
{
|
||||||
struct npc_kpu_profile_fwdata *kpu_fw = NULL;
|
int ret = -EINVAL;
|
||||||
u64 prfl_sz;
|
u64 prfl_sz;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Setting up the mapping for NPC profile image */
|
/* Setting up the mapping for NPC profile image */
|
||||||
ret = npc_fwdb_prfl_img_map(rvu, &rvu->kpu_prfl_addr, &prfl_sz);
|
ret = npc_fwdb_prfl_img_map(rvu, &rvu->kpu_prfl_addr, &prfl_sz);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto done;
|
||||||
|
|
||||||
rvu->kpu_fwdata =
|
/* Detect if profile is coalesced or single KPU profile and load */
|
||||||
(struct npc_kpu_profile_fwdata __force *)rvu->kpu_prfl_addr;
|
ret = npc_fwdb_detect_load_prfl_img(rvu, prfl_sz, kpu_profile);
|
||||||
rvu->kpu_fwdata_sz = prfl_sz;
|
if (ret == 0)
|
||||||
|
goto done;
|
||||||
kpu_fw = rvu->kpu_fwdata;
|
|
||||||
if (le64_to_cpu(kpu_fw->signature) == KPU_SIGN &&
|
|
||||||
!strncmp(kpu_fw->name, kpu_profile, KPU_NAME_LEN)) {
|
|
||||||
dev_info(rvu->dev, "Loading KPU profile from firmware db: %s\n",
|
|
||||||
kpu_profile);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cleaning up if KPU profile image from fwdata is not valid. */
|
/* Cleaning up if KPU profile image from fwdata is not valid. */
|
||||||
if (rvu->kpu_prfl_addr) {
|
if (rvu->kpu_prfl_addr) {
|
||||||
|
@ -1448,7 +1500,8 @@ static int npc_load_kpu_profile_fwdb(struct rvu *rvu, const char *kpu_profile)
|
||||||
rvu->kpu_fwdata = NULL;
|
rvu->kpu_fwdata = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
done:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void npc_load_kpu_profile(struct rvu *rvu)
|
static void npc_load_kpu_profile(struct rvu *rvu)
|
||||||
|
|
Loading…
Add table
Reference in a new issue