Commit 11c730bf authored by Harman Kalra's avatar Harman Kalra Committed by Jakub Kicinski

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: default avatarHarman Kalra <hkalra@marvell.com>
Signed-off-by: default avatarSunil Kovvuri Goutham <Sunil.Goutham@marvell.com>
Signed-off-by: default avatarGeorge Cherian <george.cherian@marvell.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c87e6b13
...@@ -427,6 +427,17 @@ struct nix_tx_action { ...@@ -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 @@ ...@@ -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, ...@@ -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) ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment