// 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;

	/*
	 * 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;

	ucode_size = ntohl(ucode_hdr->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)
{
	int ret;

	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);
	ret = device_create_file(dev, &eng_grp->info_attr);
	if (ret)
		return ret;

	return 0;
}

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++)
		((u64 *)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++)
		((u16 *)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;
	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;
	ucode->size = ntohl(ucode_hdr->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] = { 0 };
	struct otx_cpt_engines engs[OTX_CPT_MAX_ETYPES_PER_GRP] = { {0} };
	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;
}
