// SPDX-License-Identifier: GPL-2.0
/* Marvell OcteonTX CPT driver
 *
 * Copyright (C) 2019 Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/ctype.h>
#include <linux/firmware.h>
#include "otx_cpt_common.h"
#include "otx_cptpf_ucode.h"
#include "otx_cptpf.h"

#define CSR_DELAY 30
/* Tar archive defines */
#define TAR_MAGIC		"ustar"
#define TAR_MAGIC_LEN		6
#define TAR_BLOCK_LEN		512
#define REGTYPE			'0'
#define AREGTYPE		'\0'

/* tar header as defined in POSIX 1003.1-1990. */
struct tar_hdr_t {
	char name[100];
	char mode[8];
	char uid[8];
	char gid[8];
	char size[12];
	char mtime[12];
	char chksum[8];
	char typeflag;
	char linkname[100];
	char magic[6];
	char version[2];
	char uname[32];
	char gname[32];
	char devmajor[8];
	char devminor[8];
	char prefix[155];
};

struct tar_blk_t {
	union {
		struct tar_hdr_t hdr;
		char block[TAR_BLOCK_LEN];
	};
};

struct tar_arch_info_t {
	struct list_head ucodes;
	const struct firmware *fw;
};

static struct otx_cpt_bitmap get_cores_bmap(struct device *dev,
					   struct otx_cpt_eng_grp_info *eng_grp)
{
	struct otx_cpt_bitmap bmap = { {0} };
	bool found = false;
	int i;

	if (eng_grp->g->engs_num > OTX_CPT_MAX_ENGINES) {
		dev_err(dev, "unsupported number of engines %d on octeontx\n",
			eng_grp->g->engs_num);
		return bmap;
	}

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		if (eng_grp->engs[i].type) {
			bitmap_or(bmap.bits, bmap.bits,
				  eng_grp->engs[i].bmap,
				  eng_grp->g->engs_num);
			bmap.size = eng_grp->g->engs_num;
			found = true;
		}
	}

	if (!found)
		dev_err(dev, "No engines reserved for engine group %d\n",
			eng_grp->idx);
	return bmap;
}

static int is_eng_type(int val, int eng_type)
{
	return val & (1 << eng_type);
}

static int dev_supports_eng_type(struct otx_cpt_eng_grps *eng_grps,
				 int eng_type)
{
	return is_eng_type(eng_grps->eng_types_supported, eng_type);
}

static void set_ucode_filename(struct otx_cpt_ucode *ucode,
			       const char *filename)
{
	strlcpy(ucode->filename, filename, OTX_CPT_UCODE_NAME_LENGTH);
}

static char *get_eng_type_str(int eng_type)
{
	char *str = "unknown";

	switch (eng_type) {
	case OTX_CPT_SE_TYPES:
		str = "SE";
		break;

	case OTX_CPT_AE_TYPES:
		str = "AE";
		break;
	}
	return str;
}

static char *get_ucode_type_str(int ucode_type)
{
	char *str = "unknown";

	switch (ucode_type) {
	case (1 << OTX_CPT_SE_TYPES):
		str = "SE";
		break;

	case (1 << OTX_CPT_AE_TYPES):
		str = "AE";
		break;
	}
	return str;
}

static int get_ucode_type(struct otx_cpt_ucode_hdr *ucode_hdr, int *ucode_type)
{
	char tmp_ver_str[OTX_CPT_UCODE_VER_STR_SZ];
	u32 i, val = 0;
	u8 nn;

	strlcpy(tmp_ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
	for (i = 0; i < strlen(tmp_ver_str); i++)
		tmp_ver_str[i] = tolower(tmp_ver_str[i]);

	nn = ucode_hdr->ver_num.nn;
	if (strnstr(tmp_ver_str, "se-", OTX_CPT_UCODE_VER_STR_SZ) &&
	    (nn == OTX_CPT_SE_UC_TYPE1 || nn == OTX_CPT_SE_UC_TYPE2 ||
	     nn == OTX_CPT_SE_UC_TYPE3))
		val |= 1 << OTX_CPT_SE_TYPES;
	if (strnstr(tmp_ver_str, "ae", OTX_CPT_UCODE_VER_STR_SZ) &&
	    nn == OTX_CPT_AE_UC_TYPE)
		val |= 1 << OTX_CPT_AE_TYPES;

	*ucode_type = val;

	if (!val)
		return -EINVAL;
	if (is_eng_type(val, OTX_CPT_AE_TYPES) &&
	    is_eng_type(val, OTX_CPT_SE_TYPES))
		return -EINVAL;
	return 0;
}

static int is_mem_zero(const char *ptr, int size)
{
	int i;

	for (i = 0; i < size; i++) {
		if (ptr[i])
			return 0;
	}
	return 1;
}

static int cpt_set_ucode_base(struct otx_cpt_eng_grp_info *eng_grp, void *obj)
{
	struct otx_cpt_device *cpt = (struct otx_cpt_device *) obj;
	dma_addr_t dma_addr;
	struct otx_cpt_bitmap bmap;
	int i;

	bmap = get_cores_bmap(&cpt->pdev->dev, eng_grp);
	if (!bmap.size)
		return -EINVAL;

	if (eng_grp->mirror.is_ena)
		dma_addr =
		       eng_grp->g->grp[eng_grp->mirror.idx].ucode[0].align_dma;
	else
		dma_addr = eng_grp->ucode[0].align_dma;

	/*
	 * Set UCODE_BASE only for the cores which are not used,
	 * other cores should have already valid UCODE_BASE set
	 */
	for_each_set_bit(i, bmap.bits, bmap.size)
		if (!eng_grp->g->eng_ref_cnt[i])
			writeq((u64) dma_addr, cpt->reg_base +
				OTX_CPT_PF_ENGX_UCODE_BASE(i));
	return 0;
}

static int cpt_detach_and_disable_cores(struct otx_cpt_eng_grp_info *eng_grp,
					void *obj)
{
	struct otx_cpt_device *cpt = (struct otx_cpt_device *) obj;
	struct otx_cpt_bitmap bmap = { {0} };
	int timeout = 10;
	int i, busy;
	u64 reg;

	bmap = get_cores_bmap(&cpt->pdev->dev, eng_grp);
	if (!bmap.size)
		return -EINVAL;

	/* Detach the cores from group */
	reg = readq(cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));
	for_each_set_bit(i, bmap.bits, bmap.size) {
		if (reg & (1ull << i)) {
			eng_grp->g->eng_ref_cnt[i]--;
			reg &= ~(1ull << i);
		}
	}
	writeq(reg, cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));

	/* Wait for cores to become idle */
	do {
		busy = 0;
		usleep_range(10000, 20000);
		if (timeout-- < 0)
			return -EBUSY;

		reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
		for_each_set_bit(i, bmap.bits, bmap.size)
			if (reg & (1ull << i)) {
				busy = 1;
				break;
			}
	} while (busy);

	/* Disable the cores only if they are not used anymore */
	reg = readq(cpt->reg_base + OTX_CPT_PF_EXE_CTL);
	for_each_set_bit(i, bmap.bits, bmap.size)
		if (!eng_grp->g->eng_ref_cnt[i])
			reg &= ~(1ull << i);
	writeq(reg, cpt->reg_base + OTX_CPT_PF_EXE_CTL);

	return 0;
}

static int cpt_attach_and_enable_cores(struct otx_cpt_eng_grp_info *eng_grp,
				       void *obj)
{
	struct otx_cpt_device *cpt = (struct otx_cpt_device *) obj;
	struct otx_cpt_bitmap bmap;
	u64 reg;
	int i;

	bmap = get_cores_bmap(&cpt->pdev->dev, eng_grp);
	if (!bmap.size)
		return -EINVAL;

	/* Attach the cores to the group */
	reg = readq(cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));
	for_each_set_bit(i, bmap.bits, bmap.size) {
		if (!(reg & (1ull << i))) {
			eng_grp->g->eng_ref_cnt[i]++;
			reg |= 1ull << i;
		}
	}
	writeq(reg, cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));

	/* Enable the cores */
	reg = readq(cpt->reg_base + OTX_CPT_PF_EXE_CTL);
	for_each_set_bit(i, bmap.bits, bmap.size)
		reg |= 1ull << i;
	writeq(reg, cpt->reg_base + OTX_CPT_PF_EXE_CTL);

	return 0;
}

static int process_tar_file(struct device *dev,
			    struct tar_arch_info_t *tar_arch, char *filename,
			    const u8 *data, u32 size)
{
	struct tar_ucode_info_t *tar_info;
	struct otx_cpt_ucode_hdr *ucode_hdr;
	int ucode_type, ucode_size;
	unsigned int code_length;

	/*
	 * If size is less than microcode header size then don't report
	 * an error because it might not be microcode file, just process
	 * next file from archive
	 */
	if (size < sizeof(struct otx_cpt_ucode_hdr))
		return 0;

	ucode_hdr = (struct otx_cpt_ucode_hdr *) data;
	/*
	 * If microcode version can't be found don't report an error
	 * because it might not be microcode file, just process next file
	 */
	if (get_ucode_type(ucode_hdr, &ucode_type))
		return 0;

	code_length = ntohl(ucode_hdr->code_length);
	if (code_length >= INT_MAX / 2) {
		dev_err(dev, "Invalid code_length %u\n", code_length);
		return -EINVAL;
	}

	ucode_size = code_length * 2;
	if (!ucode_size || (size < round_up(ucode_size, 16) +
	    sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
		dev_err(dev, "Ucode %s invalid size\n", filename);
		return -EINVAL;
	}

	tar_info = kzalloc(sizeof(struct tar_ucode_info_t), GFP_KERNEL);
	if (!tar_info)
		return -ENOMEM;

	tar_info->ucode_ptr = data;
	set_ucode_filename(&tar_info->ucode, filename);
	memcpy(tar_info->ucode.ver_str, ucode_hdr->ver_str,
	       OTX_CPT_UCODE_VER_STR_SZ);
	tar_info->ucode.ver_num = ucode_hdr->ver_num;
	tar_info->ucode.type = ucode_type;
	tar_info->ucode.size = ucode_size;
	list_add_tail(&tar_info->list, &tar_arch->ucodes);

	return 0;
}

static void release_tar_archive(struct tar_arch_info_t *tar_arch)
{
	struct tar_ucode_info_t *curr, *temp;

	if (!tar_arch)
		return;

	list_for_each_entry_safe(curr, temp, &tar_arch->ucodes, list) {
		list_del(&curr->list);
		kfree(curr);
	}

	if (tar_arch->fw)
		release_firmware(tar_arch->fw);
	kfree(tar_arch);
}

static struct tar_ucode_info_t *get_uc_from_tar_archive(
					struct tar_arch_info_t *tar_arch,
					int ucode_type)
{
	struct tar_ucode_info_t *curr, *uc_found = NULL;

	list_for_each_entry(curr, &tar_arch->ucodes, list) {
		if (!is_eng_type(curr->ucode.type, ucode_type))
			continue;

		if (!uc_found) {
			uc_found = curr;
			continue;
		}

		switch (ucode_type) {
		case OTX_CPT_AE_TYPES:
			break;

		case OTX_CPT_SE_TYPES:
			if (uc_found->ucode.ver_num.nn == OTX_CPT_SE_UC_TYPE2 ||
			    (uc_found->ucode.ver_num.nn == OTX_CPT_SE_UC_TYPE3
			     && curr->ucode.ver_num.nn == OTX_CPT_SE_UC_TYPE1))
				uc_found = curr;
			break;
		}
	}

	return uc_found;
}

static void print_tar_dbg_info(struct tar_arch_info_t *tar_arch,
			       char *tar_filename)
{
	struct tar_ucode_info_t *curr;

	pr_debug("Tar archive filename %s\n", tar_filename);
	pr_debug("Tar archive pointer %p, size %ld\n", tar_arch->fw->data,
		 tar_arch->fw->size);
	list_for_each_entry(curr, &tar_arch->ucodes, list) {
		pr_debug("Ucode filename %s\n", curr->ucode.filename);
		pr_debug("Ucode version string %s\n", curr->ucode.ver_str);
		pr_debug("Ucode version %d.%d.%d.%d\n",
			 curr->ucode.ver_num.nn, curr->ucode.ver_num.xx,
			 curr->ucode.ver_num.yy, curr->ucode.ver_num.zz);
		pr_debug("Ucode type (%d) %s\n", curr->ucode.type,
			 get_ucode_type_str(curr->ucode.type));
		pr_debug("Ucode size %d\n", curr->ucode.size);
		pr_debug("Ucode ptr %p\n", curr->ucode_ptr);
	}
}

static struct tar_arch_info_t *load_tar_archive(struct device *dev,
						char *tar_filename)
{
	struct tar_arch_info_t *tar_arch = NULL;
	struct tar_blk_t *tar_blk;
	unsigned int cur_size;
	size_t tar_offs = 0;
	size_t tar_size;
	int ret;

	tar_arch = kzalloc(sizeof(struct tar_arch_info_t), GFP_KERNEL);
	if (!tar_arch)
		return NULL;

	INIT_LIST_HEAD(&tar_arch->ucodes);

	/* Load tar archive */
	ret = request_firmware(&tar_arch->fw, tar_filename, dev);
	if (ret)
		goto release_tar_arch;

	if (tar_arch->fw->size < TAR_BLOCK_LEN) {
		dev_err(dev, "Invalid tar archive %s\n", tar_filename);
		goto release_tar_arch;
	}

	tar_size = tar_arch->fw->size;
	tar_blk = (struct tar_blk_t *) tar_arch->fw->data;
	if (strncmp(tar_blk->hdr.magic, TAR_MAGIC, TAR_MAGIC_LEN - 1)) {
		dev_err(dev, "Unsupported format of tar archive %s\n",
			tar_filename);
		goto release_tar_arch;
	}

	while (1) {
		/* Read current file size */
		ret = kstrtouint(tar_blk->hdr.size, 8, &cur_size);
		if (ret)
			goto release_tar_arch;

		if (tar_offs + cur_size > tar_size ||
		    tar_offs + 2*TAR_BLOCK_LEN > tar_size) {
			dev_err(dev, "Invalid tar archive %s\n", tar_filename);
			goto release_tar_arch;
		}

		tar_offs += TAR_BLOCK_LEN;
		if (tar_blk->hdr.typeflag == REGTYPE ||
		    tar_blk->hdr.typeflag == AREGTYPE) {
			ret = process_tar_file(dev, tar_arch,
					       tar_blk->hdr.name,
					       &tar_arch->fw->data[tar_offs],
					       cur_size);
			if (ret)
				goto release_tar_arch;
		}

		tar_offs += (cur_size/TAR_BLOCK_LEN) * TAR_BLOCK_LEN;
		if (cur_size % TAR_BLOCK_LEN)
			tar_offs += TAR_BLOCK_LEN;

		/* Check for the end of the archive */
		if (tar_offs + 2*TAR_BLOCK_LEN > tar_size) {
			dev_err(dev, "Invalid tar archive %s\n", tar_filename);
			goto release_tar_arch;
		}

		if (is_mem_zero(&tar_arch->fw->data[tar_offs],
		    2*TAR_BLOCK_LEN))
			break;

		/* Read next block from tar archive */
		tar_blk = (struct tar_blk_t *) &tar_arch->fw->data[tar_offs];
	}

	print_tar_dbg_info(tar_arch, tar_filename);
	return tar_arch;
release_tar_arch:
	release_tar_archive(tar_arch);
	return NULL;
}

static struct otx_cpt_engs_rsvd *find_engines_by_type(
					struct otx_cpt_eng_grp_info *eng_grp,
					int eng_type)
{
	int i;

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		if (!eng_grp->engs[i].type)
			continue;

		if (eng_grp->engs[i].type == eng_type)
			return &eng_grp->engs[i];
	}
	return NULL;
}

int otx_cpt_uc_supports_eng_type(struct otx_cpt_ucode *ucode, int eng_type)
{
	return is_eng_type(ucode->type, eng_type);
}
EXPORT_SYMBOL_GPL(otx_cpt_uc_supports_eng_type);

int otx_cpt_eng_grp_has_eng_type(struct otx_cpt_eng_grp_info *eng_grp,
				 int eng_type)
{
	struct otx_cpt_engs_rsvd *engs;

	engs = find_engines_by_type(eng_grp, eng_type);

	return (engs != NULL ? 1 : 0);
}
EXPORT_SYMBOL_GPL(otx_cpt_eng_grp_has_eng_type);

static void print_ucode_info(struct otx_cpt_eng_grp_info *eng_grp,
			     char *buf, int size)
{
	if (eng_grp->mirror.is_ena) {
		scnprintf(buf, size, "%s (shared with engine_group%d)",
			  eng_grp->g->grp[eng_grp->mirror.idx].ucode[0].ver_str,
			  eng_grp->mirror.idx);
	} else {
		scnprintf(buf, size, "%s", eng_grp->ucode[0].ver_str);
	}
}

static void print_engs_info(struct otx_cpt_eng_grp_info *eng_grp,
			    char *buf, int size, int idx)
{
	struct otx_cpt_engs_rsvd *mirrored_engs = NULL;
	struct otx_cpt_engs_rsvd *engs;
	int len, i;

	buf[0] = '\0';
	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		engs = &eng_grp->engs[i];
		if (!engs->type)
			continue;
		if (idx != -1 && idx != i)
			continue;

		if (eng_grp->mirror.is_ena)
			mirrored_engs = find_engines_by_type(
					&eng_grp->g->grp[eng_grp->mirror.idx],
					engs->type);
		if (i > 0 && idx == -1) {
			len = strlen(buf);
			scnprintf(buf+len, size-len, ", ");
		}

		len = strlen(buf);
		scnprintf(buf+len, size-len, "%d %s ", mirrored_engs ?
			  engs->count + mirrored_engs->count : engs->count,
			  get_eng_type_str(engs->type));
		if (mirrored_engs) {
			len = strlen(buf);
			scnprintf(buf+len, size-len,
				  "(%d shared with engine_group%d) ",
				  engs->count <= 0 ? engs->count +
				  mirrored_engs->count : mirrored_engs->count,
				  eng_grp->mirror.idx);
		}
	}
}

static void print_ucode_dbg_info(struct otx_cpt_ucode *ucode)
{
	pr_debug("Ucode info\n");
	pr_debug("Ucode version string %s\n", ucode->ver_str);
	pr_debug("Ucode version %d.%d.%d.%d\n", ucode->ver_num.nn,
		 ucode->ver_num.xx, ucode->ver_num.yy, ucode->ver_num.zz);
	pr_debug("Ucode type %s\n", get_ucode_type_str(ucode->type));
	pr_debug("Ucode size %d\n", ucode->size);
	pr_debug("Ucode virt address %16.16llx\n", (u64)ucode->align_va);
	pr_debug("Ucode phys address %16.16llx\n", ucode->align_dma);
}

static void cpt_print_engines_mask(struct otx_cpt_eng_grp_info *eng_grp,
				   struct device *dev, char *buf, int size)
{
	struct otx_cpt_bitmap bmap;
	u32 mask[2];

	bmap = get_cores_bmap(dev, eng_grp);
	if (!bmap.size) {
		scnprintf(buf, size, "unknown");
		return;
	}
	bitmap_to_arr32(mask, bmap.bits, bmap.size);
	scnprintf(buf, size, "%8.8x %8.8x", mask[1], mask[0]);
}


static void print_dbg_info(struct device *dev,
			   struct otx_cpt_eng_grps *eng_grps)
{
	char engs_info[2*OTX_CPT_UCODE_NAME_LENGTH];
	struct otx_cpt_eng_grp_info *mirrored_grp;
	char engs_mask[OTX_CPT_UCODE_NAME_LENGTH];
	struct otx_cpt_eng_grp_info *grp;
	struct otx_cpt_engs_rsvd *engs;
	u32 mask[4];
	int i, j;

	pr_debug("Engine groups global info\n");
	pr_debug("max SE %d, max AE %d\n",
		 eng_grps->avail.max_se_cnt, eng_grps->avail.max_ae_cnt);
	pr_debug("free SE %d\n", eng_grps->avail.se_cnt);
	pr_debug("free AE %d\n", eng_grps->avail.ae_cnt);

	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
		grp = &eng_grps->grp[i];
		pr_debug("engine_group%d, state %s\n", i, grp->is_enabled ?
			 "enabled" : "disabled");
		if (grp->is_enabled) {
			mirrored_grp = &eng_grps->grp[grp->mirror.idx];
			pr_debug("Ucode0 filename %s, version %s\n",
				 grp->mirror.is_ena ?
				 mirrored_grp->ucode[0].filename :
				 grp->ucode[0].filename,
				 grp->mirror.is_ena ?
				 mirrored_grp->ucode[0].ver_str :
				 grp->ucode[0].ver_str);
		}

		for (j = 0; j < OTX_CPT_MAX_ETYPES_PER_GRP; j++) {
			engs = &grp->engs[j];
			if (engs->type) {
				print_engs_info(grp, engs_info,
						2*OTX_CPT_UCODE_NAME_LENGTH, j);
				pr_debug("Slot%d: %s\n", j, engs_info);
				bitmap_to_arr32(mask, engs->bmap,
						eng_grps->engs_num);
				pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x\n",
					 mask[3], mask[2], mask[1], mask[0]);
			} else
				pr_debug("Slot%d not used\n", j);
		}
		if (grp->is_enabled) {
			cpt_print_engines_mask(grp, dev, engs_mask,
					       OTX_CPT_UCODE_NAME_LENGTH);
			pr_debug("Cmask: %s\n", engs_mask);
		}
	}
}

static int update_engines_avail_count(struct device *dev,
				      struct otx_cpt_engs_available *avail,
				      struct otx_cpt_engs_rsvd *engs, int val)
{
	switch (engs->type) {
	case OTX_CPT_SE_TYPES:
		avail->se_cnt += val;
		break;

	case OTX_CPT_AE_TYPES:
		avail->ae_cnt += val;
		break;

	default:
		dev_err(dev, "Invalid engine type %d\n", engs->type);
		return -EINVAL;
	}

	return 0;
}

static int update_engines_offset(struct device *dev,
				 struct otx_cpt_engs_available *avail,
				 struct otx_cpt_engs_rsvd *engs)
{
	switch (engs->type) {
	case OTX_CPT_SE_TYPES:
		engs->offset = 0;
		break;

	case OTX_CPT_AE_TYPES:
		engs->offset = avail->max_se_cnt;
		break;

	default:
		dev_err(dev, "Invalid engine type %d\n", engs->type);
		return -EINVAL;
	}

	return 0;
}

static int release_engines(struct device *dev, struct otx_cpt_eng_grp_info *grp)
{
	int i, ret = 0;

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		if (!grp->engs[i].type)
			continue;

		if (grp->engs[i].count > 0) {
			ret = update_engines_avail_count(dev, &grp->g->avail,
							 &grp->engs[i],
							 grp->engs[i].count);
			if (ret)
				return ret;
		}

		grp->engs[i].type = 0;
		grp->engs[i].count = 0;
		grp->engs[i].offset = 0;
		grp->engs[i].ucode = NULL;
		bitmap_zero(grp->engs[i].bmap, grp->g->engs_num);
	}

	return 0;
}

static int do_reserve_engines(struct device *dev,
			      struct otx_cpt_eng_grp_info *grp,
			      struct otx_cpt_engines *req_engs)
{
	struct otx_cpt_engs_rsvd *engs = NULL;
	int i, ret;

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		if (!grp->engs[i].type) {
			engs = &grp->engs[i];
			break;
		}
	}

	if (!engs)
		return -ENOMEM;

	engs->type = req_engs->type;
	engs->count = req_engs->count;

	ret = update_engines_offset(dev, &grp->g->avail, engs);
	if (ret)
		return ret;

	if (engs->count > 0) {
		ret = update_engines_avail_count(dev, &grp->g->avail, engs,
						 -engs->count);
		if (ret)
			return ret;
	}

	return 0;
}

static int check_engines_availability(struct device *dev,
				      struct otx_cpt_eng_grp_info *grp,
				      struct otx_cpt_engines *req_eng)
{
	int avail_cnt = 0;

	switch (req_eng->type) {
	case OTX_CPT_SE_TYPES:
		avail_cnt = grp->g->avail.se_cnt;
		break;

	case OTX_CPT_AE_TYPES:
		avail_cnt = grp->g->avail.ae_cnt;
		break;

	default:
		dev_err(dev, "Invalid engine type %d\n", req_eng->type);
		return -EINVAL;
	}

	if (avail_cnt < req_eng->count) {
		dev_err(dev,
			"Error available %s engines %d < than requested %d\n",
			get_eng_type_str(req_eng->type),
			avail_cnt, req_eng->count);
		return -EBUSY;
	}

	return 0;
}

static int reserve_engines(struct device *dev, struct otx_cpt_eng_grp_info *grp,
			   struct otx_cpt_engines *req_engs, int req_cnt)
{
	int i, ret;

	/* Validate if a number of requested engines is available */
	for (i = 0; i < req_cnt; i++) {
		ret = check_engines_availability(dev, grp, &req_engs[i]);
		if (ret)
			return ret;
	}

	/* Reserve requested engines for this engine group */
	for (i = 0; i < req_cnt; i++) {
		ret = do_reserve_engines(dev, grp, &req_engs[i]);
		if (ret)
			return ret;
	}
	return 0;
}

static ssize_t eng_grp_info_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	char ucode_info[2*OTX_CPT_UCODE_NAME_LENGTH];
	char engs_info[2*OTX_CPT_UCODE_NAME_LENGTH];
	char engs_mask[OTX_CPT_UCODE_NAME_LENGTH];
	struct otx_cpt_eng_grp_info *eng_grp;
	int ret;

	eng_grp = container_of(attr, struct otx_cpt_eng_grp_info, info_attr);
	mutex_lock(&eng_grp->g->lock);

	print_engs_info(eng_grp, engs_info, 2*OTX_CPT_UCODE_NAME_LENGTH, -1);
	print_ucode_info(eng_grp, ucode_info, 2*OTX_CPT_UCODE_NAME_LENGTH);
	cpt_print_engines_mask(eng_grp, dev, engs_mask,
			       OTX_CPT_UCODE_NAME_LENGTH);
	ret = scnprintf(buf, PAGE_SIZE,
			"Microcode : %s\nEngines: %s\nEngines mask: %s\n",
			ucode_info, engs_info, engs_mask);

	mutex_unlock(&eng_grp->g->lock);
	return ret;
}

static int create_sysfs_eng_grps_info(struct device *dev,
				      struct otx_cpt_eng_grp_info *eng_grp)
{
	eng_grp->info_attr.show = eng_grp_info_show;
	eng_grp->info_attr.store = NULL;
	eng_grp->info_attr.attr.name = eng_grp->sysfs_info_name;
	eng_grp->info_attr.attr.mode = 0440;
	sysfs_attr_init(&eng_grp->info_attr.attr);
	return device_create_file(dev, &eng_grp->info_attr);
}

static void ucode_unload(struct device *dev, struct otx_cpt_ucode *ucode)
{
	if (ucode->va) {
		dma_free_coherent(dev, ucode->size + OTX_CPT_UCODE_ALIGNMENT,
				  ucode->va, ucode->dma);
		ucode->va = NULL;
		ucode->align_va = NULL;
		ucode->dma = 0;
		ucode->align_dma = 0;
		ucode->size = 0;
	}

	memset(&ucode->ver_str, 0, OTX_CPT_UCODE_VER_STR_SZ);
	memset(&ucode->ver_num, 0, sizeof(struct otx_cpt_ucode_ver_num));
	set_ucode_filename(ucode, "");
	ucode->type = 0;
}

static int copy_ucode_to_dma_mem(struct device *dev,
				 struct otx_cpt_ucode *ucode,
				 const u8 *ucode_data)
{
	u32 i;

	/*  Allocate DMAable space */
	ucode->va = dma_alloc_coherent(dev, ucode->size +
				       OTX_CPT_UCODE_ALIGNMENT,
				       &ucode->dma, GFP_KERNEL);
	if (!ucode->va) {
		dev_err(dev, "Unable to allocate space for microcode\n");
		return -ENOMEM;
	}
	ucode->align_va = PTR_ALIGN(ucode->va, OTX_CPT_UCODE_ALIGNMENT);
	ucode->align_dma = PTR_ALIGN(ucode->dma, OTX_CPT_UCODE_ALIGNMENT);

	memcpy((void *) ucode->align_va, (void *) ucode_data +
	       sizeof(struct otx_cpt_ucode_hdr), ucode->size);

	/* Byte swap 64-bit */
	for (i = 0; i < (ucode->size / 8); i++)
		((__be64 *)ucode->align_va)[i] =
				cpu_to_be64(((u64 *)ucode->align_va)[i]);
	/*  Ucode needs 16-bit swap */
	for (i = 0; i < (ucode->size / 2); i++)
		((__be16 *)ucode->align_va)[i] =
				cpu_to_be16(((u16 *)ucode->align_va)[i]);
	return 0;
}

static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
		      const char *ucode_filename)
{
	struct otx_cpt_ucode_hdr *ucode_hdr;
	const struct firmware *fw;
	unsigned int code_length;
	int ret;

	set_ucode_filename(ucode, ucode_filename);
	ret = request_firmware(&fw, ucode->filename, dev);
	if (ret)
		return ret;

	ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;
	memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
	ucode->ver_num = ucode_hdr->ver_num;
	code_length = ntohl(ucode_hdr->code_length);
	if (code_length >= INT_MAX / 2) {
		dev_err(dev, "Ucode invalid code_length %u\n", code_length);
		ret = -EINVAL;
		goto release_fw;
	}
	ucode->size = code_length * 2;
	if (!ucode->size || (fw->size < round_up(ucode->size, 16)
	    + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
		dev_err(dev, "Ucode %s invalid size\n", ucode_filename);
		ret = -EINVAL;
		goto release_fw;
	}

	ret = get_ucode_type(ucode_hdr, &ucode->type);
	if (ret) {
		dev_err(dev, "Microcode %s unknown type 0x%x\n",
			ucode->filename, ucode->type);
		goto release_fw;
	}

	ret = copy_ucode_to_dma_mem(dev, ucode, fw->data);
	if (ret)
		goto release_fw;

	print_ucode_dbg_info(ucode);
release_fw:
	release_firmware(fw);
	return ret;
}

static int enable_eng_grp(struct otx_cpt_eng_grp_info *eng_grp,
			  void *obj)
{
	int ret;

	ret = cpt_set_ucode_base(eng_grp, obj);
	if (ret)
		return ret;

	ret = cpt_attach_and_enable_cores(eng_grp, obj);
	return ret;
}

static int disable_eng_grp(struct device *dev,
			   struct otx_cpt_eng_grp_info *eng_grp,
			   void *obj)
{
	int i, ret;

	ret = cpt_detach_and_disable_cores(eng_grp, obj);
	if (ret)
		return ret;

	/* Unload ucode used by this engine group */
	ucode_unload(dev, &eng_grp->ucode[0]);

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		if (!eng_grp->engs[i].type)
			continue;

		eng_grp->engs[i].ucode = &eng_grp->ucode[0];
	}

	ret = cpt_set_ucode_base(eng_grp, obj);

	return ret;
}

static void setup_eng_grp_mirroring(struct otx_cpt_eng_grp_info *dst_grp,
				    struct otx_cpt_eng_grp_info *src_grp)
{
	/* Setup fields for engine group which is mirrored */
	src_grp->mirror.is_ena = false;
	src_grp->mirror.idx = 0;
	src_grp->mirror.ref_count++;

	/* Setup fields for mirroring engine group */
	dst_grp->mirror.is_ena = true;
	dst_grp->mirror.idx = src_grp->idx;
	dst_grp->mirror.ref_count = 0;
}

static void remove_eng_grp_mirroring(struct otx_cpt_eng_grp_info *dst_grp)
{
	struct otx_cpt_eng_grp_info *src_grp;

	if (!dst_grp->mirror.is_ena)
		return;

	src_grp = &dst_grp->g->grp[dst_grp->mirror.idx];

	src_grp->mirror.ref_count--;
	dst_grp->mirror.is_ena = false;
	dst_grp->mirror.idx = 0;
	dst_grp->mirror.ref_count = 0;
}

static void update_requested_engs(struct otx_cpt_eng_grp_info *mirrored_eng_grp,
				  struct otx_cpt_engines *engs, int engs_cnt)
{
	struct otx_cpt_engs_rsvd *mirrored_engs;
	int i;

	for (i = 0; i < engs_cnt; i++) {
		mirrored_engs = find_engines_by_type(mirrored_eng_grp,
						     engs[i].type);
		if (!mirrored_engs)
			continue;

		/*
		 * If mirrored group has this type of engines attached then
		 * there are 3 scenarios possible:
		 * 1) mirrored_engs.count == engs[i].count then all engines
		 * from mirrored engine group will be shared with this engine
		 * group
		 * 2) mirrored_engs.count > engs[i].count then only a subset of
		 * engines from mirrored engine group will be shared with this
		 * engine group
		 * 3) mirrored_engs.count < engs[i].count then all engines
		 * from mirrored engine group will be shared with this group
		 * and additional engines will be reserved for exclusively use
		 * by this engine group
		 */
		engs[i].count -= mirrored_engs->count;
	}
}

static struct otx_cpt_eng_grp_info *find_mirrored_eng_grp(
					struct otx_cpt_eng_grp_info *grp)
{
	struct otx_cpt_eng_grps *eng_grps = grp->g;
	int i;

	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
		if (!eng_grps->grp[i].is_enabled)
			continue;
		if (eng_grps->grp[i].ucode[0].type)
			continue;
		if (grp->idx == i)
			continue;
		if (!strncasecmp(eng_grps->grp[i].ucode[0].ver_str,
				 grp->ucode[0].ver_str,
				 OTX_CPT_UCODE_VER_STR_SZ))
			return &eng_grps->grp[i];
	}

	return NULL;
}

static struct otx_cpt_eng_grp_info *find_unused_eng_grp(
					struct otx_cpt_eng_grps *eng_grps)
{
	int i;

	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
		if (!eng_grps->grp[i].is_enabled)
			return &eng_grps->grp[i];
	}
	return NULL;
}

static int eng_grp_update_masks(struct device *dev,
				struct otx_cpt_eng_grp_info *eng_grp)
{
	struct otx_cpt_engs_rsvd *engs, *mirrored_engs;
	struct otx_cpt_bitmap tmp_bmap = { {0} };
	int i, j, cnt, max_cnt;
	int bit;

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		engs = &eng_grp->engs[i];
		if (!engs->type)
			continue;
		if (engs->count <= 0)
			continue;

		switch (engs->type) {
		case OTX_CPT_SE_TYPES:
			max_cnt = eng_grp->g->avail.max_se_cnt;
			break;

		case OTX_CPT_AE_TYPES:
			max_cnt = eng_grp->g->avail.max_ae_cnt;
			break;

		default:
			dev_err(dev, "Invalid engine type %d\n", engs->type);
			return -EINVAL;
		}

		cnt = engs->count;
		WARN_ON(engs->offset + max_cnt > OTX_CPT_MAX_ENGINES);
		bitmap_zero(tmp_bmap.bits, eng_grp->g->engs_num);
		for (j = engs->offset; j < engs->offset + max_cnt; j++) {
			if (!eng_grp->g->eng_ref_cnt[j]) {
				bitmap_set(tmp_bmap.bits, j, 1);
				cnt--;
				if (!cnt)
					break;
			}
		}

		if (cnt)
			return -ENOSPC;

		bitmap_copy(engs->bmap, tmp_bmap.bits, eng_grp->g->engs_num);
	}

	if (!eng_grp->mirror.is_ena)
		return 0;

	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
		engs = &eng_grp->engs[i];
		if (!engs->type)
			continue;

		mirrored_engs = find_engines_by_type(
					&eng_grp->g->grp[eng_grp->mirror.idx],
					engs->type);
		WARN_ON(!mirrored_engs && engs->count <= 0);
		if (!mirrored_engs)
			continue;

		bitmap_copy(tmp_bmap.bits, mirrored_engs->bmap,
			    eng_grp->g->engs_num);
		if (engs->count < 0) {
			bit = find_first_bit(mirrored_engs->bmap,
					     eng_grp->g->engs_num);
			bitmap_clear(tmp_bmap.bits, bit, -engs->count);
		}
		bitmap_or(engs->bmap, engs->bmap, tmp_bmap.bits,
			  eng_grp->g->engs_num);
	}
	return 0;
}

static int delete_engine_group(struct device *dev,
			       struct otx_cpt_eng_grp_info *eng_grp)
{
	int i, ret;

	if (!eng_grp->is_enabled)
		return -EINVAL;

	if (eng_grp->mirror.ref_count) {
		dev_err(dev, "Can't delete engine_group%d as it is used by engine_group(s):",
			eng_grp->idx);
		for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
			if (eng_grp->g->grp[i].mirror.is_ena &&
			    eng_grp->g->grp[i].mirror.idx == eng_grp->idx)
				pr_cont(" %d", i);
		}
		pr_cont("\n");
		return -EINVAL;
	}

	/* Removing engine group mirroring if enabled */
	remove_eng_grp_mirroring(eng_grp);

	/* Disable engine group */
	ret = disable_eng_grp(dev, eng_grp, eng_grp->g->obj);
	if (ret)
		return ret;

	/* Release all engines held by this engine group */
	ret = release_engines(dev, eng_grp);
	if (ret)
		return ret;

	device_remove_file(dev, &eng_grp->info_attr);
	eng_grp->is_enabled = false;

	return 0;
}

static int validate_1_ucode_scenario(struct device *dev,
				     struct otx_cpt_eng_grp_info *eng_grp,
				     struct otx_cpt_engines *engs, int engs_cnt)
{
	int i;

	/* Verify that ucode loaded supports requested engine types */
	for (i = 0; i < engs_cnt; i++) {
		if (!otx_cpt_uc_supports_eng_type(&eng_grp->ucode[0],
						  engs[i].type)) {
			dev_err(dev,
				"Microcode %s does not support %s engines\n",
				eng_grp->ucode[0].filename,
				get_eng_type_str(engs[i].type));
			return -EINVAL;
		}
	}
	return 0;
}

static void update_ucode_ptrs(struct otx_cpt_eng_grp_info *eng_grp)
{
	struct otx_cpt_ucode *ucode;

	if (eng_grp->mirror.is_ena)
		ucode = &eng_grp->g->grp[eng_grp->mirror.idx].ucode[0];
	else
		ucode = &eng_grp->ucode[0];
	WARN_ON(!eng_grp->engs[0].type);
	eng_grp->engs[0].ucode = ucode;
}

static int create_engine_group(struct device *dev,
			       struct otx_cpt_eng_grps *eng_grps,
			       struct otx_cpt_engines *engs, int engs_cnt,
			       void *ucode_data[], int ucodes_cnt,
			       bool use_uc_from_tar_arch)
{
	struct otx_cpt_eng_grp_info *mirrored_eng_grp;
	struct tar_ucode_info_t *tar_info;
	struct otx_cpt_eng_grp_info *eng_grp;
	int i, ret = 0;

	if (ucodes_cnt > OTX_CPT_MAX_ETYPES_PER_GRP)
		return -EINVAL;

	/* Validate if requested engine types are supported by this device */
	for (i = 0; i < engs_cnt; i++)
		if (!dev_supports_eng_type(eng_grps, engs[i].type)) {
			dev_err(dev, "Device does not support %s engines\n",
				get_eng_type_str(engs[i].type));
			return -EPERM;
		}

	/* Find engine group which is not used */
	eng_grp = find_unused_eng_grp(eng_grps);
	if (!eng_grp) {
		dev_err(dev, "Error all engine groups are being used\n");
		return -ENOSPC;
	}

	/* Load ucode */
	for (i = 0; i < ucodes_cnt; i++) {
		if (use_uc_from_tar_arch) {
			tar_info = (struct tar_ucode_info_t *) ucode_data[i];
			eng_grp->ucode[i] = tar_info->ucode;
			ret = copy_ucode_to_dma_mem(dev, &eng_grp->ucode[i],
						    tar_info->ucode_ptr);
		} else
			ret = ucode_load(dev, &eng_grp->ucode[i],
					 (char *) ucode_data[i]);
		if (ret)
			goto err_ucode_unload;
	}

	/* Validate scenario where 1 ucode is used */
	ret = validate_1_ucode_scenario(dev, eng_grp, engs, engs_cnt);
	if (ret)
		goto err_ucode_unload;

	/* Check if this group mirrors another existing engine group */
	mirrored_eng_grp = find_mirrored_eng_grp(eng_grp);
	if (mirrored_eng_grp) {
		/* Setup mirroring */
		setup_eng_grp_mirroring(eng_grp, mirrored_eng_grp);

		/*
		 * Update count of requested engines because some
		 * of them might be shared with mirrored group
		 */
		update_requested_engs(mirrored_eng_grp, engs, engs_cnt);
	}

	/* Reserve engines */
	ret = reserve_engines(dev, eng_grp, engs, engs_cnt);
	if (ret)
		goto err_ucode_unload;

	/* Update ucode pointers used by engines */
	update_ucode_ptrs(eng_grp);

	/* Update engine masks used by this group */
	ret = eng_grp_update_masks(dev, eng_grp);
	if (ret)
		goto err_release_engs;

	/* Create sysfs entry for engine group info */
	ret = create_sysfs_eng_grps_info(dev, eng_grp);
	if (ret)
		goto err_release_engs;

	/* Enable engine group */
	ret = enable_eng_grp(eng_grp, eng_grps->obj);
	if (ret)
		goto err_release_engs;

	/*
	 * If this engine group mirrors another engine group
	 * then we need to unload ucode as we will use ucode
	 * from mirrored engine group
	 */
	if (eng_grp->mirror.is_ena)
		ucode_unload(dev, &eng_grp->ucode[0]);

	eng_grp->is_enabled = true;
	if (eng_grp->mirror.is_ena)
		dev_info(dev,
			 "Engine_group%d: reuse microcode %s from group %d\n",
			 eng_grp->idx, mirrored_eng_grp->ucode[0].ver_str,
			 mirrored_eng_grp->idx);
	else
		dev_info(dev, "Engine_group%d: microcode loaded %s\n",
			 eng_grp->idx, eng_grp->ucode[0].ver_str);

	return 0;

err_release_engs:
	release_engines(dev, eng_grp);
err_ucode_unload:
	ucode_unload(dev, &eng_grp->ucode[0]);
	return ret;
}

static ssize_t ucode_load_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct otx_cpt_engines engs[OTX_CPT_MAX_ETYPES_PER_GRP] = { {0} };
	char *ucode_filename[OTX_CPT_MAX_ETYPES_PER_GRP];
	char tmp_buf[OTX_CPT_UCODE_NAME_LENGTH] = { 0 };
	char *start, *val, *err_msg, *tmp;
	struct otx_cpt_eng_grps *eng_grps;
	int grp_idx = 0, ret = -EINVAL;
	bool has_se, has_ie, has_ae;
	int del_grp_idx = -1;
	int ucode_idx = 0;

	if (strlen(buf) > OTX_CPT_UCODE_NAME_LENGTH)
		return -EINVAL;

	eng_grps = container_of(attr, struct otx_cpt_eng_grps, ucode_load_attr);
	err_msg = "Invalid engine group format";
	strlcpy(tmp_buf, buf, OTX_CPT_UCODE_NAME_LENGTH);
	start = tmp_buf;

	has_se = has_ie = has_ae = false;

	for (;;) {
		val = strsep(&start, ";");
		if (!val)
			break;
		val = strim(val);
		if (!*val)
			continue;

		if (!strncasecmp(val, "engine_group", 12)) {
			if (del_grp_idx != -1)
				goto err_print;
			tmp = strim(strsep(&val, ":"));
			if (!val)
				goto err_print;
			if (strlen(tmp) != 13)
				goto err_print;
			if (kstrtoint((tmp + 12), 10, &del_grp_idx))
				goto err_print;
			val = strim(val);
			if (strncasecmp(val, "null", 4))
				goto err_print;
			if (strlen(val) != 4)
				goto err_print;
		} else if (!strncasecmp(val, "se", 2) && strchr(val, ':')) {
			if (has_se || ucode_idx)
				goto err_print;
			tmp = strim(strsep(&val, ":"));
			if (!val)
				goto err_print;
			if (strlen(tmp) != 2)
				goto err_print;
			if (kstrtoint(strim(val), 10, &engs[grp_idx].count))
				goto err_print;
			engs[grp_idx++].type = OTX_CPT_SE_TYPES;
			has_se = true;
		} else if (!strncasecmp(val, "ae", 2) && strchr(val, ':')) {
			if (has_ae || ucode_idx)
				goto err_print;
			tmp = strim(strsep(&val, ":"));
			if (!val)
				goto err_print;
			if (strlen(tmp) != 2)
				goto err_print;
			if (kstrtoint(strim(val), 10, &engs[grp_idx].count))
				goto err_print;
			engs[grp_idx++].type = OTX_CPT_AE_TYPES;
			has_ae = true;
		} else {
			if (ucode_idx > 1)
				goto err_print;
			if (!strlen(val))
				goto err_print;
			if (strnstr(val, " ", strlen(val)))
				goto err_print;
			ucode_filename[ucode_idx++] = val;
		}
	}

	/* Validate input parameters */
	if (del_grp_idx == -1) {
		if (!(grp_idx && ucode_idx))
			goto err_print;

		if (ucode_idx > 1 && grp_idx < 2)
			goto err_print;

		if (grp_idx > OTX_CPT_MAX_ETYPES_PER_GRP) {
			err_msg = "Error max 2 engine types can be attached";
			goto err_print;
		}

	} else {
		if (del_grp_idx < 0 ||
		    del_grp_idx >= OTX_CPT_MAX_ENGINE_GROUPS) {
			dev_err(dev, "Invalid engine group index %d\n",
				del_grp_idx);
			ret = -EINVAL;
			return ret;
		}

		if (!eng_grps->grp[del_grp_idx].is_enabled) {
			dev_err(dev, "Error engine_group%d is not configured\n",
				del_grp_idx);
			ret = -EINVAL;
			return ret;
		}

		if (grp_idx || ucode_idx)
			goto err_print;
	}

	mutex_lock(&eng_grps->lock);

	if (eng_grps->is_rdonly) {
		dev_err(dev, "Disable VFs before modifying engine groups\n");
		ret = -EACCES;
		goto err_unlock;
	}

	if (del_grp_idx == -1)
		/* create engine group */
		ret = create_engine_group(dev, eng_grps, engs, grp_idx,
					  (void **) ucode_filename,
					  ucode_idx, false);
	else
		/* delete engine group */
		ret = delete_engine_group(dev, &eng_grps->grp[del_grp_idx]);
	if (ret)
		goto err_unlock;

	print_dbg_info(dev, eng_grps);
err_unlock:
	mutex_unlock(&eng_grps->lock);
	return ret ? ret : count;
err_print:
	dev_err(dev, "%s\n", err_msg);

	return ret;
}

int otx_cpt_try_create_default_eng_grps(struct pci_dev *pdev,
					struct otx_cpt_eng_grps *eng_grps,
					int pf_type)
{
	struct tar_ucode_info_t *tar_info[OTX_CPT_MAX_ETYPES_PER_GRP] = {};
	struct otx_cpt_engines engs[OTX_CPT_MAX_ETYPES_PER_GRP] = {};
	struct tar_arch_info_t *tar_arch = NULL;
	char *tar_filename;
	int i, ret = 0;

	mutex_lock(&eng_grps->lock);

	/*
	 * We don't create engine group for kernel crypto if attempt to create
	 * it was already made (when user enabled VFs for the first time)
	 */
	if (eng_grps->is_first_try)
		goto unlock_mutex;
	eng_grps->is_first_try = true;

	/* We create group for kcrypto only if no groups are configured */
	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++)
		if (eng_grps->grp[i].is_enabled)
			goto unlock_mutex;

	switch (pf_type) {
	case OTX_CPT_AE:
	case OTX_CPT_SE:
		tar_filename = OTX_CPT_UCODE_TAR_FILE_NAME;
		break;

	default:
		dev_err(&pdev->dev, "Unknown PF type %d\n", pf_type);
		ret = -EINVAL;
		goto unlock_mutex;
	}

	tar_arch = load_tar_archive(&pdev->dev, tar_filename);
	if (!tar_arch)
		goto unlock_mutex;

	/*
	 * If device supports SE engines and there is SE microcode in tar
	 * archive try to create engine group with SE engines for kernel
	 * crypto functionality (symmetric crypto)
	 */
	tar_info[0] = get_uc_from_tar_archive(tar_arch, OTX_CPT_SE_TYPES);
	if (tar_info[0] &&
	    dev_supports_eng_type(eng_grps, OTX_CPT_SE_TYPES)) {

		engs[0].type = OTX_CPT_SE_TYPES;
		engs[0].count = eng_grps->avail.max_se_cnt;

		ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
					  (void **) tar_info, 1, true);
		if (ret)
			goto release_tar_arch;
	}
	/*
	 * If device supports AE engines and there is AE microcode in tar
	 * archive try to create engine group with AE engines for asymmetric
	 * crypto functionality.
	 */
	tar_info[0] = get_uc_from_tar_archive(tar_arch, OTX_CPT_AE_TYPES);
	if (tar_info[0] &&
	    dev_supports_eng_type(eng_grps, OTX_CPT_AE_TYPES)) {

		engs[0].type = OTX_CPT_AE_TYPES;
		engs[0].count = eng_grps->avail.max_ae_cnt;

		ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
					  (void **) tar_info, 1, true);
		if (ret)
			goto release_tar_arch;
	}

	print_dbg_info(&pdev->dev, eng_grps);
release_tar_arch:
	release_tar_archive(tar_arch);
unlock_mutex:
	mutex_unlock(&eng_grps->lock);
	return ret;
}

void otx_cpt_set_eng_grps_is_rdonly(struct otx_cpt_eng_grps *eng_grps,
				    bool is_rdonly)
{
	mutex_lock(&eng_grps->lock);

	eng_grps->is_rdonly = is_rdonly;

	mutex_unlock(&eng_grps->lock);
}

void otx_cpt_disable_all_cores(struct otx_cpt_device *cpt)
{
	int grp, timeout = 100;
	u64 reg;

	/* Disengage the cores from groups */
	for (grp = 0; grp < OTX_CPT_MAX_ENGINE_GROUPS; grp++) {
		writeq(0, cpt->reg_base + OTX_CPT_PF_GX_EN(grp));
		udelay(CSR_DELAY);
	}

	reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
	while (reg) {
		udelay(CSR_DELAY);
		reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
		if (timeout--) {
			dev_warn(&cpt->pdev->dev, "Cores still busy\n");
			break;
		}
	}

	/* Disable the cores */
	writeq(0, cpt->reg_base + OTX_CPT_PF_EXE_CTL);
}

void otx_cpt_cleanup_eng_grps(struct pci_dev *pdev,
			      struct otx_cpt_eng_grps *eng_grps)
{
	struct otx_cpt_eng_grp_info *grp;
	int i, j;

	mutex_lock(&eng_grps->lock);
	if (eng_grps->is_ucode_load_created) {
		device_remove_file(&pdev->dev,
				   &eng_grps->ucode_load_attr);
		eng_grps->is_ucode_load_created = false;
	}

	/* First delete all mirroring engine groups */
	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++)
		if (eng_grps->grp[i].mirror.is_ena)
			delete_engine_group(&pdev->dev, &eng_grps->grp[i]);

	/* Delete remaining engine groups */
	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++)
		delete_engine_group(&pdev->dev, &eng_grps->grp[i]);

	/* Release memory */
	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
		grp = &eng_grps->grp[i];
		for (j = 0; j < OTX_CPT_MAX_ETYPES_PER_GRP; j++) {
			kfree(grp->engs[j].bmap);
			grp->engs[j].bmap = NULL;
		}
	}

	mutex_unlock(&eng_grps->lock);
}

int otx_cpt_init_eng_grps(struct pci_dev *pdev,
			  struct otx_cpt_eng_grps *eng_grps, int pf_type)
{
	struct otx_cpt_eng_grp_info *grp;
	int i, j, ret = 0;

	mutex_init(&eng_grps->lock);
	eng_grps->obj = pci_get_drvdata(pdev);
	eng_grps->avail.se_cnt = eng_grps->avail.max_se_cnt;
	eng_grps->avail.ae_cnt = eng_grps->avail.max_ae_cnt;

	eng_grps->engs_num = eng_grps->avail.max_se_cnt +
			     eng_grps->avail.max_ae_cnt;
	if (eng_grps->engs_num > OTX_CPT_MAX_ENGINES) {
		dev_err(&pdev->dev,
			"Number of engines %d > than max supported %d\n",
			eng_grps->engs_num, OTX_CPT_MAX_ENGINES);
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
		grp = &eng_grps->grp[i];
		grp->g = eng_grps;
		grp->idx = i;

		snprintf(grp->sysfs_info_name, OTX_CPT_UCODE_NAME_LENGTH,
			 "engine_group%d", i);
		for (j = 0; j < OTX_CPT_MAX_ETYPES_PER_GRP; j++) {
			grp->engs[j].bmap =
				kcalloc(BITS_TO_LONGS(eng_grps->engs_num),
					sizeof(long), GFP_KERNEL);
			if (!grp->engs[j].bmap) {
				ret = -ENOMEM;
				goto err;
			}
		}
	}

	switch (pf_type) {
	case OTX_CPT_SE:
		/* OcteonTX 83XX SE CPT PF has only SE engines attached */
		eng_grps->eng_types_supported = 1 << OTX_CPT_SE_TYPES;
		break;

	case OTX_CPT_AE:
		/* OcteonTX 83XX AE CPT PF has only AE engines attached */
		eng_grps->eng_types_supported = 1 << OTX_CPT_AE_TYPES;
		break;

	default:
		dev_err(&pdev->dev, "Unknown PF type %d\n", pf_type);
		ret = -EINVAL;
		goto err;
	}

	eng_grps->ucode_load_attr.show = NULL;
	eng_grps->ucode_load_attr.store = ucode_load_store;
	eng_grps->ucode_load_attr.attr.name = "ucode_load";
	eng_grps->ucode_load_attr.attr.mode = 0220;
	sysfs_attr_init(&eng_grps->ucode_load_attr.attr);
	ret = device_create_file(&pdev->dev,
				 &eng_grps->ucode_load_attr);
	if (ret)
		goto err;
	eng_grps->is_ucode_load_created = true;

	print_dbg_info(&pdev->dev, eng_grps);
	return ret;
err:
	otx_cpt_cleanup_eng_grps(pdev, eng_grps);
	return ret;
}
