cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

otx_cptpf_ucode.c (42304B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Marvell OcteonTX CPT driver
      3 *
      4 * Copyright (C) 2019 Marvell International Ltd.
      5 *
      6 * This program is free software; you can redistribute it and/or modify
      7 * it under the terms of the GNU General Public License version 2 as
      8 * published by the Free Software Foundation.
      9 */
     10
     11#include <linux/ctype.h>
     12#include <linux/firmware.h>
     13#include "otx_cpt_common.h"
     14#include "otx_cptpf_ucode.h"
     15#include "otx_cptpf.h"
     16
     17#define CSR_DELAY 30
     18/* Tar archive defines */
     19#define TAR_MAGIC		"ustar"
     20#define TAR_MAGIC_LEN		6
     21#define TAR_BLOCK_LEN		512
     22#define REGTYPE			'0'
     23#define AREGTYPE		'\0'
     24
     25/* tar header as defined in POSIX 1003.1-1990. */
     26struct tar_hdr_t {
     27	char name[100];
     28	char mode[8];
     29	char uid[8];
     30	char gid[8];
     31	char size[12];
     32	char mtime[12];
     33	char chksum[8];
     34	char typeflag;
     35	char linkname[100];
     36	char magic[6];
     37	char version[2];
     38	char uname[32];
     39	char gname[32];
     40	char devmajor[8];
     41	char devminor[8];
     42	char prefix[155];
     43};
     44
     45struct tar_blk_t {
     46	union {
     47		struct tar_hdr_t hdr;
     48		char block[TAR_BLOCK_LEN];
     49	};
     50};
     51
     52struct tar_arch_info_t {
     53	struct list_head ucodes;
     54	const struct firmware *fw;
     55};
     56
     57static struct otx_cpt_bitmap get_cores_bmap(struct device *dev,
     58					   struct otx_cpt_eng_grp_info *eng_grp)
     59{
     60	struct otx_cpt_bitmap bmap = { {0} };
     61	bool found = false;
     62	int i;
     63
     64	if (eng_grp->g->engs_num > OTX_CPT_MAX_ENGINES) {
     65		dev_err(dev, "unsupported number of engines %d on octeontx\n",
     66			eng_grp->g->engs_num);
     67		return bmap;
     68	}
     69
     70	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
     71		if (eng_grp->engs[i].type) {
     72			bitmap_or(bmap.bits, bmap.bits,
     73				  eng_grp->engs[i].bmap,
     74				  eng_grp->g->engs_num);
     75			bmap.size = eng_grp->g->engs_num;
     76			found = true;
     77		}
     78	}
     79
     80	if (!found)
     81		dev_err(dev, "No engines reserved for engine group %d\n",
     82			eng_grp->idx);
     83	return bmap;
     84}
     85
     86static int is_eng_type(int val, int eng_type)
     87{
     88	return val & (1 << eng_type);
     89}
     90
     91static int dev_supports_eng_type(struct otx_cpt_eng_grps *eng_grps,
     92				 int eng_type)
     93{
     94	return is_eng_type(eng_grps->eng_types_supported, eng_type);
     95}
     96
     97static void set_ucode_filename(struct otx_cpt_ucode *ucode,
     98			       const char *filename)
     99{
    100	strlcpy(ucode->filename, filename, OTX_CPT_UCODE_NAME_LENGTH);
    101}
    102
    103static char *get_eng_type_str(int eng_type)
    104{
    105	char *str = "unknown";
    106
    107	switch (eng_type) {
    108	case OTX_CPT_SE_TYPES:
    109		str = "SE";
    110		break;
    111
    112	case OTX_CPT_AE_TYPES:
    113		str = "AE";
    114		break;
    115	}
    116	return str;
    117}
    118
    119static char *get_ucode_type_str(int ucode_type)
    120{
    121	char *str = "unknown";
    122
    123	switch (ucode_type) {
    124	case (1 << OTX_CPT_SE_TYPES):
    125		str = "SE";
    126		break;
    127
    128	case (1 << OTX_CPT_AE_TYPES):
    129		str = "AE";
    130		break;
    131	}
    132	return str;
    133}
    134
    135static int get_ucode_type(struct otx_cpt_ucode_hdr *ucode_hdr, int *ucode_type)
    136{
    137	char tmp_ver_str[OTX_CPT_UCODE_VER_STR_SZ];
    138	u32 i, val = 0;
    139	u8 nn;
    140
    141	strlcpy(tmp_ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
    142	for (i = 0; i < strlen(tmp_ver_str); i++)
    143		tmp_ver_str[i] = tolower(tmp_ver_str[i]);
    144
    145	nn = ucode_hdr->ver_num.nn;
    146	if (strnstr(tmp_ver_str, "se-", OTX_CPT_UCODE_VER_STR_SZ) &&
    147	    (nn == OTX_CPT_SE_UC_TYPE1 || nn == OTX_CPT_SE_UC_TYPE2 ||
    148	     nn == OTX_CPT_SE_UC_TYPE3))
    149		val |= 1 << OTX_CPT_SE_TYPES;
    150	if (strnstr(tmp_ver_str, "ae", OTX_CPT_UCODE_VER_STR_SZ) &&
    151	    nn == OTX_CPT_AE_UC_TYPE)
    152		val |= 1 << OTX_CPT_AE_TYPES;
    153
    154	*ucode_type = val;
    155
    156	if (!val)
    157		return -EINVAL;
    158	if (is_eng_type(val, OTX_CPT_AE_TYPES) &&
    159	    is_eng_type(val, OTX_CPT_SE_TYPES))
    160		return -EINVAL;
    161	return 0;
    162}
    163
    164static int is_mem_zero(const char *ptr, int size)
    165{
    166	int i;
    167
    168	for (i = 0; i < size; i++) {
    169		if (ptr[i])
    170			return 0;
    171	}
    172	return 1;
    173}
    174
    175static int cpt_set_ucode_base(struct otx_cpt_eng_grp_info *eng_grp, void *obj)
    176{
    177	struct otx_cpt_device *cpt = (struct otx_cpt_device *) obj;
    178	dma_addr_t dma_addr;
    179	struct otx_cpt_bitmap bmap;
    180	int i;
    181
    182	bmap = get_cores_bmap(&cpt->pdev->dev, eng_grp);
    183	if (!bmap.size)
    184		return -EINVAL;
    185
    186	if (eng_grp->mirror.is_ena)
    187		dma_addr =
    188		       eng_grp->g->grp[eng_grp->mirror.idx].ucode[0].align_dma;
    189	else
    190		dma_addr = eng_grp->ucode[0].align_dma;
    191
    192	/*
    193	 * Set UCODE_BASE only for the cores which are not used,
    194	 * other cores should have already valid UCODE_BASE set
    195	 */
    196	for_each_set_bit(i, bmap.bits, bmap.size)
    197		if (!eng_grp->g->eng_ref_cnt[i])
    198			writeq((u64) dma_addr, cpt->reg_base +
    199				OTX_CPT_PF_ENGX_UCODE_BASE(i));
    200	return 0;
    201}
    202
    203static int cpt_detach_and_disable_cores(struct otx_cpt_eng_grp_info *eng_grp,
    204					void *obj)
    205{
    206	struct otx_cpt_device *cpt = (struct otx_cpt_device *) obj;
    207	struct otx_cpt_bitmap bmap = { {0} };
    208	int timeout = 10;
    209	int i, busy;
    210	u64 reg;
    211
    212	bmap = get_cores_bmap(&cpt->pdev->dev, eng_grp);
    213	if (!bmap.size)
    214		return -EINVAL;
    215
    216	/* Detach the cores from group */
    217	reg = readq(cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));
    218	for_each_set_bit(i, bmap.bits, bmap.size) {
    219		if (reg & (1ull << i)) {
    220			eng_grp->g->eng_ref_cnt[i]--;
    221			reg &= ~(1ull << i);
    222		}
    223	}
    224	writeq(reg, cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));
    225
    226	/* Wait for cores to become idle */
    227	do {
    228		busy = 0;
    229		usleep_range(10000, 20000);
    230		if (timeout-- < 0)
    231			return -EBUSY;
    232
    233		reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
    234		for_each_set_bit(i, bmap.bits, bmap.size)
    235			if (reg & (1ull << i)) {
    236				busy = 1;
    237				break;
    238			}
    239	} while (busy);
    240
    241	/* Disable the cores only if they are not used anymore */
    242	reg = readq(cpt->reg_base + OTX_CPT_PF_EXE_CTL);
    243	for_each_set_bit(i, bmap.bits, bmap.size)
    244		if (!eng_grp->g->eng_ref_cnt[i])
    245			reg &= ~(1ull << i);
    246	writeq(reg, cpt->reg_base + OTX_CPT_PF_EXE_CTL);
    247
    248	return 0;
    249}
    250
    251static int cpt_attach_and_enable_cores(struct otx_cpt_eng_grp_info *eng_grp,
    252				       void *obj)
    253{
    254	struct otx_cpt_device *cpt = (struct otx_cpt_device *) obj;
    255	struct otx_cpt_bitmap bmap;
    256	u64 reg;
    257	int i;
    258
    259	bmap = get_cores_bmap(&cpt->pdev->dev, eng_grp);
    260	if (!bmap.size)
    261		return -EINVAL;
    262
    263	/* Attach the cores to the group */
    264	reg = readq(cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));
    265	for_each_set_bit(i, bmap.bits, bmap.size) {
    266		if (!(reg & (1ull << i))) {
    267			eng_grp->g->eng_ref_cnt[i]++;
    268			reg |= 1ull << i;
    269		}
    270	}
    271	writeq(reg, cpt->reg_base + OTX_CPT_PF_GX_EN(eng_grp->idx));
    272
    273	/* Enable the cores */
    274	reg = readq(cpt->reg_base + OTX_CPT_PF_EXE_CTL);
    275	for_each_set_bit(i, bmap.bits, bmap.size)
    276		reg |= 1ull << i;
    277	writeq(reg, cpt->reg_base + OTX_CPT_PF_EXE_CTL);
    278
    279	return 0;
    280}
    281
    282static int process_tar_file(struct device *dev,
    283			    struct tar_arch_info_t *tar_arch, char *filename,
    284			    const u8 *data, u32 size)
    285{
    286	struct tar_ucode_info_t *tar_info;
    287	struct otx_cpt_ucode_hdr *ucode_hdr;
    288	int ucode_type, ucode_size;
    289
    290	/*
    291	 * If size is less than microcode header size then don't report
    292	 * an error because it might not be microcode file, just process
    293	 * next file from archive
    294	 */
    295	if (size < sizeof(struct otx_cpt_ucode_hdr))
    296		return 0;
    297
    298	ucode_hdr = (struct otx_cpt_ucode_hdr *) data;
    299	/*
    300	 * If microcode version can't be found don't report an error
    301	 * because it might not be microcode file, just process next file
    302	 */
    303	if (get_ucode_type(ucode_hdr, &ucode_type))
    304		return 0;
    305
    306	ucode_size = ntohl(ucode_hdr->code_length) * 2;
    307	if (!ucode_size || (size < round_up(ucode_size, 16) +
    308	    sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
    309		dev_err(dev, "Ucode %s invalid size\n", filename);
    310		return -EINVAL;
    311	}
    312
    313	tar_info = kzalloc(sizeof(struct tar_ucode_info_t), GFP_KERNEL);
    314	if (!tar_info)
    315		return -ENOMEM;
    316
    317	tar_info->ucode_ptr = data;
    318	set_ucode_filename(&tar_info->ucode, filename);
    319	memcpy(tar_info->ucode.ver_str, ucode_hdr->ver_str,
    320	       OTX_CPT_UCODE_VER_STR_SZ);
    321	tar_info->ucode.ver_num = ucode_hdr->ver_num;
    322	tar_info->ucode.type = ucode_type;
    323	tar_info->ucode.size = ucode_size;
    324	list_add_tail(&tar_info->list, &tar_arch->ucodes);
    325
    326	return 0;
    327}
    328
    329static void release_tar_archive(struct tar_arch_info_t *tar_arch)
    330{
    331	struct tar_ucode_info_t *curr, *temp;
    332
    333	if (!tar_arch)
    334		return;
    335
    336	list_for_each_entry_safe(curr, temp, &tar_arch->ucodes, list) {
    337		list_del(&curr->list);
    338		kfree(curr);
    339	}
    340
    341	if (tar_arch->fw)
    342		release_firmware(tar_arch->fw);
    343	kfree(tar_arch);
    344}
    345
    346static struct tar_ucode_info_t *get_uc_from_tar_archive(
    347					struct tar_arch_info_t *tar_arch,
    348					int ucode_type)
    349{
    350	struct tar_ucode_info_t *curr, *uc_found = NULL;
    351
    352	list_for_each_entry(curr, &tar_arch->ucodes, list) {
    353		if (!is_eng_type(curr->ucode.type, ucode_type))
    354			continue;
    355
    356		if (!uc_found) {
    357			uc_found = curr;
    358			continue;
    359		}
    360
    361		switch (ucode_type) {
    362		case OTX_CPT_AE_TYPES:
    363			break;
    364
    365		case OTX_CPT_SE_TYPES:
    366			if (uc_found->ucode.ver_num.nn == OTX_CPT_SE_UC_TYPE2 ||
    367			    (uc_found->ucode.ver_num.nn == OTX_CPT_SE_UC_TYPE3
    368			     && curr->ucode.ver_num.nn == OTX_CPT_SE_UC_TYPE1))
    369				uc_found = curr;
    370			break;
    371		}
    372	}
    373
    374	return uc_found;
    375}
    376
    377static void print_tar_dbg_info(struct tar_arch_info_t *tar_arch,
    378			       char *tar_filename)
    379{
    380	struct tar_ucode_info_t *curr;
    381
    382	pr_debug("Tar archive filename %s\n", tar_filename);
    383	pr_debug("Tar archive pointer %p, size %ld\n", tar_arch->fw->data,
    384		 tar_arch->fw->size);
    385	list_for_each_entry(curr, &tar_arch->ucodes, list) {
    386		pr_debug("Ucode filename %s\n", curr->ucode.filename);
    387		pr_debug("Ucode version string %s\n", curr->ucode.ver_str);
    388		pr_debug("Ucode version %d.%d.%d.%d\n",
    389			 curr->ucode.ver_num.nn, curr->ucode.ver_num.xx,
    390			 curr->ucode.ver_num.yy, curr->ucode.ver_num.zz);
    391		pr_debug("Ucode type (%d) %s\n", curr->ucode.type,
    392			 get_ucode_type_str(curr->ucode.type));
    393		pr_debug("Ucode size %d\n", curr->ucode.size);
    394		pr_debug("Ucode ptr %p\n", curr->ucode_ptr);
    395	}
    396}
    397
    398static struct tar_arch_info_t *load_tar_archive(struct device *dev,
    399						char *tar_filename)
    400{
    401	struct tar_arch_info_t *tar_arch = NULL;
    402	struct tar_blk_t *tar_blk;
    403	unsigned int cur_size;
    404	size_t tar_offs = 0;
    405	size_t tar_size;
    406	int ret;
    407
    408	tar_arch = kzalloc(sizeof(struct tar_arch_info_t), GFP_KERNEL);
    409	if (!tar_arch)
    410		return NULL;
    411
    412	INIT_LIST_HEAD(&tar_arch->ucodes);
    413
    414	/* Load tar archive */
    415	ret = request_firmware(&tar_arch->fw, tar_filename, dev);
    416	if (ret)
    417		goto release_tar_arch;
    418
    419	if (tar_arch->fw->size < TAR_BLOCK_LEN) {
    420		dev_err(dev, "Invalid tar archive %s\n", tar_filename);
    421		goto release_tar_arch;
    422	}
    423
    424	tar_size = tar_arch->fw->size;
    425	tar_blk = (struct tar_blk_t *) tar_arch->fw->data;
    426	if (strncmp(tar_blk->hdr.magic, TAR_MAGIC, TAR_MAGIC_LEN - 1)) {
    427		dev_err(dev, "Unsupported format of tar archive %s\n",
    428			tar_filename);
    429		goto release_tar_arch;
    430	}
    431
    432	while (1) {
    433		/* Read current file size */
    434		ret = kstrtouint(tar_blk->hdr.size, 8, &cur_size);
    435		if (ret)
    436			goto release_tar_arch;
    437
    438		if (tar_offs + cur_size > tar_size ||
    439		    tar_offs + 2*TAR_BLOCK_LEN > tar_size) {
    440			dev_err(dev, "Invalid tar archive %s\n", tar_filename);
    441			goto release_tar_arch;
    442		}
    443
    444		tar_offs += TAR_BLOCK_LEN;
    445		if (tar_blk->hdr.typeflag == REGTYPE ||
    446		    tar_blk->hdr.typeflag == AREGTYPE) {
    447			ret = process_tar_file(dev, tar_arch,
    448					       tar_blk->hdr.name,
    449					       &tar_arch->fw->data[tar_offs],
    450					       cur_size);
    451			if (ret)
    452				goto release_tar_arch;
    453		}
    454
    455		tar_offs += (cur_size/TAR_BLOCK_LEN) * TAR_BLOCK_LEN;
    456		if (cur_size % TAR_BLOCK_LEN)
    457			tar_offs += TAR_BLOCK_LEN;
    458
    459		/* Check for the end of the archive */
    460		if (tar_offs + 2*TAR_BLOCK_LEN > tar_size) {
    461			dev_err(dev, "Invalid tar archive %s\n", tar_filename);
    462			goto release_tar_arch;
    463		}
    464
    465		if (is_mem_zero(&tar_arch->fw->data[tar_offs],
    466		    2*TAR_BLOCK_LEN))
    467			break;
    468
    469		/* Read next block from tar archive */
    470		tar_blk = (struct tar_blk_t *) &tar_arch->fw->data[tar_offs];
    471	}
    472
    473	print_tar_dbg_info(tar_arch, tar_filename);
    474	return tar_arch;
    475release_tar_arch:
    476	release_tar_archive(tar_arch);
    477	return NULL;
    478}
    479
    480static struct otx_cpt_engs_rsvd *find_engines_by_type(
    481					struct otx_cpt_eng_grp_info *eng_grp,
    482					int eng_type)
    483{
    484	int i;
    485
    486	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
    487		if (!eng_grp->engs[i].type)
    488			continue;
    489
    490		if (eng_grp->engs[i].type == eng_type)
    491			return &eng_grp->engs[i];
    492	}
    493	return NULL;
    494}
    495
    496int otx_cpt_uc_supports_eng_type(struct otx_cpt_ucode *ucode, int eng_type)
    497{
    498	return is_eng_type(ucode->type, eng_type);
    499}
    500EXPORT_SYMBOL_GPL(otx_cpt_uc_supports_eng_type);
    501
    502int otx_cpt_eng_grp_has_eng_type(struct otx_cpt_eng_grp_info *eng_grp,
    503				 int eng_type)
    504{
    505	struct otx_cpt_engs_rsvd *engs;
    506
    507	engs = find_engines_by_type(eng_grp, eng_type);
    508
    509	return (engs != NULL ? 1 : 0);
    510}
    511EXPORT_SYMBOL_GPL(otx_cpt_eng_grp_has_eng_type);
    512
    513static void print_ucode_info(struct otx_cpt_eng_grp_info *eng_grp,
    514			     char *buf, int size)
    515{
    516	if (eng_grp->mirror.is_ena) {
    517		scnprintf(buf, size, "%s (shared with engine_group%d)",
    518			  eng_grp->g->grp[eng_grp->mirror.idx].ucode[0].ver_str,
    519			  eng_grp->mirror.idx);
    520	} else {
    521		scnprintf(buf, size, "%s", eng_grp->ucode[0].ver_str);
    522	}
    523}
    524
    525static void print_engs_info(struct otx_cpt_eng_grp_info *eng_grp,
    526			    char *buf, int size, int idx)
    527{
    528	struct otx_cpt_engs_rsvd *mirrored_engs = NULL;
    529	struct otx_cpt_engs_rsvd *engs;
    530	int len, i;
    531
    532	buf[0] = '\0';
    533	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
    534		engs = &eng_grp->engs[i];
    535		if (!engs->type)
    536			continue;
    537		if (idx != -1 && idx != i)
    538			continue;
    539
    540		if (eng_grp->mirror.is_ena)
    541			mirrored_engs = find_engines_by_type(
    542					&eng_grp->g->grp[eng_grp->mirror.idx],
    543					engs->type);
    544		if (i > 0 && idx == -1) {
    545			len = strlen(buf);
    546			scnprintf(buf+len, size-len, ", ");
    547		}
    548
    549		len = strlen(buf);
    550		scnprintf(buf+len, size-len, "%d %s ", mirrored_engs ?
    551			  engs->count + mirrored_engs->count : engs->count,
    552			  get_eng_type_str(engs->type));
    553		if (mirrored_engs) {
    554			len = strlen(buf);
    555			scnprintf(buf+len, size-len,
    556				  "(%d shared with engine_group%d) ",
    557				  engs->count <= 0 ? engs->count +
    558				  mirrored_engs->count : mirrored_engs->count,
    559				  eng_grp->mirror.idx);
    560		}
    561	}
    562}
    563
    564static void print_ucode_dbg_info(struct otx_cpt_ucode *ucode)
    565{
    566	pr_debug("Ucode info\n");
    567	pr_debug("Ucode version string %s\n", ucode->ver_str);
    568	pr_debug("Ucode version %d.%d.%d.%d\n", ucode->ver_num.nn,
    569		 ucode->ver_num.xx, ucode->ver_num.yy, ucode->ver_num.zz);
    570	pr_debug("Ucode type %s\n", get_ucode_type_str(ucode->type));
    571	pr_debug("Ucode size %d\n", ucode->size);
    572	pr_debug("Ucode virt address %16.16llx\n", (u64)ucode->align_va);
    573	pr_debug("Ucode phys address %16.16llx\n", ucode->align_dma);
    574}
    575
    576static void cpt_print_engines_mask(struct otx_cpt_eng_grp_info *eng_grp,
    577				   struct device *dev, char *buf, int size)
    578{
    579	struct otx_cpt_bitmap bmap;
    580	u32 mask[2];
    581
    582	bmap = get_cores_bmap(dev, eng_grp);
    583	if (!bmap.size) {
    584		scnprintf(buf, size, "unknown");
    585		return;
    586	}
    587	bitmap_to_arr32(mask, bmap.bits, bmap.size);
    588	scnprintf(buf, size, "%8.8x %8.8x", mask[1], mask[0]);
    589}
    590
    591
    592static void print_dbg_info(struct device *dev,
    593			   struct otx_cpt_eng_grps *eng_grps)
    594{
    595	char engs_info[2*OTX_CPT_UCODE_NAME_LENGTH];
    596	struct otx_cpt_eng_grp_info *mirrored_grp;
    597	char engs_mask[OTX_CPT_UCODE_NAME_LENGTH];
    598	struct otx_cpt_eng_grp_info *grp;
    599	struct otx_cpt_engs_rsvd *engs;
    600	u32 mask[4];
    601	int i, j;
    602
    603	pr_debug("Engine groups global info\n");
    604	pr_debug("max SE %d, max AE %d\n",
    605		 eng_grps->avail.max_se_cnt, eng_grps->avail.max_ae_cnt);
    606	pr_debug("free SE %d\n", eng_grps->avail.se_cnt);
    607	pr_debug("free AE %d\n", eng_grps->avail.ae_cnt);
    608
    609	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
    610		grp = &eng_grps->grp[i];
    611		pr_debug("engine_group%d, state %s\n", i, grp->is_enabled ?
    612			 "enabled" : "disabled");
    613		if (grp->is_enabled) {
    614			mirrored_grp = &eng_grps->grp[grp->mirror.idx];
    615			pr_debug("Ucode0 filename %s, version %s\n",
    616				 grp->mirror.is_ena ?
    617				 mirrored_grp->ucode[0].filename :
    618				 grp->ucode[0].filename,
    619				 grp->mirror.is_ena ?
    620				 mirrored_grp->ucode[0].ver_str :
    621				 grp->ucode[0].ver_str);
    622		}
    623
    624		for (j = 0; j < OTX_CPT_MAX_ETYPES_PER_GRP; j++) {
    625			engs = &grp->engs[j];
    626			if (engs->type) {
    627				print_engs_info(grp, engs_info,
    628						2*OTX_CPT_UCODE_NAME_LENGTH, j);
    629				pr_debug("Slot%d: %s\n", j, engs_info);
    630				bitmap_to_arr32(mask, engs->bmap,
    631						eng_grps->engs_num);
    632				pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x\n",
    633					 mask[3], mask[2], mask[1], mask[0]);
    634			} else
    635				pr_debug("Slot%d not used\n", j);
    636		}
    637		if (grp->is_enabled) {
    638			cpt_print_engines_mask(grp, dev, engs_mask,
    639					       OTX_CPT_UCODE_NAME_LENGTH);
    640			pr_debug("Cmask: %s\n", engs_mask);
    641		}
    642	}
    643}
    644
    645static int update_engines_avail_count(struct device *dev,
    646				      struct otx_cpt_engs_available *avail,
    647				      struct otx_cpt_engs_rsvd *engs, int val)
    648{
    649	switch (engs->type) {
    650	case OTX_CPT_SE_TYPES:
    651		avail->se_cnt += val;
    652		break;
    653
    654	case OTX_CPT_AE_TYPES:
    655		avail->ae_cnt += val;
    656		break;
    657
    658	default:
    659		dev_err(dev, "Invalid engine type %d\n", engs->type);
    660		return -EINVAL;
    661	}
    662
    663	return 0;
    664}
    665
    666static int update_engines_offset(struct device *dev,
    667				 struct otx_cpt_engs_available *avail,
    668				 struct otx_cpt_engs_rsvd *engs)
    669{
    670	switch (engs->type) {
    671	case OTX_CPT_SE_TYPES:
    672		engs->offset = 0;
    673		break;
    674
    675	case OTX_CPT_AE_TYPES:
    676		engs->offset = avail->max_se_cnt;
    677		break;
    678
    679	default:
    680		dev_err(dev, "Invalid engine type %d\n", engs->type);
    681		return -EINVAL;
    682	}
    683
    684	return 0;
    685}
    686
    687static int release_engines(struct device *dev, struct otx_cpt_eng_grp_info *grp)
    688{
    689	int i, ret = 0;
    690
    691	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
    692		if (!grp->engs[i].type)
    693			continue;
    694
    695		if (grp->engs[i].count > 0) {
    696			ret = update_engines_avail_count(dev, &grp->g->avail,
    697							 &grp->engs[i],
    698							 grp->engs[i].count);
    699			if (ret)
    700				return ret;
    701		}
    702
    703		grp->engs[i].type = 0;
    704		grp->engs[i].count = 0;
    705		grp->engs[i].offset = 0;
    706		grp->engs[i].ucode = NULL;
    707		bitmap_zero(grp->engs[i].bmap, grp->g->engs_num);
    708	}
    709
    710	return 0;
    711}
    712
    713static int do_reserve_engines(struct device *dev,
    714			      struct otx_cpt_eng_grp_info *grp,
    715			      struct otx_cpt_engines *req_engs)
    716{
    717	struct otx_cpt_engs_rsvd *engs = NULL;
    718	int i, ret;
    719
    720	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
    721		if (!grp->engs[i].type) {
    722			engs = &grp->engs[i];
    723			break;
    724		}
    725	}
    726
    727	if (!engs)
    728		return -ENOMEM;
    729
    730	engs->type = req_engs->type;
    731	engs->count = req_engs->count;
    732
    733	ret = update_engines_offset(dev, &grp->g->avail, engs);
    734	if (ret)
    735		return ret;
    736
    737	if (engs->count > 0) {
    738		ret = update_engines_avail_count(dev, &grp->g->avail, engs,
    739						 -engs->count);
    740		if (ret)
    741			return ret;
    742	}
    743
    744	return 0;
    745}
    746
    747static int check_engines_availability(struct device *dev,
    748				      struct otx_cpt_eng_grp_info *grp,
    749				      struct otx_cpt_engines *req_eng)
    750{
    751	int avail_cnt = 0;
    752
    753	switch (req_eng->type) {
    754	case OTX_CPT_SE_TYPES:
    755		avail_cnt = grp->g->avail.se_cnt;
    756		break;
    757
    758	case OTX_CPT_AE_TYPES:
    759		avail_cnt = grp->g->avail.ae_cnt;
    760		break;
    761
    762	default:
    763		dev_err(dev, "Invalid engine type %d\n", req_eng->type);
    764		return -EINVAL;
    765	}
    766
    767	if (avail_cnt < req_eng->count) {
    768		dev_err(dev,
    769			"Error available %s engines %d < than requested %d\n",
    770			get_eng_type_str(req_eng->type),
    771			avail_cnt, req_eng->count);
    772		return -EBUSY;
    773	}
    774
    775	return 0;
    776}
    777
    778static int reserve_engines(struct device *dev, struct otx_cpt_eng_grp_info *grp,
    779			   struct otx_cpt_engines *req_engs, int req_cnt)
    780{
    781	int i, ret;
    782
    783	/* Validate if a number of requested engines is available */
    784	for (i = 0; i < req_cnt; i++) {
    785		ret = check_engines_availability(dev, grp, &req_engs[i]);
    786		if (ret)
    787			return ret;
    788	}
    789
    790	/* Reserve requested engines for this engine group */
    791	for (i = 0; i < req_cnt; i++) {
    792		ret = do_reserve_engines(dev, grp, &req_engs[i]);
    793		if (ret)
    794			return ret;
    795	}
    796	return 0;
    797}
    798
    799static ssize_t eng_grp_info_show(struct device *dev,
    800				 struct device_attribute *attr,
    801				 char *buf)
    802{
    803	char ucode_info[2*OTX_CPT_UCODE_NAME_LENGTH];
    804	char engs_info[2*OTX_CPT_UCODE_NAME_LENGTH];
    805	char engs_mask[OTX_CPT_UCODE_NAME_LENGTH];
    806	struct otx_cpt_eng_grp_info *eng_grp;
    807	int ret;
    808
    809	eng_grp = container_of(attr, struct otx_cpt_eng_grp_info, info_attr);
    810	mutex_lock(&eng_grp->g->lock);
    811
    812	print_engs_info(eng_grp, engs_info, 2*OTX_CPT_UCODE_NAME_LENGTH, -1);
    813	print_ucode_info(eng_grp, ucode_info, 2*OTX_CPT_UCODE_NAME_LENGTH);
    814	cpt_print_engines_mask(eng_grp, dev, engs_mask,
    815			       OTX_CPT_UCODE_NAME_LENGTH);
    816	ret = scnprintf(buf, PAGE_SIZE,
    817			"Microcode : %s\nEngines: %s\nEngines mask: %s\n",
    818			ucode_info, engs_info, engs_mask);
    819
    820	mutex_unlock(&eng_grp->g->lock);
    821	return ret;
    822}
    823
    824static int create_sysfs_eng_grps_info(struct device *dev,
    825				      struct otx_cpt_eng_grp_info *eng_grp)
    826{
    827	eng_grp->info_attr.show = eng_grp_info_show;
    828	eng_grp->info_attr.store = NULL;
    829	eng_grp->info_attr.attr.name = eng_grp->sysfs_info_name;
    830	eng_grp->info_attr.attr.mode = 0440;
    831	sysfs_attr_init(&eng_grp->info_attr.attr);
    832	return device_create_file(dev, &eng_grp->info_attr);
    833}
    834
    835static void ucode_unload(struct device *dev, struct otx_cpt_ucode *ucode)
    836{
    837	if (ucode->va) {
    838		dma_free_coherent(dev, ucode->size + OTX_CPT_UCODE_ALIGNMENT,
    839				  ucode->va, ucode->dma);
    840		ucode->va = NULL;
    841		ucode->align_va = NULL;
    842		ucode->dma = 0;
    843		ucode->align_dma = 0;
    844		ucode->size = 0;
    845	}
    846
    847	memset(&ucode->ver_str, 0, OTX_CPT_UCODE_VER_STR_SZ);
    848	memset(&ucode->ver_num, 0, sizeof(struct otx_cpt_ucode_ver_num));
    849	set_ucode_filename(ucode, "");
    850	ucode->type = 0;
    851}
    852
    853static int copy_ucode_to_dma_mem(struct device *dev,
    854				 struct otx_cpt_ucode *ucode,
    855				 const u8 *ucode_data)
    856{
    857	u32 i;
    858
    859	/*  Allocate DMAable space */
    860	ucode->va = dma_alloc_coherent(dev, ucode->size +
    861				       OTX_CPT_UCODE_ALIGNMENT,
    862				       &ucode->dma, GFP_KERNEL);
    863	if (!ucode->va) {
    864		dev_err(dev, "Unable to allocate space for microcode\n");
    865		return -ENOMEM;
    866	}
    867	ucode->align_va = PTR_ALIGN(ucode->va, OTX_CPT_UCODE_ALIGNMENT);
    868	ucode->align_dma = PTR_ALIGN(ucode->dma, OTX_CPT_UCODE_ALIGNMENT);
    869
    870	memcpy((void *) ucode->align_va, (void *) ucode_data +
    871	       sizeof(struct otx_cpt_ucode_hdr), ucode->size);
    872
    873	/* Byte swap 64-bit */
    874	for (i = 0; i < (ucode->size / 8); i++)
    875		((__be64 *)ucode->align_va)[i] =
    876				cpu_to_be64(((u64 *)ucode->align_va)[i]);
    877	/*  Ucode needs 16-bit swap */
    878	for (i = 0; i < (ucode->size / 2); i++)
    879		((__be16 *)ucode->align_va)[i] =
    880				cpu_to_be16(((u16 *)ucode->align_va)[i]);
    881	return 0;
    882}
    883
    884static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
    885		      const char *ucode_filename)
    886{
    887	struct otx_cpt_ucode_hdr *ucode_hdr;
    888	const struct firmware *fw;
    889	int ret;
    890
    891	set_ucode_filename(ucode, ucode_filename);
    892	ret = request_firmware(&fw, ucode->filename, dev);
    893	if (ret)
    894		return ret;
    895
    896	ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;
    897	memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
    898	ucode->ver_num = ucode_hdr->ver_num;
    899	ucode->size = ntohl(ucode_hdr->code_length) * 2;
    900	if (!ucode->size || (fw->size < round_up(ucode->size, 16)
    901	    + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
    902		dev_err(dev, "Ucode %s invalid size\n", ucode_filename);
    903		ret = -EINVAL;
    904		goto release_fw;
    905	}
    906
    907	ret = get_ucode_type(ucode_hdr, &ucode->type);
    908	if (ret) {
    909		dev_err(dev, "Microcode %s unknown type 0x%x\n",
    910			ucode->filename, ucode->type);
    911		goto release_fw;
    912	}
    913
    914	ret = copy_ucode_to_dma_mem(dev, ucode, fw->data);
    915	if (ret)
    916		goto release_fw;
    917
    918	print_ucode_dbg_info(ucode);
    919release_fw:
    920	release_firmware(fw);
    921	return ret;
    922}
    923
    924static int enable_eng_grp(struct otx_cpt_eng_grp_info *eng_grp,
    925			  void *obj)
    926{
    927	int ret;
    928
    929	ret = cpt_set_ucode_base(eng_grp, obj);
    930	if (ret)
    931		return ret;
    932
    933	ret = cpt_attach_and_enable_cores(eng_grp, obj);
    934	return ret;
    935}
    936
    937static int disable_eng_grp(struct device *dev,
    938			   struct otx_cpt_eng_grp_info *eng_grp,
    939			   void *obj)
    940{
    941	int i, ret;
    942
    943	ret = cpt_detach_and_disable_cores(eng_grp, obj);
    944	if (ret)
    945		return ret;
    946
    947	/* Unload ucode used by this engine group */
    948	ucode_unload(dev, &eng_grp->ucode[0]);
    949
    950	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
    951		if (!eng_grp->engs[i].type)
    952			continue;
    953
    954		eng_grp->engs[i].ucode = &eng_grp->ucode[0];
    955	}
    956
    957	ret = cpt_set_ucode_base(eng_grp, obj);
    958
    959	return ret;
    960}
    961
    962static void setup_eng_grp_mirroring(struct otx_cpt_eng_grp_info *dst_grp,
    963				    struct otx_cpt_eng_grp_info *src_grp)
    964{
    965	/* Setup fields for engine group which is mirrored */
    966	src_grp->mirror.is_ena = false;
    967	src_grp->mirror.idx = 0;
    968	src_grp->mirror.ref_count++;
    969
    970	/* Setup fields for mirroring engine group */
    971	dst_grp->mirror.is_ena = true;
    972	dst_grp->mirror.idx = src_grp->idx;
    973	dst_grp->mirror.ref_count = 0;
    974}
    975
    976static void remove_eng_grp_mirroring(struct otx_cpt_eng_grp_info *dst_grp)
    977{
    978	struct otx_cpt_eng_grp_info *src_grp;
    979
    980	if (!dst_grp->mirror.is_ena)
    981		return;
    982
    983	src_grp = &dst_grp->g->grp[dst_grp->mirror.idx];
    984
    985	src_grp->mirror.ref_count--;
    986	dst_grp->mirror.is_ena = false;
    987	dst_grp->mirror.idx = 0;
    988	dst_grp->mirror.ref_count = 0;
    989}
    990
    991static void update_requested_engs(struct otx_cpt_eng_grp_info *mirrored_eng_grp,
    992				  struct otx_cpt_engines *engs, int engs_cnt)
    993{
    994	struct otx_cpt_engs_rsvd *mirrored_engs;
    995	int i;
    996
    997	for (i = 0; i < engs_cnt; i++) {
    998		mirrored_engs = find_engines_by_type(mirrored_eng_grp,
    999						     engs[i].type);
   1000		if (!mirrored_engs)
   1001			continue;
   1002
   1003		/*
   1004		 * If mirrored group has this type of engines attached then
   1005		 * there are 3 scenarios possible:
   1006		 * 1) mirrored_engs.count == engs[i].count then all engines
   1007		 * from mirrored engine group will be shared with this engine
   1008		 * group
   1009		 * 2) mirrored_engs.count > engs[i].count then only a subset of
   1010		 * engines from mirrored engine group will be shared with this
   1011		 * engine group
   1012		 * 3) mirrored_engs.count < engs[i].count then all engines
   1013		 * from mirrored engine group will be shared with this group
   1014		 * and additional engines will be reserved for exclusively use
   1015		 * by this engine group
   1016		 */
   1017		engs[i].count -= mirrored_engs->count;
   1018	}
   1019}
   1020
   1021static struct otx_cpt_eng_grp_info *find_mirrored_eng_grp(
   1022					struct otx_cpt_eng_grp_info *grp)
   1023{
   1024	struct otx_cpt_eng_grps *eng_grps = grp->g;
   1025	int i;
   1026
   1027	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
   1028		if (!eng_grps->grp[i].is_enabled)
   1029			continue;
   1030		if (eng_grps->grp[i].ucode[0].type)
   1031			continue;
   1032		if (grp->idx == i)
   1033			continue;
   1034		if (!strncasecmp(eng_grps->grp[i].ucode[0].ver_str,
   1035				 grp->ucode[0].ver_str,
   1036				 OTX_CPT_UCODE_VER_STR_SZ))
   1037			return &eng_grps->grp[i];
   1038	}
   1039
   1040	return NULL;
   1041}
   1042
   1043static struct otx_cpt_eng_grp_info *find_unused_eng_grp(
   1044					struct otx_cpt_eng_grps *eng_grps)
   1045{
   1046	int i;
   1047
   1048	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
   1049		if (!eng_grps->grp[i].is_enabled)
   1050			return &eng_grps->grp[i];
   1051	}
   1052	return NULL;
   1053}
   1054
   1055static int eng_grp_update_masks(struct device *dev,
   1056				struct otx_cpt_eng_grp_info *eng_grp)
   1057{
   1058	struct otx_cpt_engs_rsvd *engs, *mirrored_engs;
   1059	struct otx_cpt_bitmap tmp_bmap = { {0} };
   1060	int i, j, cnt, max_cnt;
   1061	int bit;
   1062
   1063	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
   1064		engs = &eng_grp->engs[i];
   1065		if (!engs->type)
   1066			continue;
   1067		if (engs->count <= 0)
   1068			continue;
   1069
   1070		switch (engs->type) {
   1071		case OTX_CPT_SE_TYPES:
   1072			max_cnt = eng_grp->g->avail.max_se_cnt;
   1073			break;
   1074
   1075		case OTX_CPT_AE_TYPES:
   1076			max_cnt = eng_grp->g->avail.max_ae_cnt;
   1077			break;
   1078
   1079		default:
   1080			dev_err(dev, "Invalid engine type %d\n", engs->type);
   1081			return -EINVAL;
   1082		}
   1083
   1084		cnt = engs->count;
   1085		WARN_ON(engs->offset + max_cnt > OTX_CPT_MAX_ENGINES);
   1086		bitmap_zero(tmp_bmap.bits, eng_grp->g->engs_num);
   1087		for (j = engs->offset; j < engs->offset + max_cnt; j++) {
   1088			if (!eng_grp->g->eng_ref_cnt[j]) {
   1089				bitmap_set(tmp_bmap.bits, j, 1);
   1090				cnt--;
   1091				if (!cnt)
   1092					break;
   1093			}
   1094		}
   1095
   1096		if (cnt)
   1097			return -ENOSPC;
   1098
   1099		bitmap_copy(engs->bmap, tmp_bmap.bits, eng_grp->g->engs_num);
   1100	}
   1101
   1102	if (!eng_grp->mirror.is_ena)
   1103		return 0;
   1104
   1105	for (i = 0; i < OTX_CPT_MAX_ETYPES_PER_GRP; i++) {
   1106		engs = &eng_grp->engs[i];
   1107		if (!engs->type)
   1108			continue;
   1109
   1110		mirrored_engs = find_engines_by_type(
   1111					&eng_grp->g->grp[eng_grp->mirror.idx],
   1112					engs->type);
   1113		WARN_ON(!mirrored_engs && engs->count <= 0);
   1114		if (!mirrored_engs)
   1115			continue;
   1116
   1117		bitmap_copy(tmp_bmap.bits, mirrored_engs->bmap,
   1118			    eng_grp->g->engs_num);
   1119		if (engs->count < 0) {
   1120			bit = find_first_bit(mirrored_engs->bmap,
   1121					     eng_grp->g->engs_num);
   1122			bitmap_clear(tmp_bmap.bits, bit, -engs->count);
   1123		}
   1124		bitmap_or(engs->bmap, engs->bmap, tmp_bmap.bits,
   1125			  eng_grp->g->engs_num);
   1126	}
   1127	return 0;
   1128}
   1129
   1130static int delete_engine_group(struct device *dev,
   1131			       struct otx_cpt_eng_grp_info *eng_grp)
   1132{
   1133	int i, ret;
   1134
   1135	if (!eng_grp->is_enabled)
   1136		return -EINVAL;
   1137
   1138	if (eng_grp->mirror.ref_count) {
   1139		dev_err(dev, "Can't delete engine_group%d as it is used by engine_group(s):",
   1140			eng_grp->idx);
   1141		for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
   1142			if (eng_grp->g->grp[i].mirror.is_ena &&
   1143			    eng_grp->g->grp[i].mirror.idx == eng_grp->idx)
   1144				pr_cont(" %d", i);
   1145		}
   1146		pr_cont("\n");
   1147		return -EINVAL;
   1148	}
   1149
   1150	/* Removing engine group mirroring if enabled */
   1151	remove_eng_grp_mirroring(eng_grp);
   1152
   1153	/* Disable engine group */
   1154	ret = disable_eng_grp(dev, eng_grp, eng_grp->g->obj);
   1155	if (ret)
   1156		return ret;
   1157
   1158	/* Release all engines held by this engine group */
   1159	ret = release_engines(dev, eng_grp);
   1160	if (ret)
   1161		return ret;
   1162
   1163	device_remove_file(dev, &eng_grp->info_attr);
   1164	eng_grp->is_enabled = false;
   1165
   1166	return 0;
   1167}
   1168
   1169static int validate_1_ucode_scenario(struct device *dev,
   1170				     struct otx_cpt_eng_grp_info *eng_grp,
   1171				     struct otx_cpt_engines *engs, int engs_cnt)
   1172{
   1173	int i;
   1174
   1175	/* Verify that ucode loaded supports requested engine types */
   1176	for (i = 0; i < engs_cnt; i++) {
   1177		if (!otx_cpt_uc_supports_eng_type(&eng_grp->ucode[0],
   1178						  engs[i].type)) {
   1179			dev_err(dev,
   1180				"Microcode %s does not support %s engines\n",
   1181				eng_grp->ucode[0].filename,
   1182				get_eng_type_str(engs[i].type));
   1183			return -EINVAL;
   1184		}
   1185	}
   1186	return 0;
   1187}
   1188
   1189static void update_ucode_ptrs(struct otx_cpt_eng_grp_info *eng_grp)
   1190{
   1191	struct otx_cpt_ucode *ucode;
   1192
   1193	if (eng_grp->mirror.is_ena)
   1194		ucode = &eng_grp->g->grp[eng_grp->mirror.idx].ucode[0];
   1195	else
   1196		ucode = &eng_grp->ucode[0];
   1197	WARN_ON(!eng_grp->engs[0].type);
   1198	eng_grp->engs[0].ucode = ucode;
   1199}
   1200
   1201static int create_engine_group(struct device *dev,
   1202			       struct otx_cpt_eng_grps *eng_grps,
   1203			       struct otx_cpt_engines *engs, int engs_cnt,
   1204			       void *ucode_data[], int ucodes_cnt,
   1205			       bool use_uc_from_tar_arch)
   1206{
   1207	struct otx_cpt_eng_grp_info *mirrored_eng_grp;
   1208	struct tar_ucode_info_t *tar_info;
   1209	struct otx_cpt_eng_grp_info *eng_grp;
   1210	int i, ret = 0;
   1211
   1212	if (ucodes_cnt > OTX_CPT_MAX_ETYPES_PER_GRP)
   1213		return -EINVAL;
   1214
   1215	/* Validate if requested engine types are supported by this device */
   1216	for (i = 0; i < engs_cnt; i++)
   1217		if (!dev_supports_eng_type(eng_grps, engs[i].type)) {
   1218			dev_err(dev, "Device does not support %s engines\n",
   1219				get_eng_type_str(engs[i].type));
   1220			return -EPERM;
   1221		}
   1222
   1223	/* Find engine group which is not used */
   1224	eng_grp = find_unused_eng_grp(eng_grps);
   1225	if (!eng_grp) {
   1226		dev_err(dev, "Error all engine groups are being used\n");
   1227		return -ENOSPC;
   1228	}
   1229
   1230	/* Load ucode */
   1231	for (i = 0; i < ucodes_cnt; i++) {
   1232		if (use_uc_from_tar_arch) {
   1233			tar_info = (struct tar_ucode_info_t *) ucode_data[i];
   1234			eng_grp->ucode[i] = tar_info->ucode;
   1235			ret = copy_ucode_to_dma_mem(dev, &eng_grp->ucode[i],
   1236						    tar_info->ucode_ptr);
   1237		} else
   1238			ret = ucode_load(dev, &eng_grp->ucode[i],
   1239					 (char *) ucode_data[i]);
   1240		if (ret)
   1241			goto err_ucode_unload;
   1242	}
   1243
   1244	/* Validate scenario where 1 ucode is used */
   1245	ret = validate_1_ucode_scenario(dev, eng_grp, engs, engs_cnt);
   1246	if (ret)
   1247		goto err_ucode_unload;
   1248
   1249	/* Check if this group mirrors another existing engine group */
   1250	mirrored_eng_grp = find_mirrored_eng_grp(eng_grp);
   1251	if (mirrored_eng_grp) {
   1252		/* Setup mirroring */
   1253		setup_eng_grp_mirroring(eng_grp, mirrored_eng_grp);
   1254
   1255		/*
   1256		 * Update count of requested engines because some
   1257		 * of them might be shared with mirrored group
   1258		 */
   1259		update_requested_engs(mirrored_eng_grp, engs, engs_cnt);
   1260	}
   1261
   1262	/* Reserve engines */
   1263	ret = reserve_engines(dev, eng_grp, engs, engs_cnt);
   1264	if (ret)
   1265		goto err_ucode_unload;
   1266
   1267	/* Update ucode pointers used by engines */
   1268	update_ucode_ptrs(eng_grp);
   1269
   1270	/* Update engine masks used by this group */
   1271	ret = eng_grp_update_masks(dev, eng_grp);
   1272	if (ret)
   1273		goto err_release_engs;
   1274
   1275	/* Create sysfs entry for engine group info */
   1276	ret = create_sysfs_eng_grps_info(dev, eng_grp);
   1277	if (ret)
   1278		goto err_release_engs;
   1279
   1280	/* Enable engine group */
   1281	ret = enable_eng_grp(eng_grp, eng_grps->obj);
   1282	if (ret)
   1283		goto err_release_engs;
   1284
   1285	/*
   1286	 * If this engine group mirrors another engine group
   1287	 * then we need to unload ucode as we will use ucode
   1288	 * from mirrored engine group
   1289	 */
   1290	if (eng_grp->mirror.is_ena)
   1291		ucode_unload(dev, &eng_grp->ucode[0]);
   1292
   1293	eng_grp->is_enabled = true;
   1294	if (eng_grp->mirror.is_ena)
   1295		dev_info(dev,
   1296			 "Engine_group%d: reuse microcode %s from group %d\n",
   1297			 eng_grp->idx, mirrored_eng_grp->ucode[0].ver_str,
   1298			 mirrored_eng_grp->idx);
   1299	else
   1300		dev_info(dev, "Engine_group%d: microcode loaded %s\n",
   1301			 eng_grp->idx, eng_grp->ucode[0].ver_str);
   1302
   1303	return 0;
   1304
   1305err_release_engs:
   1306	release_engines(dev, eng_grp);
   1307err_ucode_unload:
   1308	ucode_unload(dev, &eng_grp->ucode[0]);
   1309	return ret;
   1310}
   1311
   1312static ssize_t ucode_load_store(struct device *dev,
   1313				struct device_attribute *attr,
   1314				const char *buf, size_t count)
   1315{
   1316	struct otx_cpt_engines engs[OTX_CPT_MAX_ETYPES_PER_GRP] = { {0} };
   1317	char *ucode_filename[OTX_CPT_MAX_ETYPES_PER_GRP];
   1318	char tmp_buf[OTX_CPT_UCODE_NAME_LENGTH] = { 0 };
   1319	char *start, *val, *err_msg, *tmp;
   1320	struct otx_cpt_eng_grps *eng_grps;
   1321	int grp_idx = 0, ret = -EINVAL;
   1322	bool has_se, has_ie, has_ae;
   1323	int del_grp_idx = -1;
   1324	int ucode_idx = 0;
   1325
   1326	if (strlen(buf) > OTX_CPT_UCODE_NAME_LENGTH)
   1327		return -EINVAL;
   1328
   1329	eng_grps = container_of(attr, struct otx_cpt_eng_grps, ucode_load_attr);
   1330	err_msg = "Invalid engine group format";
   1331	strlcpy(tmp_buf, buf, OTX_CPT_UCODE_NAME_LENGTH);
   1332	start = tmp_buf;
   1333
   1334	has_se = has_ie = has_ae = false;
   1335
   1336	for (;;) {
   1337		val = strsep(&start, ";");
   1338		if (!val)
   1339			break;
   1340		val = strim(val);
   1341		if (!*val)
   1342			continue;
   1343
   1344		if (!strncasecmp(val, "engine_group", 12)) {
   1345			if (del_grp_idx != -1)
   1346				goto err_print;
   1347			tmp = strim(strsep(&val, ":"));
   1348			if (!val)
   1349				goto err_print;
   1350			if (strlen(tmp) != 13)
   1351				goto err_print;
   1352			if (kstrtoint((tmp + 12), 10, &del_grp_idx))
   1353				goto err_print;
   1354			val = strim(val);
   1355			if (strncasecmp(val, "null", 4))
   1356				goto err_print;
   1357			if (strlen(val) != 4)
   1358				goto err_print;
   1359		} else if (!strncasecmp(val, "se", 2) && strchr(val, ':')) {
   1360			if (has_se || ucode_idx)
   1361				goto err_print;
   1362			tmp = strim(strsep(&val, ":"));
   1363			if (!val)
   1364				goto err_print;
   1365			if (strlen(tmp) != 2)
   1366				goto err_print;
   1367			if (kstrtoint(strim(val), 10, &engs[grp_idx].count))
   1368				goto err_print;
   1369			engs[grp_idx++].type = OTX_CPT_SE_TYPES;
   1370			has_se = true;
   1371		} else if (!strncasecmp(val, "ae", 2) && strchr(val, ':')) {
   1372			if (has_ae || ucode_idx)
   1373				goto err_print;
   1374			tmp = strim(strsep(&val, ":"));
   1375			if (!val)
   1376				goto err_print;
   1377			if (strlen(tmp) != 2)
   1378				goto err_print;
   1379			if (kstrtoint(strim(val), 10, &engs[grp_idx].count))
   1380				goto err_print;
   1381			engs[grp_idx++].type = OTX_CPT_AE_TYPES;
   1382			has_ae = true;
   1383		} else {
   1384			if (ucode_idx > 1)
   1385				goto err_print;
   1386			if (!strlen(val))
   1387				goto err_print;
   1388			if (strnstr(val, " ", strlen(val)))
   1389				goto err_print;
   1390			ucode_filename[ucode_idx++] = val;
   1391		}
   1392	}
   1393
   1394	/* Validate input parameters */
   1395	if (del_grp_idx == -1) {
   1396		if (!(grp_idx && ucode_idx))
   1397			goto err_print;
   1398
   1399		if (ucode_idx > 1 && grp_idx < 2)
   1400			goto err_print;
   1401
   1402		if (grp_idx > OTX_CPT_MAX_ETYPES_PER_GRP) {
   1403			err_msg = "Error max 2 engine types can be attached";
   1404			goto err_print;
   1405		}
   1406
   1407	} else {
   1408		if (del_grp_idx < 0 ||
   1409		    del_grp_idx >= OTX_CPT_MAX_ENGINE_GROUPS) {
   1410			dev_err(dev, "Invalid engine group index %d\n",
   1411				del_grp_idx);
   1412			ret = -EINVAL;
   1413			return ret;
   1414		}
   1415
   1416		if (!eng_grps->grp[del_grp_idx].is_enabled) {
   1417			dev_err(dev, "Error engine_group%d is not configured\n",
   1418				del_grp_idx);
   1419			ret = -EINVAL;
   1420			return ret;
   1421		}
   1422
   1423		if (grp_idx || ucode_idx)
   1424			goto err_print;
   1425	}
   1426
   1427	mutex_lock(&eng_grps->lock);
   1428
   1429	if (eng_grps->is_rdonly) {
   1430		dev_err(dev, "Disable VFs before modifying engine groups\n");
   1431		ret = -EACCES;
   1432		goto err_unlock;
   1433	}
   1434
   1435	if (del_grp_idx == -1)
   1436		/* create engine group */
   1437		ret = create_engine_group(dev, eng_grps, engs, grp_idx,
   1438					  (void **) ucode_filename,
   1439					  ucode_idx, false);
   1440	else
   1441		/* delete engine group */
   1442		ret = delete_engine_group(dev, &eng_grps->grp[del_grp_idx]);
   1443	if (ret)
   1444		goto err_unlock;
   1445
   1446	print_dbg_info(dev, eng_grps);
   1447err_unlock:
   1448	mutex_unlock(&eng_grps->lock);
   1449	return ret ? ret : count;
   1450err_print:
   1451	dev_err(dev, "%s\n", err_msg);
   1452
   1453	return ret;
   1454}
   1455
   1456int otx_cpt_try_create_default_eng_grps(struct pci_dev *pdev,
   1457					struct otx_cpt_eng_grps *eng_grps,
   1458					int pf_type)
   1459{
   1460	struct tar_ucode_info_t *tar_info[OTX_CPT_MAX_ETYPES_PER_GRP] = {};
   1461	struct otx_cpt_engines engs[OTX_CPT_MAX_ETYPES_PER_GRP] = {};
   1462	struct tar_arch_info_t *tar_arch = NULL;
   1463	char *tar_filename;
   1464	int i, ret = 0;
   1465
   1466	mutex_lock(&eng_grps->lock);
   1467
   1468	/*
   1469	 * We don't create engine group for kernel crypto if attempt to create
   1470	 * it was already made (when user enabled VFs for the first time)
   1471	 */
   1472	if (eng_grps->is_first_try)
   1473		goto unlock_mutex;
   1474	eng_grps->is_first_try = true;
   1475
   1476	/* We create group for kcrypto only if no groups are configured */
   1477	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++)
   1478		if (eng_grps->grp[i].is_enabled)
   1479			goto unlock_mutex;
   1480
   1481	switch (pf_type) {
   1482	case OTX_CPT_AE:
   1483	case OTX_CPT_SE:
   1484		tar_filename = OTX_CPT_UCODE_TAR_FILE_NAME;
   1485		break;
   1486
   1487	default:
   1488		dev_err(&pdev->dev, "Unknown PF type %d\n", pf_type);
   1489		ret = -EINVAL;
   1490		goto unlock_mutex;
   1491	}
   1492
   1493	tar_arch = load_tar_archive(&pdev->dev, tar_filename);
   1494	if (!tar_arch)
   1495		goto unlock_mutex;
   1496
   1497	/*
   1498	 * If device supports SE engines and there is SE microcode in tar
   1499	 * archive try to create engine group with SE engines for kernel
   1500	 * crypto functionality (symmetric crypto)
   1501	 */
   1502	tar_info[0] = get_uc_from_tar_archive(tar_arch, OTX_CPT_SE_TYPES);
   1503	if (tar_info[0] &&
   1504	    dev_supports_eng_type(eng_grps, OTX_CPT_SE_TYPES)) {
   1505
   1506		engs[0].type = OTX_CPT_SE_TYPES;
   1507		engs[0].count = eng_grps->avail.max_se_cnt;
   1508
   1509		ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
   1510					  (void **) tar_info, 1, true);
   1511		if (ret)
   1512			goto release_tar_arch;
   1513	}
   1514	/*
   1515	 * If device supports AE engines and there is AE microcode in tar
   1516	 * archive try to create engine group with AE engines for asymmetric
   1517	 * crypto functionality.
   1518	 */
   1519	tar_info[0] = get_uc_from_tar_archive(tar_arch, OTX_CPT_AE_TYPES);
   1520	if (tar_info[0] &&
   1521	    dev_supports_eng_type(eng_grps, OTX_CPT_AE_TYPES)) {
   1522
   1523		engs[0].type = OTX_CPT_AE_TYPES;
   1524		engs[0].count = eng_grps->avail.max_ae_cnt;
   1525
   1526		ret = create_engine_group(&pdev->dev, eng_grps, engs, 1,
   1527					  (void **) tar_info, 1, true);
   1528		if (ret)
   1529			goto release_tar_arch;
   1530	}
   1531
   1532	print_dbg_info(&pdev->dev, eng_grps);
   1533release_tar_arch:
   1534	release_tar_archive(tar_arch);
   1535unlock_mutex:
   1536	mutex_unlock(&eng_grps->lock);
   1537	return ret;
   1538}
   1539
   1540void otx_cpt_set_eng_grps_is_rdonly(struct otx_cpt_eng_grps *eng_grps,
   1541				    bool is_rdonly)
   1542{
   1543	mutex_lock(&eng_grps->lock);
   1544
   1545	eng_grps->is_rdonly = is_rdonly;
   1546
   1547	mutex_unlock(&eng_grps->lock);
   1548}
   1549
   1550void otx_cpt_disable_all_cores(struct otx_cpt_device *cpt)
   1551{
   1552	int grp, timeout = 100;
   1553	u64 reg;
   1554
   1555	/* Disengage the cores from groups */
   1556	for (grp = 0; grp < OTX_CPT_MAX_ENGINE_GROUPS; grp++) {
   1557		writeq(0, cpt->reg_base + OTX_CPT_PF_GX_EN(grp));
   1558		udelay(CSR_DELAY);
   1559	}
   1560
   1561	reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
   1562	while (reg) {
   1563		udelay(CSR_DELAY);
   1564		reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
   1565		if (timeout--) {
   1566			dev_warn(&cpt->pdev->dev, "Cores still busy\n");
   1567			break;
   1568		}
   1569	}
   1570
   1571	/* Disable the cores */
   1572	writeq(0, cpt->reg_base + OTX_CPT_PF_EXE_CTL);
   1573}
   1574
   1575void otx_cpt_cleanup_eng_grps(struct pci_dev *pdev,
   1576			      struct otx_cpt_eng_grps *eng_grps)
   1577{
   1578	struct otx_cpt_eng_grp_info *grp;
   1579	int i, j;
   1580
   1581	mutex_lock(&eng_grps->lock);
   1582	if (eng_grps->is_ucode_load_created) {
   1583		device_remove_file(&pdev->dev,
   1584				   &eng_grps->ucode_load_attr);
   1585		eng_grps->is_ucode_load_created = false;
   1586	}
   1587
   1588	/* First delete all mirroring engine groups */
   1589	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++)
   1590		if (eng_grps->grp[i].mirror.is_ena)
   1591			delete_engine_group(&pdev->dev, &eng_grps->grp[i]);
   1592
   1593	/* Delete remaining engine groups */
   1594	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++)
   1595		delete_engine_group(&pdev->dev, &eng_grps->grp[i]);
   1596
   1597	/* Release memory */
   1598	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
   1599		grp = &eng_grps->grp[i];
   1600		for (j = 0; j < OTX_CPT_MAX_ETYPES_PER_GRP; j++) {
   1601			kfree(grp->engs[j].bmap);
   1602			grp->engs[j].bmap = NULL;
   1603		}
   1604	}
   1605
   1606	mutex_unlock(&eng_grps->lock);
   1607}
   1608
   1609int otx_cpt_init_eng_grps(struct pci_dev *pdev,
   1610			  struct otx_cpt_eng_grps *eng_grps, int pf_type)
   1611{
   1612	struct otx_cpt_eng_grp_info *grp;
   1613	int i, j, ret = 0;
   1614
   1615	mutex_init(&eng_grps->lock);
   1616	eng_grps->obj = pci_get_drvdata(pdev);
   1617	eng_grps->avail.se_cnt = eng_grps->avail.max_se_cnt;
   1618	eng_grps->avail.ae_cnt = eng_grps->avail.max_ae_cnt;
   1619
   1620	eng_grps->engs_num = eng_grps->avail.max_se_cnt +
   1621			     eng_grps->avail.max_ae_cnt;
   1622	if (eng_grps->engs_num > OTX_CPT_MAX_ENGINES) {
   1623		dev_err(&pdev->dev,
   1624			"Number of engines %d > than max supported %d\n",
   1625			eng_grps->engs_num, OTX_CPT_MAX_ENGINES);
   1626		ret = -EINVAL;
   1627		goto err;
   1628	}
   1629
   1630	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
   1631		grp = &eng_grps->grp[i];
   1632		grp->g = eng_grps;
   1633		grp->idx = i;
   1634
   1635		snprintf(grp->sysfs_info_name, OTX_CPT_UCODE_NAME_LENGTH,
   1636			 "engine_group%d", i);
   1637		for (j = 0; j < OTX_CPT_MAX_ETYPES_PER_GRP; j++) {
   1638			grp->engs[j].bmap =
   1639				kcalloc(BITS_TO_LONGS(eng_grps->engs_num),
   1640					sizeof(long), GFP_KERNEL);
   1641			if (!grp->engs[j].bmap) {
   1642				ret = -ENOMEM;
   1643				goto err;
   1644			}
   1645		}
   1646	}
   1647
   1648	switch (pf_type) {
   1649	case OTX_CPT_SE:
   1650		/* OcteonTX 83XX SE CPT PF has only SE engines attached */
   1651		eng_grps->eng_types_supported = 1 << OTX_CPT_SE_TYPES;
   1652		break;
   1653
   1654	case OTX_CPT_AE:
   1655		/* OcteonTX 83XX AE CPT PF has only AE engines attached */
   1656		eng_grps->eng_types_supported = 1 << OTX_CPT_AE_TYPES;
   1657		break;
   1658
   1659	default:
   1660		dev_err(&pdev->dev, "Unknown PF type %d\n", pf_type);
   1661		ret = -EINVAL;
   1662		goto err;
   1663	}
   1664
   1665	eng_grps->ucode_load_attr.show = NULL;
   1666	eng_grps->ucode_load_attr.store = ucode_load_store;
   1667	eng_grps->ucode_load_attr.attr.name = "ucode_load";
   1668	eng_grps->ucode_load_attr.attr.mode = 0220;
   1669	sysfs_attr_init(&eng_grps->ucode_load_attr.attr);
   1670	ret = device_create_file(&pdev->dev,
   1671				 &eng_grps->ucode_load_attr);
   1672	if (ret)
   1673		goto err;
   1674	eng_grps->is_ucode_load_created = true;
   1675
   1676	print_dbg_info(&pdev->dev, eng_grps);
   1677	return ret;
   1678err:
   1679	otx_cpt_cleanup_eng_grps(pdev, eng_grps);
   1680	return ret;
   1681}