162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2015-2016 Freescale Semiconductor Inc.
462306a36Sopenharmony_ci * Copyright 2017-2019 NXP
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include "compat.h"
862306a36Sopenharmony_ci#include "regs.h"
962306a36Sopenharmony_ci#include "caamalg_qi2.h"
1062306a36Sopenharmony_ci#include "dpseci_cmd.h"
1162306a36Sopenharmony_ci#include "desc_constr.h"
1262306a36Sopenharmony_ci#include "error.h"
1362306a36Sopenharmony_ci#include "sg_sw_sec4.h"
1462306a36Sopenharmony_ci#include "sg_sw_qm2.h"
1562306a36Sopenharmony_ci#include "key_gen.h"
1662306a36Sopenharmony_ci#include "caamalg_desc.h"
1762306a36Sopenharmony_ci#include "caamhash_desc.h"
1862306a36Sopenharmony_ci#include "dpseci-debugfs.h"
1962306a36Sopenharmony_ci#include <linux/dma-mapping.h>
2062306a36Sopenharmony_ci#include <linux/fsl/mc.h>
2162306a36Sopenharmony_ci#include <linux/kernel.h>
2262306a36Sopenharmony_ci#include <soc/fsl/dpaa2-io.h>
2362306a36Sopenharmony_ci#include <soc/fsl/dpaa2-fd.h>
2462306a36Sopenharmony_ci#include <crypto/xts.h>
2562306a36Sopenharmony_ci#include <asm/unaligned.h>
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define CAAM_CRA_PRIORITY	2000
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* max key is sum of AES_MAX_KEY_SIZE, max split key size */
3062306a36Sopenharmony_ci#define CAAM_MAX_KEY_SIZE	(AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \
3162306a36Sopenharmony_ci				 SHA512_DIGEST_SIZE * 2)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/*
3462306a36Sopenharmony_ci * This is a cache of buffers, from which the users of CAAM QI driver
3562306a36Sopenharmony_ci * can allocate short buffers. It's speedier than doing kmalloc on the hotpath.
3662306a36Sopenharmony_ci * NOTE: A more elegant solution would be to have some headroom in the frames
3762306a36Sopenharmony_ci *       being processed. This can be added by the dpaa2-eth driver. This would
3862306a36Sopenharmony_ci *       pose a problem for userspace application processing which cannot
3962306a36Sopenharmony_ci *       know of this limitation. So for now, this will work.
4062306a36Sopenharmony_ci * NOTE: The memcache is SMP-safe. No need to handle spinlocks in-here
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_cistatic struct kmem_cache *qi_cache;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistruct caam_alg_entry {
4562306a36Sopenharmony_ci	struct device *dev;
4662306a36Sopenharmony_ci	int class1_alg_type;
4762306a36Sopenharmony_ci	int class2_alg_type;
4862306a36Sopenharmony_ci	bool rfc3686;
4962306a36Sopenharmony_ci	bool geniv;
5062306a36Sopenharmony_ci	bool nodkp;
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistruct caam_aead_alg {
5462306a36Sopenharmony_ci	struct aead_alg aead;
5562306a36Sopenharmony_ci	struct caam_alg_entry caam;
5662306a36Sopenharmony_ci	bool registered;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistruct caam_skcipher_alg {
6062306a36Sopenharmony_ci	struct skcipher_alg skcipher;
6162306a36Sopenharmony_ci	struct caam_alg_entry caam;
6262306a36Sopenharmony_ci	bool registered;
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/**
6662306a36Sopenharmony_ci * struct caam_ctx - per-session context
6762306a36Sopenharmony_ci * @flc: Flow Contexts array
6862306a36Sopenharmony_ci * @key:  [authentication key], encryption key
6962306a36Sopenharmony_ci * @flc_dma: I/O virtual addresses of the Flow Contexts
7062306a36Sopenharmony_ci * @key_dma: I/O virtual address of the key
7162306a36Sopenharmony_ci * @dir: DMA direction for mapping key and Flow Contexts
7262306a36Sopenharmony_ci * @dev: dpseci device
7362306a36Sopenharmony_ci * @adata: authentication algorithm details
7462306a36Sopenharmony_ci * @cdata: encryption algorithm details
7562306a36Sopenharmony_ci * @authsize: authentication tag (a.k.a. ICV / MAC) size
7662306a36Sopenharmony_ci * @xts_key_fallback: true if fallback tfm needs to be used due
7762306a36Sopenharmony_ci *		      to unsupported xts key lengths
7862306a36Sopenharmony_ci * @fallback: xts fallback tfm
7962306a36Sopenharmony_ci */
8062306a36Sopenharmony_cistruct caam_ctx {
8162306a36Sopenharmony_ci	struct caam_flc flc[NUM_OP];
8262306a36Sopenharmony_ci	u8 key[CAAM_MAX_KEY_SIZE];
8362306a36Sopenharmony_ci	dma_addr_t flc_dma[NUM_OP];
8462306a36Sopenharmony_ci	dma_addr_t key_dma;
8562306a36Sopenharmony_ci	enum dma_data_direction dir;
8662306a36Sopenharmony_ci	struct device *dev;
8762306a36Sopenharmony_ci	struct alginfo adata;
8862306a36Sopenharmony_ci	struct alginfo cdata;
8962306a36Sopenharmony_ci	unsigned int authsize;
9062306a36Sopenharmony_ci	bool xts_key_fallback;
9162306a36Sopenharmony_ci	struct crypto_skcipher *fallback;
9262306a36Sopenharmony_ci};
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistatic void *dpaa2_caam_iova_to_virt(struct dpaa2_caam_priv *priv,
9562306a36Sopenharmony_ci				     dma_addr_t iova_addr)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	phys_addr_t phys_addr;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	phys_addr = priv->domain ? iommu_iova_to_phys(priv->domain, iova_addr) :
10062306a36Sopenharmony_ci				   iova_addr;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	return phys_to_virt(phys_addr);
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/*
10662306a36Sopenharmony_ci * qi_cache_zalloc - Allocate buffers from CAAM-QI cache
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci * Allocate data on the hotpath. Instead of using kzalloc, one can use the
10962306a36Sopenharmony_ci * services of the CAAM QI memory cache (backed by kmem_cache). The buffers
11062306a36Sopenharmony_ci * will have a size of CAAM_QI_MEMCACHE_SIZE, which should be sufficient for
11162306a36Sopenharmony_ci * hosting 16 SG entries.
11262306a36Sopenharmony_ci *
11362306a36Sopenharmony_ci * @flags - flags that would be used for the equivalent kmalloc(..) call
11462306a36Sopenharmony_ci *
11562306a36Sopenharmony_ci * Returns a pointer to a retrieved buffer on success or NULL on failure.
11662306a36Sopenharmony_ci */
11762306a36Sopenharmony_cistatic inline void *qi_cache_zalloc(gfp_t flags)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	return kmem_cache_zalloc(qi_cache, flags);
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/*
12362306a36Sopenharmony_ci * qi_cache_free - Frees buffers allocated from CAAM-QI cache
12462306a36Sopenharmony_ci *
12562306a36Sopenharmony_ci * @obj - buffer previously allocated by qi_cache_zalloc
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * No checking is being done, the call is a passthrough call to
12862306a36Sopenharmony_ci * kmem_cache_free(...)
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_cistatic inline void qi_cache_free(void *obj)
13162306a36Sopenharmony_ci{
13262306a36Sopenharmony_ci	kmem_cache_free(qi_cache, obj);
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic struct caam_request *to_caam_req(struct crypto_async_request *areq)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	switch (crypto_tfm_alg_type(areq->tfm)) {
13862306a36Sopenharmony_ci	case CRYPTO_ALG_TYPE_SKCIPHER:
13962306a36Sopenharmony_ci		return skcipher_request_ctx_dma(skcipher_request_cast(areq));
14062306a36Sopenharmony_ci	case CRYPTO_ALG_TYPE_AEAD:
14162306a36Sopenharmony_ci		return aead_request_ctx_dma(
14262306a36Sopenharmony_ci			container_of(areq, struct aead_request, base));
14362306a36Sopenharmony_ci	case CRYPTO_ALG_TYPE_AHASH:
14462306a36Sopenharmony_ci		return ahash_request_ctx_dma(ahash_request_cast(areq));
14562306a36Sopenharmony_ci	default:
14662306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
14762306a36Sopenharmony_ci	}
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic void caam_unmap(struct device *dev, struct scatterlist *src,
15162306a36Sopenharmony_ci		       struct scatterlist *dst, int src_nents,
15262306a36Sopenharmony_ci		       int dst_nents, dma_addr_t iv_dma, int ivsize,
15362306a36Sopenharmony_ci		       enum dma_data_direction iv_dir, dma_addr_t qm_sg_dma,
15462306a36Sopenharmony_ci		       int qm_sg_bytes)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	if (dst != src) {
15762306a36Sopenharmony_ci		if (src_nents)
15862306a36Sopenharmony_ci			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
15962306a36Sopenharmony_ci		if (dst_nents)
16062306a36Sopenharmony_ci			dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
16162306a36Sopenharmony_ci	} else {
16262306a36Sopenharmony_ci		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
16362306a36Sopenharmony_ci	}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	if (iv_dma)
16662306a36Sopenharmony_ci		dma_unmap_single(dev, iv_dma, ivsize, iv_dir);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	if (qm_sg_bytes)
16962306a36Sopenharmony_ci		dma_unmap_single(dev, qm_sg_dma, qm_sg_bytes, DMA_TO_DEVICE);
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic int aead_set_sh_desc(struct crypto_aead *aead)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
17562306a36Sopenharmony_ci						 typeof(*alg), aead);
17662306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
17762306a36Sopenharmony_ci	unsigned int ivsize = crypto_aead_ivsize(aead);
17862306a36Sopenharmony_ci	struct device *dev = ctx->dev;
17962306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
18062306a36Sopenharmony_ci	struct caam_flc *flc;
18162306a36Sopenharmony_ci	u32 *desc;
18262306a36Sopenharmony_ci	u32 ctx1_iv_off = 0;
18362306a36Sopenharmony_ci	u32 *nonce = NULL;
18462306a36Sopenharmony_ci	unsigned int data_len[2];
18562306a36Sopenharmony_ci	u32 inl_mask;
18662306a36Sopenharmony_ci	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
18762306a36Sopenharmony_ci			       OP_ALG_AAI_CTR_MOD128);
18862306a36Sopenharmony_ci	const bool is_rfc3686 = alg->caam.rfc3686;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	if (!ctx->cdata.keylen || !ctx->authsize)
19162306a36Sopenharmony_ci		return 0;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	/*
19462306a36Sopenharmony_ci	 * AES-CTR needs to load IV in CONTEXT1 reg
19562306a36Sopenharmony_ci	 * at an offset of 128bits (16bytes)
19662306a36Sopenharmony_ci	 * CONTEXT1[255:128] = IV
19762306a36Sopenharmony_ci	 */
19862306a36Sopenharmony_ci	if (ctr_mode)
19962306a36Sopenharmony_ci		ctx1_iv_off = 16;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	/*
20262306a36Sopenharmony_ci	 * RFC3686 specific:
20362306a36Sopenharmony_ci	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
20462306a36Sopenharmony_ci	 */
20562306a36Sopenharmony_ci	if (is_rfc3686) {
20662306a36Sopenharmony_ci		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
20762306a36Sopenharmony_ci		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
20862306a36Sopenharmony_ci				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
20962306a36Sopenharmony_ci	}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	/*
21262306a36Sopenharmony_ci	 * In case |user key| > |derived key|, using DKP<imm,imm> would result
21362306a36Sopenharmony_ci	 * in invalid opcodes (last bytes of user key) in the resulting
21462306a36Sopenharmony_ci	 * descriptor. Use DKP<ptr,imm> instead => both virtual and dma key
21562306a36Sopenharmony_ci	 * addresses are needed.
21662306a36Sopenharmony_ci	 */
21762306a36Sopenharmony_ci	ctx->adata.key_virt = ctx->key;
21862306a36Sopenharmony_ci	ctx->adata.key_dma = ctx->key_dma;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
22162306a36Sopenharmony_ci	ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	data_len[0] = ctx->adata.keylen_pad;
22462306a36Sopenharmony_ci	data_len[1] = ctx->cdata.keylen;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	/* aead_encrypt shared descriptor */
22762306a36Sopenharmony_ci	if (desc_inline_query((alg->caam.geniv ? DESC_QI_AEAD_GIVENC_LEN :
22862306a36Sopenharmony_ci						 DESC_QI_AEAD_ENC_LEN) +
22962306a36Sopenharmony_ci			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
23062306a36Sopenharmony_ci			      DESC_JOB_IO_LEN, data_len, &inl_mask,
23162306a36Sopenharmony_ci			      ARRAY_SIZE(data_len)) < 0)
23262306a36Sopenharmony_ci		return -EINVAL;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	ctx->adata.key_inline = !!(inl_mask & 1);
23562306a36Sopenharmony_ci	ctx->cdata.key_inline = !!(inl_mask & 2);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
23862306a36Sopenharmony_ci	desc = flc->sh_desc;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	if (alg->caam.geniv)
24162306a36Sopenharmony_ci		cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata,
24262306a36Sopenharmony_ci					  ivsize, ctx->authsize, is_rfc3686,
24362306a36Sopenharmony_ci					  nonce, ctx1_iv_off, true,
24462306a36Sopenharmony_ci					  priv->sec_attr.era);
24562306a36Sopenharmony_ci	else
24662306a36Sopenharmony_ci		cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata,
24762306a36Sopenharmony_ci				       ivsize, ctx->authsize, is_rfc3686, nonce,
24862306a36Sopenharmony_ci				       ctx1_iv_off, true, priv->sec_attr.era);
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
25162306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
25262306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
25362306a36Sopenharmony_ci				   ctx->dir);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	/* aead_decrypt shared descriptor */
25662306a36Sopenharmony_ci	if (desc_inline_query(DESC_QI_AEAD_DEC_LEN +
25762306a36Sopenharmony_ci			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
25862306a36Sopenharmony_ci			      DESC_JOB_IO_LEN, data_len, &inl_mask,
25962306a36Sopenharmony_ci			      ARRAY_SIZE(data_len)) < 0)
26062306a36Sopenharmony_ci		return -EINVAL;
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	ctx->adata.key_inline = !!(inl_mask & 1);
26362306a36Sopenharmony_ci	ctx->cdata.key_inline = !!(inl_mask & 2);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
26662306a36Sopenharmony_ci	desc = flc->sh_desc;
26762306a36Sopenharmony_ci	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata,
26862306a36Sopenharmony_ci			       ivsize, ctx->authsize, alg->caam.geniv,
26962306a36Sopenharmony_ci			       is_rfc3686, nonce, ctx1_iv_off, true,
27062306a36Sopenharmony_ci			       priv->sec_attr.era);
27162306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
27262306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
27362306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
27462306a36Sopenharmony_ci				   ctx->dir);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	return 0;
27762306a36Sopenharmony_ci}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_cistatic int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
28062306a36Sopenharmony_ci{
28162306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	ctx->authsize = authsize;
28462306a36Sopenharmony_ci	aead_set_sh_desc(authenc);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	return 0;
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistatic int aead_setkey(struct crypto_aead *aead, const u8 *key,
29062306a36Sopenharmony_ci		       unsigned int keylen)
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
29362306a36Sopenharmony_ci	struct device *dev = ctx->dev;
29462306a36Sopenharmony_ci	struct crypto_authenc_keys keys;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
29762306a36Sopenharmony_ci		goto badkey;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	dev_dbg(dev, "keylen %d enckeylen %d authkeylen %d\n",
30062306a36Sopenharmony_ci		keys.authkeylen + keys.enckeylen, keys.enckeylen,
30162306a36Sopenharmony_ci		keys.authkeylen);
30262306a36Sopenharmony_ci	print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
30362306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	ctx->adata.keylen = keys.authkeylen;
30662306a36Sopenharmony_ci	ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
30762306a36Sopenharmony_ci					      OP_ALG_ALGSEL_MASK);
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
31062306a36Sopenharmony_ci		goto badkey;
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	memcpy(ctx->key, keys.authkey, keys.authkeylen);
31362306a36Sopenharmony_ci	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
31462306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->key_dma, ctx->adata.keylen_pad +
31562306a36Sopenharmony_ci				   keys.enckeylen, ctx->dir);
31662306a36Sopenharmony_ci	print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ",
31762306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
31862306a36Sopenharmony_ci			     ctx->adata.keylen_pad + keys.enckeylen, 1);
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	ctx->cdata.keylen = keys.enckeylen;
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	memzero_explicit(&keys, sizeof(keys));
32362306a36Sopenharmony_ci	return aead_set_sh_desc(aead);
32462306a36Sopenharmony_cibadkey:
32562306a36Sopenharmony_ci	memzero_explicit(&keys, sizeof(keys));
32662306a36Sopenharmony_ci	return -EINVAL;
32762306a36Sopenharmony_ci}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_cistatic int des3_aead_setkey(struct crypto_aead *aead, const u8 *key,
33062306a36Sopenharmony_ci			    unsigned int keylen)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	struct crypto_authenc_keys keys;
33362306a36Sopenharmony_ci	int err;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	err = crypto_authenc_extractkeys(&keys, key, keylen);
33662306a36Sopenharmony_ci	if (unlikely(err))
33762306a36Sopenharmony_ci		goto out;
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	err = -EINVAL;
34062306a36Sopenharmony_ci	if (keys.enckeylen != DES3_EDE_KEY_SIZE)
34162306a36Sopenharmony_ci		goto out;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	err = crypto_des3_ede_verify_key(crypto_aead_tfm(aead), keys.enckey) ?:
34462306a36Sopenharmony_ci	      aead_setkey(aead, key, keylen);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ciout:
34762306a36Sopenharmony_ci	memzero_explicit(&keys, sizeof(keys));
34862306a36Sopenharmony_ci	return err;
34962306a36Sopenharmony_ci}
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
35262306a36Sopenharmony_ci					   bool encrypt)
35362306a36Sopenharmony_ci{
35462306a36Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
35562306a36Sopenharmony_ci	struct caam_request *req_ctx = aead_request_ctx_dma(req);
35662306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
35762306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
35862306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
35962306a36Sopenharmony_ci	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
36062306a36Sopenharmony_ci						 typeof(*alg), aead);
36162306a36Sopenharmony_ci	struct device *dev = ctx->dev;
36262306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
36362306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
36462306a36Sopenharmony_ci	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
36562306a36Sopenharmony_ci	int src_len, dst_len = 0;
36662306a36Sopenharmony_ci	struct aead_edesc *edesc;
36762306a36Sopenharmony_ci	dma_addr_t qm_sg_dma, iv_dma = 0;
36862306a36Sopenharmony_ci	int ivsize = 0;
36962306a36Sopenharmony_ci	unsigned int authsize = ctx->authsize;
37062306a36Sopenharmony_ci	int qm_sg_index = 0, qm_sg_nents = 0, qm_sg_bytes;
37162306a36Sopenharmony_ci	int in_len, out_len;
37262306a36Sopenharmony_ci	struct dpaa2_sg_entry *sg_table;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	/* allocate space for base edesc, link tables and IV */
37562306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
37662306a36Sopenharmony_ci	if (unlikely(!edesc)) {
37762306a36Sopenharmony_ci		dev_err(dev, "could not allocate extended descriptor\n");
37862306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
37962306a36Sopenharmony_ci	}
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	if (unlikely(req->dst != req->src)) {
38262306a36Sopenharmony_ci		src_len = req->assoclen + req->cryptlen;
38362306a36Sopenharmony_ci		dst_len = src_len + (encrypt ? authsize : (-authsize));
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci		src_nents = sg_nents_for_len(req->src, src_len);
38662306a36Sopenharmony_ci		if (unlikely(src_nents < 0)) {
38762306a36Sopenharmony_ci			dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
38862306a36Sopenharmony_ci				src_len);
38962306a36Sopenharmony_ci			qi_cache_free(edesc);
39062306a36Sopenharmony_ci			return ERR_PTR(src_nents);
39162306a36Sopenharmony_ci		}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci		dst_nents = sg_nents_for_len(req->dst, dst_len);
39462306a36Sopenharmony_ci		if (unlikely(dst_nents < 0)) {
39562306a36Sopenharmony_ci			dev_err(dev, "Insufficient bytes (%d) in dst S/G\n",
39662306a36Sopenharmony_ci				dst_len);
39762306a36Sopenharmony_ci			qi_cache_free(edesc);
39862306a36Sopenharmony_ci			return ERR_PTR(dst_nents);
39962306a36Sopenharmony_ci		}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci		if (src_nents) {
40262306a36Sopenharmony_ci			mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
40362306a36Sopenharmony_ci						      DMA_TO_DEVICE);
40462306a36Sopenharmony_ci			if (unlikely(!mapped_src_nents)) {
40562306a36Sopenharmony_ci				dev_err(dev, "unable to map source\n");
40662306a36Sopenharmony_ci				qi_cache_free(edesc);
40762306a36Sopenharmony_ci				return ERR_PTR(-ENOMEM);
40862306a36Sopenharmony_ci			}
40962306a36Sopenharmony_ci		} else {
41062306a36Sopenharmony_ci			mapped_src_nents = 0;
41162306a36Sopenharmony_ci		}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci		if (dst_nents) {
41462306a36Sopenharmony_ci			mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents,
41562306a36Sopenharmony_ci						      DMA_FROM_DEVICE);
41662306a36Sopenharmony_ci			if (unlikely(!mapped_dst_nents)) {
41762306a36Sopenharmony_ci				dev_err(dev, "unable to map destination\n");
41862306a36Sopenharmony_ci				dma_unmap_sg(dev, req->src, src_nents,
41962306a36Sopenharmony_ci					     DMA_TO_DEVICE);
42062306a36Sopenharmony_ci				qi_cache_free(edesc);
42162306a36Sopenharmony_ci				return ERR_PTR(-ENOMEM);
42262306a36Sopenharmony_ci			}
42362306a36Sopenharmony_ci		} else {
42462306a36Sopenharmony_ci			mapped_dst_nents = 0;
42562306a36Sopenharmony_ci		}
42662306a36Sopenharmony_ci	} else {
42762306a36Sopenharmony_ci		src_len = req->assoclen + req->cryptlen +
42862306a36Sopenharmony_ci			  (encrypt ? authsize : 0);
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci		src_nents = sg_nents_for_len(req->src, src_len);
43162306a36Sopenharmony_ci		if (unlikely(src_nents < 0)) {
43262306a36Sopenharmony_ci			dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
43362306a36Sopenharmony_ci				src_len);
43462306a36Sopenharmony_ci			qi_cache_free(edesc);
43562306a36Sopenharmony_ci			return ERR_PTR(src_nents);
43662306a36Sopenharmony_ci		}
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci		mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
43962306a36Sopenharmony_ci					      DMA_BIDIRECTIONAL);
44062306a36Sopenharmony_ci		if (unlikely(!mapped_src_nents)) {
44162306a36Sopenharmony_ci			dev_err(dev, "unable to map source\n");
44262306a36Sopenharmony_ci			qi_cache_free(edesc);
44362306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
44462306a36Sopenharmony_ci		}
44562306a36Sopenharmony_ci	}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	if ((alg->caam.rfc3686 && encrypt) || !alg->caam.geniv)
44862306a36Sopenharmony_ci		ivsize = crypto_aead_ivsize(aead);
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	/*
45162306a36Sopenharmony_ci	 * Create S/G table: req->assoclen, [IV,] req->src [, req->dst].
45262306a36Sopenharmony_ci	 * Input is not contiguous.
45362306a36Sopenharmony_ci	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
45462306a36Sopenharmony_ci	 * the end of the table by allocating more S/G entries. Logic:
45562306a36Sopenharmony_ci	 * if (src != dst && output S/G)
45662306a36Sopenharmony_ci	 *      pad output S/G, if needed
45762306a36Sopenharmony_ci	 * else if (src == dst && S/G)
45862306a36Sopenharmony_ci	 *      overlapping S/Gs; pad one of them
45962306a36Sopenharmony_ci	 * else if (input S/G) ...
46062306a36Sopenharmony_ci	 *      pad input S/G, if needed
46162306a36Sopenharmony_ci	 */
46262306a36Sopenharmony_ci	qm_sg_nents = 1 + !!ivsize + mapped_src_nents;
46362306a36Sopenharmony_ci	if (mapped_dst_nents > 1)
46462306a36Sopenharmony_ci		qm_sg_nents += pad_sg_nents(mapped_dst_nents);
46562306a36Sopenharmony_ci	else if ((req->src == req->dst) && (mapped_src_nents > 1))
46662306a36Sopenharmony_ci		qm_sg_nents = max(pad_sg_nents(qm_sg_nents),
46762306a36Sopenharmony_ci				  1 + !!ivsize +
46862306a36Sopenharmony_ci				  pad_sg_nents(mapped_src_nents));
46962306a36Sopenharmony_ci	else
47062306a36Sopenharmony_ci		qm_sg_nents = pad_sg_nents(qm_sg_nents);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	sg_table = &edesc->sgt[0];
47362306a36Sopenharmony_ci	qm_sg_bytes = qm_sg_nents * sizeof(*sg_table);
47462306a36Sopenharmony_ci	if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize >
47562306a36Sopenharmony_ci		     CAAM_QI_MEMCACHE_SIZE)) {
47662306a36Sopenharmony_ci		dev_err(dev, "No space for %d S/G entries and/or %dB IV\n",
47762306a36Sopenharmony_ci			qm_sg_nents, ivsize);
47862306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
47962306a36Sopenharmony_ci			   0, DMA_NONE, 0, 0);
48062306a36Sopenharmony_ci		qi_cache_free(edesc);
48162306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
48262306a36Sopenharmony_ci	}
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	if (ivsize) {
48562306a36Sopenharmony_ci		u8 *iv = (u8 *)(sg_table + qm_sg_nents);
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci		/* Make sure IV is located in a DMAable area */
48862306a36Sopenharmony_ci		memcpy(iv, req->iv, ivsize);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci		iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
49162306a36Sopenharmony_ci		if (dma_mapping_error(dev, iv_dma)) {
49262306a36Sopenharmony_ci			dev_err(dev, "unable to map IV\n");
49362306a36Sopenharmony_ci			caam_unmap(dev, req->src, req->dst, src_nents,
49462306a36Sopenharmony_ci				   dst_nents, 0, 0, DMA_NONE, 0, 0);
49562306a36Sopenharmony_ci			qi_cache_free(edesc);
49662306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
49762306a36Sopenharmony_ci		}
49862306a36Sopenharmony_ci	}
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	edesc->src_nents = src_nents;
50162306a36Sopenharmony_ci	edesc->dst_nents = dst_nents;
50262306a36Sopenharmony_ci	edesc->iv_dma = iv_dma;
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci	if ((alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK) ==
50562306a36Sopenharmony_ci	    OP_ALG_ALGSEL_CHACHA20 && ivsize != CHACHAPOLY_IV_SIZE)
50662306a36Sopenharmony_ci		/*
50762306a36Sopenharmony_ci		 * The associated data comes already with the IV but we need
50862306a36Sopenharmony_ci		 * to skip it when we authenticate or encrypt...
50962306a36Sopenharmony_ci		 */
51062306a36Sopenharmony_ci		edesc->assoclen = cpu_to_caam32(req->assoclen - ivsize);
51162306a36Sopenharmony_ci	else
51262306a36Sopenharmony_ci		edesc->assoclen = cpu_to_caam32(req->assoclen);
51362306a36Sopenharmony_ci	edesc->assoclen_dma = dma_map_single(dev, &edesc->assoclen, 4,
51462306a36Sopenharmony_ci					     DMA_TO_DEVICE);
51562306a36Sopenharmony_ci	if (dma_mapping_error(dev, edesc->assoclen_dma)) {
51662306a36Sopenharmony_ci		dev_err(dev, "unable to map assoclen\n");
51762306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents,
51862306a36Sopenharmony_ci			   iv_dma, ivsize, DMA_TO_DEVICE, 0, 0);
51962306a36Sopenharmony_ci		qi_cache_free(edesc);
52062306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
52162306a36Sopenharmony_ci	}
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	dma_to_qm_sg_one(sg_table, edesc->assoclen_dma, 4, 0);
52462306a36Sopenharmony_ci	qm_sg_index++;
52562306a36Sopenharmony_ci	if (ivsize) {
52662306a36Sopenharmony_ci		dma_to_qm_sg_one(sg_table + qm_sg_index, iv_dma, ivsize, 0);
52762306a36Sopenharmony_ci		qm_sg_index++;
52862306a36Sopenharmony_ci	}
52962306a36Sopenharmony_ci	sg_to_qm_sg_last(req->src, src_len, sg_table + qm_sg_index, 0);
53062306a36Sopenharmony_ci	qm_sg_index += mapped_src_nents;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci	if (mapped_dst_nents > 1)
53362306a36Sopenharmony_ci		sg_to_qm_sg_last(req->dst, dst_len, sg_table + qm_sg_index, 0);
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	qm_sg_dma = dma_map_single(dev, sg_table, qm_sg_bytes, DMA_TO_DEVICE);
53662306a36Sopenharmony_ci	if (dma_mapping_error(dev, qm_sg_dma)) {
53762306a36Sopenharmony_ci		dev_err(dev, "unable to map S/G table\n");
53862306a36Sopenharmony_ci		dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
53962306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents,
54062306a36Sopenharmony_ci			   iv_dma, ivsize, DMA_TO_DEVICE, 0, 0);
54162306a36Sopenharmony_ci		qi_cache_free(edesc);
54262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
54362306a36Sopenharmony_ci	}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	edesc->qm_sg_dma = qm_sg_dma;
54662306a36Sopenharmony_ci	edesc->qm_sg_bytes = qm_sg_bytes;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	out_len = req->assoclen + req->cryptlen +
54962306a36Sopenharmony_ci		  (encrypt ? ctx->authsize : (-ctx->authsize));
55062306a36Sopenharmony_ci	in_len = 4 + ivsize + req->assoclen + req->cryptlen;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
55362306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
55462306a36Sopenharmony_ci	dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
55562306a36Sopenharmony_ci	dpaa2_fl_set_addr(in_fle, qm_sg_dma);
55662306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, in_len);
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	if (req->dst == req->src) {
55962306a36Sopenharmony_ci		if (mapped_src_nents == 1) {
56062306a36Sopenharmony_ci			dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
56162306a36Sopenharmony_ci			dpaa2_fl_set_addr(out_fle, sg_dma_address(req->src));
56262306a36Sopenharmony_ci		} else {
56362306a36Sopenharmony_ci			dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
56462306a36Sopenharmony_ci			dpaa2_fl_set_addr(out_fle, qm_sg_dma +
56562306a36Sopenharmony_ci					  (1 + !!ivsize) * sizeof(*sg_table));
56662306a36Sopenharmony_ci		}
56762306a36Sopenharmony_ci	} else if (!mapped_dst_nents) {
56862306a36Sopenharmony_ci		/*
56962306a36Sopenharmony_ci		 * crypto engine requires the output entry to be present when
57062306a36Sopenharmony_ci		 * "frame list" FD is used.
57162306a36Sopenharmony_ci		 * Since engine does not support FMT=2'b11 (unused entry type),
57262306a36Sopenharmony_ci		 * leaving out_fle zeroized is the best option.
57362306a36Sopenharmony_ci		 */
57462306a36Sopenharmony_ci		goto skip_out_fle;
57562306a36Sopenharmony_ci	} else if (mapped_dst_nents == 1) {
57662306a36Sopenharmony_ci		dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
57762306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, sg_dma_address(req->dst));
57862306a36Sopenharmony_ci	} else {
57962306a36Sopenharmony_ci		dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
58062306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, qm_sg_dma + qm_sg_index *
58162306a36Sopenharmony_ci				  sizeof(*sg_table));
58262306a36Sopenharmony_ci	}
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, out_len);
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ciskip_out_fle:
58762306a36Sopenharmony_ci	return edesc;
58862306a36Sopenharmony_ci}
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_cistatic int chachapoly_set_sh_desc(struct crypto_aead *aead)
59162306a36Sopenharmony_ci{
59262306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
59362306a36Sopenharmony_ci	unsigned int ivsize = crypto_aead_ivsize(aead);
59462306a36Sopenharmony_ci	struct device *dev = ctx->dev;
59562306a36Sopenharmony_ci	struct caam_flc *flc;
59662306a36Sopenharmony_ci	u32 *desc;
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci	if (!ctx->cdata.keylen || !ctx->authsize)
59962306a36Sopenharmony_ci		return 0;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
60262306a36Sopenharmony_ci	desc = flc->sh_desc;
60362306a36Sopenharmony_ci	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
60462306a36Sopenharmony_ci			       ctx->authsize, true, true);
60562306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
60662306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
60762306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
60862306a36Sopenharmony_ci				   ctx->dir);
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
61162306a36Sopenharmony_ci	desc = flc->sh_desc;
61262306a36Sopenharmony_ci	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
61362306a36Sopenharmony_ci			       ctx->authsize, false, true);
61462306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
61562306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
61662306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
61762306a36Sopenharmony_ci				   ctx->dir);
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	return 0;
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_cistatic int chachapoly_setauthsize(struct crypto_aead *aead,
62362306a36Sopenharmony_ci				  unsigned int authsize)
62462306a36Sopenharmony_ci{
62562306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	if (authsize != POLY1305_DIGEST_SIZE)
62862306a36Sopenharmony_ci		return -EINVAL;
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	ctx->authsize = authsize;
63162306a36Sopenharmony_ci	return chachapoly_set_sh_desc(aead);
63262306a36Sopenharmony_ci}
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_cistatic int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
63562306a36Sopenharmony_ci			     unsigned int keylen)
63662306a36Sopenharmony_ci{
63762306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
63862306a36Sopenharmony_ci	unsigned int ivsize = crypto_aead_ivsize(aead);
63962306a36Sopenharmony_ci	unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	if (keylen != CHACHA_KEY_SIZE + saltlen)
64262306a36Sopenharmony_ci		return -EINVAL;
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	memcpy(ctx->key, key, keylen);
64562306a36Sopenharmony_ci	ctx->cdata.key_virt = ctx->key;
64662306a36Sopenharmony_ci	ctx->cdata.keylen = keylen - saltlen;
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	return chachapoly_set_sh_desc(aead);
64962306a36Sopenharmony_ci}
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_cistatic int gcm_set_sh_desc(struct crypto_aead *aead)
65262306a36Sopenharmony_ci{
65362306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
65462306a36Sopenharmony_ci	struct device *dev = ctx->dev;
65562306a36Sopenharmony_ci	unsigned int ivsize = crypto_aead_ivsize(aead);
65662306a36Sopenharmony_ci	struct caam_flc *flc;
65762306a36Sopenharmony_ci	u32 *desc;
65862306a36Sopenharmony_ci	int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
65962306a36Sopenharmony_ci			ctx->cdata.keylen;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	if (!ctx->cdata.keylen || !ctx->authsize)
66262306a36Sopenharmony_ci		return 0;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	/*
66562306a36Sopenharmony_ci	 * AES GCM encrypt shared descriptor
66662306a36Sopenharmony_ci	 * Job Descriptor and Shared Descriptor
66762306a36Sopenharmony_ci	 * must fit into the 64-word Descriptor h/w Buffer
66862306a36Sopenharmony_ci	 */
66962306a36Sopenharmony_ci	if (rem_bytes >= DESC_QI_GCM_ENC_LEN) {
67062306a36Sopenharmony_ci		ctx->cdata.key_inline = true;
67162306a36Sopenharmony_ci		ctx->cdata.key_virt = ctx->key;
67262306a36Sopenharmony_ci	} else {
67362306a36Sopenharmony_ci		ctx->cdata.key_inline = false;
67462306a36Sopenharmony_ci		ctx->cdata.key_dma = ctx->key_dma;
67562306a36Sopenharmony_ci	}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
67862306a36Sopenharmony_ci	desc = flc->sh_desc;
67962306a36Sopenharmony_ci	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, true);
68062306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
68162306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
68262306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
68362306a36Sopenharmony_ci				   ctx->dir);
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci	/*
68662306a36Sopenharmony_ci	 * Job Descriptor and Shared Descriptors
68762306a36Sopenharmony_ci	 * must all fit into the 64-word Descriptor h/w Buffer
68862306a36Sopenharmony_ci	 */
68962306a36Sopenharmony_ci	if (rem_bytes >= DESC_QI_GCM_DEC_LEN) {
69062306a36Sopenharmony_ci		ctx->cdata.key_inline = true;
69162306a36Sopenharmony_ci		ctx->cdata.key_virt = ctx->key;
69262306a36Sopenharmony_ci	} else {
69362306a36Sopenharmony_ci		ctx->cdata.key_inline = false;
69462306a36Sopenharmony_ci		ctx->cdata.key_dma = ctx->key_dma;
69562306a36Sopenharmony_ci	}
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
69862306a36Sopenharmony_ci	desc = flc->sh_desc;
69962306a36Sopenharmony_ci	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, true);
70062306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
70162306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
70262306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
70362306a36Sopenharmony_ci				   ctx->dir);
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	return 0;
70662306a36Sopenharmony_ci}
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_cistatic int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
70962306a36Sopenharmony_ci{
71062306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
71162306a36Sopenharmony_ci	int err;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	err = crypto_gcm_check_authsize(authsize);
71462306a36Sopenharmony_ci	if (err)
71562306a36Sopenharmony_ci		return err;
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	ctx->authsize = authsize;
71862306a36Sopenharmony_ci	gcm_set_sh_desc(authenc);
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	return 0;
72162306a36Sopenharmony_ci}
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_cistatic int gcm_setkey(struct crypto_aead *aead,
72462306a36Sopenharmony_ci		      const u8 *key, unsigned int keylen)
72562306a36Sopenharmony_ci{
72662306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
72762306a36Sopenharmony_ci	struct device *dev = ctx->dev;
72862306a36Sopenharmony_ci	int ret;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	ret = aes_check_keylen(keylen);
73162306a36Sopenharmony_ci	if (ret)
73262306a36Sopenharmony_ci		return ret;
73362306a36Sopenharmony_ci	print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
73462306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	memcpy(ctx->key, key, keylen);
73762306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->key_dma, keylen, ctx->dir);
73862306a36Sopenharmony_ci	ctx->cdata.keylen = keylen;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	return gcm_set_sh_desc(aead);
74162306a36Sopenharmony_ci}
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_cistatic int rfc4106_set_sh_desc(struct crypto_aead *aead)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
74662306a36Sopenharmony_ci	struct device *dev = ctx->dev;
74762306a36Sopenharmony_ci	unsigned int ivsize = crypto_aead_ivsize(aead);
74862306a36Sopenharmony_ci	struct caam_flc *flc;
74962306a36Sopenharmony_ci	u32 *desc;
75062306a36Sopenharmony_ci	int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
75162306a36Sopenharmony_ci			ctx->cdata.keylen;
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci	if (!ctx->cdata.keylen || !ctx->authsize)
75462306a36Sopenharmony_ci		return 0;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	ctx->cdata.key_virt = ctx->key;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	/*
75962306a36Sopenharmony_ci	 * RFC4106 encrypt shared descriptor
76062306a36Sopenharmony_ci	 * Job Descriptor and Shared Descriptor
76162306a36Sopenharmony_ci	 * must fit into the 64-word Descriptor h/w Buffer
76262306a36Sopenharmony_ci	 */
76362306a36Sopenharmony_ci	if (rem_bytes >= DESC_QI_RFC4106_ENC_LEN) {
76462306a36Sopenharmony_ci		ctx->cdata.key_inline = true;
76562306a36Sopenharmony_ci	} else {
76662306a36Sopenharmony_ci		ctx->cdata.key_inline = false;
76762306a36Sopenharmony_ci		ctx->cdata.key_dma = ctx->key_dma;
76862306a36Sopenharmony_ci	}
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
77162306a36Sopenharmony_ci	desc = flc->sh_desc;
77262306a36Sopenharmony_ci	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
77362306a36Sopenharmony_ci				  true);
77462306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
77562306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
77662306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
77762306a36Sopenharmony_ci				   ctx->dir);
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci	/*
78062306a36Sopenharmony_ci	 * Job Descriptor and Shared Descriptors
78162306a36Sopenharmony_ci	 * must all fit into the 64-word Descriptor h/w Buffer
78262306a36Sopenharmony_ci	 */
78362306a36Sopenharmony_ci	if (rem_bytes >= DESC_QI_RFC4106_DEC_LEN) {
78462306a36Sopenharmony_ci		ctx->cdata.key_inline = true;
78562306a36Sopenharmony_ci	} else {
78662306a36Sopenharmony_ci		ctx->cdata.key_inline = false;
78762306a36Sopenharmony_ci		ctx->cdata.key_dma = ctx->key_dma;
78862306a36Sopenharmony_ci	}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
79162306a36Sopenharmony_ci	desc = flc->sh_desc;
79262306a36Sopenharmony_ci	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
79362306a36Sopenharmony_ci				  true);
79462306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
79562306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
79662306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
79762306a36Sopenharmony_ci				   ctx->dir);
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	return 0;
80062306a36Sopenharmony_ci}
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_cistatic int rfc4106_setauthsize(struct crypto_aead *authenc,
80362306a36Sopenharmony_ci			       unsigned int authsize)
80462306a36Sopenharmony_ci{
80562306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
80662306a36Sopenharmony_ci	int err;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	err = crypto_rfc4106_check_authsize(authsize);
80962306a36Sopenharmony_ci	if (err)
81062306a36Sopenharmony_ci		return err;
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	ctx->authsize = authsize;
81362306a36Sopenharmony_ci	rfc4106_set_sh_desc(authenc);
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	return 0;
81662306a36Sopenharmony_ci}
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_cistatic int rfc4106_setkey(struct crypto_aead *aead,
81962306a36Sopenharmony_ci			  const u8 *key, unsigned int keylen)
82062306a36Sopenharmony_ci{
82162306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
82262306a36Sopenharmony_ci	struct device *dev = ctx->dev;
82362306a36Sopenharmony_ci	int ret;
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	ret = aes_check_keylen(keylen - 4);
82662306a36Sopenharmony_ci	if (ret)
82762306a36Sopenharmony_ci		return ret;
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci	print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
83062306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci	memcpy(ctx->key, key, keylen);
83362306a36Sopenharmony_ci	/*
83462306a36Sopenharmony_ci	 * The last four bytes of the key material are used as the salt value
83562306a36Sopenharmony_ci	 * in the nonce. Update the AES key length.
83662306a36Sopenharmony_ci	 */
83762306a36Sopenharmony_ci	ctx->cdata.keylen = keylen - 4;
83862306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->key_dma, ctx->cdata.keylen,
83962306a36Sopenharmony_ci				   ctx->dir);
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	return rfc4106_set_sh_desc(aead);
84262306a36Sopenharmony_ci}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_cistatic int rfc4543_set_sh_desc(struct crypto_aead *aead)
84562306a36Sopenharmony_ci{
84662306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
84762306a36Sopenharmony_ci	struct device *dev = ctx->dev;
84862306a36Sopenharmony_ci	unsigned int ivsize = crypto_aead_ivsize(aead);
84962306a36Sopenharmony_ci	struct caam_flc *flc;
85062306a36Sopenharmony_ci	u32 *desc;
85162306a36Sopenharmony_ci	int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
85262306a36Sopenharmony_ci			ctx->cdata.keylen;
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci	if (!ctx->cdata.keylen || !ctx->authsize)
85562306a36Sopenharmony_ci		return 0;
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci	ctx->cdata.key_virt = ctx->key;
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	/*
86062306a36Sopenharmony_ci	 * RFC4543 encrypt shared descriptor
86162306a36Sopenharmony_ci	 * Job Descriptor and Shared Descriptor
86262306a36Sopenharmony_ci	 * must fit into the 64-word Descriptor h/w Buffer
86362306a36Sopenharmony_ci	 */
86462306a36Sopenharmony_ci	if (rem_bytes >= DESC_QI_RFC4543_ENC_LEN) {
86562306a36Sopenharmony_ci		ctx->cdata.key_inline = true;
86662306a36Sopenharmony_ci	} else {
86762306a36Sopenharmony_ci		ctx->cdata.key_inline = false;
86862306a36Sopenharmony_ci		ctx->cdata.key_dma = ctx->key_dma;
86962306a36Sopenharmony_ci	}
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
87262306a36Sopenharmony_ci	desc = flc->sh_desc;
87362306a36Sopenharmony_ci	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
87462306a36Sopenharmony_ci				  true);
87562306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
87662306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
87762306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
87862306a36Sopenharmony_ci				   ctx->dir);
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci	/*
88162306a36Sopenharmony_ci	 * Job Descriptor and Shared Descriptors
88262306a36Sopenharmony_ci	 * must all fit into the 64-word Descriptor h/w Buffer
88362306a36Sopenharmony_ci	 */
88462306a36Sopenharmony_ci	if (rem_bytes >= DESC_QI_RFC4543_DEC_LEN) {
88562306a36Sopenharmony_ci		ctx->cdata.key_inline = true;
88662306a36Sopenharmony_ci	} else {
88762306a36Sopenharmony_ci		ctx->cdata.key_inline = false;
88862306a36Sopenharmony_ci		ctx->cdata.key_dma = ctx->key_dma;
88962306a36Sopenharmony_ci	}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
89262306a36Sopenharmony_ci	desc = flc->sh_desc;
89362306a36Sopenharmony_ci	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
89462306a36Sopenharmony_ci				  true);
89562306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
89662306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
89762306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
89862306a36Sopenharmony_ci				   ctx->dir);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	return 0;
90162306a36Sopenharmony_ci}
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_cistatic int rfc4543_setauthsize(struct crypto_aead *authenc,
90462306a36Sopenharmony_ci			       unsigned int authsize)
90562306a36Sopenharmony_ci{
90662306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc);
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci	if (authsize != 16)
90962306a36Sopenharmony_ci		return -EINVAL;
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	ctx->authsize = authsize;
91262306a36Sopenharmony_ci	rfc4543_set_sh_desc(authenc);
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	return 0;
91562306a36Sopenharmony_ci}
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_cistatic int rfc4543_setkey(struct crypto_aead *aead,
91862306a36Sopenharmony_ci			  const u8 *key, unsigned int keylen)
91962306a36Sopenharmony_ci{
92062306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
92162306a36Sopenharmony_ci	struct device *dev = ctx->dev;
92262306a36Sopenharmony_ci	int ret;
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_ci	ret = aes_check_keylen(keylen - 4);
92562306a36Sopenharmony_ci	if (ret)
92662306a36Sopenharmony_ci		return ret;
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci	print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
92962306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_ci	memcpy(ctx->key, key, keylen);
93262306a36Sopenharmony_ci	/*
93362306a36Sopenharmony_ci	 * The last four bytes of the key material are used as the salt value
93462306a36Sopenharmony_ci	 * in the nonce. Update the AES key length.
93562306a36Sopenharmony_ci	 */
93662306a36Sopenharmony_ci	ctx->cdata.keylen = keylen - 4;
93762306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->key_dma, ctx->cdata.keylen,
93862306a36Sopenharmony_ci				   ctx->dir);
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_ci	return rfc4543_set_sh_desc(aead);
94162306a36Sopenharmony_ci}
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_cistatic int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
94462306a36Sopenharmony_ci			   unsigned int keylen, const u32 ctx1_iv_off)
94562306a36Sopenharmony_ci{
94662306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
94762306a36Sopenharmony_ci	struct caam_skcipher_alg *alg =
94862306a36Sopenharmony_ci		container_of(crypto_skcipher_alg(skcipher),
94962306a36Sopenharmony_ci			     struct caam_skcipher_alg, skcipher);
95062306a36Sopenharmony_ci	struct device *dev = ctx->dev;
95162306a36Sopenharmony_ci	struct caam_flc *flc;
95262306a36Sopenharmony_ci	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
95362306a36Sopenharmony_ci	u32 *desc;
95462306a36Sopenharmony_ci	const bool is_rfc3686 = alg->caam.rfc3686;
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
95762306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	ctx->cdata.keylen = keylen;
96062306a36Sopenharmony_ci	ctx->cdata.key_virt = key;
96162306a36Sopenharmony_ci	ctx->cdata.key_inline = true;
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci	/* skcipher_encrypt shared descriptor */
96462306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
96562306a36Sopenharmony_ci	desc = flc->sh_desc;
96662306a36Sopenharmony_ci	cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
96762306a36Sopenharmony_ci				   ctx1_iv_off);
96862306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
96962306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
97062306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
97162306a36Sopenharmony_ci				   ctx->dir);
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	/* skcipher_decrypt shared descriptor */
97462306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
97562306a36Sopenharmony_ci	desc = flc->sh_desc;
97662306a36Sopenharmony_ci	cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
97762306a36Sopenharmony_ci				   ctx1_iv_off);
97862306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
97962306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
98062306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
98162306a36Sopenharmony_ci				   ctx->dir);
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci	return 0;
98462306a36Sopenharmony_ci}
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_cistatic int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
98762306a36Sopenharmony_ci			       const u8 *key, unsigned int keylen)
98862306a36Sopenharmony_ci{
98962306a36Sopenharmony_ci	int err;
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	err = aes_check_keylen(keylen);
99262306a36Sopenharmony_ci	if (err)
99362306a36Sopenharmony_ci		return err;
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci	return skcipher_setkey(skcipher, key, keylen, 0);
99662306a36Sopenharmony_ci}
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_cistatic int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher,
99962306a36Sopenharmony_ci				   const u8 *key, unsigned int keylen)
100062306a36Sopenharmony_ci{
100162306a36Sopenharmony_ci	u32 ctx1_iv_off;
100262306a36Sopenharmony_ci	int err;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	/*
100562306a36Sopenharmony_ci	 * RFC3686 specific:
100662306a36Sopenharmony_ci	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
100762306a36Sopenharmony_ci	 *	| *key = {KEY, NONCE}
100862306a36Sopenharmony_ci	 */
100962306a36Sopenharmony_ci	ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
101062306a36Sopenharmony_ci	keylen -= CTR_RFC3686_NONCE_SIZE;
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	err = aes_check_keylen(keylen);
101362306a36Sopenharmony_ci	if (err)
101462306a36Sopenharmony_ci		return err;
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
101762306a36Sopenharmony_ci}
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_cistatic int ctr_skcipher_setkey(struct crypto_skcipher *skcipher,
102062306a36Sopenharmony_ci			       const u8 *key, unsigned int keylen)
102162306a36Sopenharmony_ci{
102262306a36Sopenharmony_ci	u32 ctx1_iv_off;
102362306a36Sopenharmony_ci	int err;
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci	/*
102662306a36Sopenharmony_ci	 * AES-CTR needs to load IV in CONTEXT1 reg
102762306a36Sopenharmony_ci	 * at an offset of 128bits (16bytes)
102862306a36Sopenharmony_ci	 * CONTEXT1[255:128] = IV
102962306a36Sopenharmony_ci	 */
103062306a36Sopenharmony_ci	ctx1_iv_off = 16;
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	err = aes_check_keylen(keylen);
103362306a36Sopenharmony_ci	if (err)
103462306a36Sopenharmony_ci		return err;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
103762306a36Sopenharmony_ci}
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_cistatic int chacha20_skcipher_setkey(struct crypto_skcipher *skcipher,
104062306a36Sopenharmony_ci				    const u8 *key, unsigned int keylen)
104162306a36Sopenharmony_ci{
104262306a36Sopenharmony_ci	if (keylen != CHACHA_KEY_SIZE)
104362306a36Sopenharmony_ci		return -EINVAL;
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_ci	return skcipher_setkey(skcipher, key, keylen, 0);
104662306a36Sopenharmony_ci}
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_cistatic int des_skcipher_setkey(struct crypto_skcipher *skcipher,
104962306a36Sopenharmony_ci			       const u8 *key, unsigned int keylen)
105062306a36Sopenharmony_ci{
105162306a36Sopenharmony_ci	return verify_skcipher_des_key(skcipher, key) ?:
105262306a36Sopenharmony_ci	       skcipher_setkey(skcipher, key, keylen, 0);
105362306a36Sopenharmony_ci}
105462306a36Sopenharmony_ci
105562306a36Sopenharmony_cistatic int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
105662306a36Sopenharmony_ci			        const u8 *key, unsigned int keylen)
105762306a36Sopenharmony_ci{
105862306a36Sopenharmony_ci	return verify_skcipher_des3_key(skcipher, key) ?:
105962306a36Sopenharmony_ci	       skcipher_setkey(skcipher, key, keylen, 0);
106062306a36Sopenharmony_ci}
106162306a36Sopenharmony_ci
106262306a36Sopenharmony_cistatic int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
106362306a36Sopenharmony_ci			       unsigned int keylen)
106462306a36Sopenharmony_ci{
106562306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
106662306a36Sopenharmony_ci	struct device *dev = ctx->dev;
106762306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
106862306a36Sopenharmony_ci	struct caam_flc *flc;
106962306a36Sopenharmony_ci	u32 *desc;
107062306a36Sopenharmony_ci	int err;
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	err = xts_verify_key(skcipher, key, keylen);
107362306a36Sopenharmony_ci	if (err) {
107462306a36Sopenharmony_ci		dev_dbg(dev, "key size mismatch\n");
107562306a36Sopenharmony_ci		return err;
107662306a36Sopenharmony_ci	}
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci	if (keylen != 2 * AES_KEYSIZE_128 && keylen != 2 * AES_KEYSIZE_256)
107962306a36Sopenharmony_ci		ctx->xts_key_fallback = true;
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci	if (priv->sec_attr.era <= 8 || ctx->xts_key_fallback) {
108262306a36Sopenharmony_ci		err = crypto_skcipher_setkey(ctx->fallback, key, keylen);
108362306a36Sopenharmony_ci		if (err)
108462306a36Sopenharmony_ci			return err;
108562306a36Sopenharmony_ci	}
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci	ctx->cdata.keylen = keylen;
108862306a36Sopenharmony_ci	ctx->cdata.key_virt = key;
108962306a36Sopenharmony_ci	ctx->cdata.key_inline = true;
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci	/* xts_skcipher_encrypt shared descriptor */
109262306a36Sopenharmony_ci	flc = &ctx->flc[ENCRYPT];
109362306a36Sopenharmony_ci	desc = flc->sh_desc;
109462306a36Sopenharmony_ci	cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata);
109562306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
109662306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
109762306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
109862306a36Sopenharmony_ci				   ctx->dir);
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci	/* xts_skcipher_decrypt shared descriptor */
110162306a36Sopenharmony_ci	flc = &ctx->flc[DECRYPT];
110262306a36Sopenharmony_ci	desc = flc->sh_desc;
110362306a36Sopenharmony_ci	cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata);
110462306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
110562306a36Sopenharmony_ci	dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
110662306a36Sopenharmony_ci				   sizeof(flc->flc) + desc_bytes(desc),
110762306a36Sopenharmony_ci				   ctx->dir);
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	return 0;
111062306a36Sopenharmony_ci}
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_cistatic struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req)
111362306a36Sopenharmony_ci{
111462306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
111562306a36Sopenharmony_ci	struct caam_request *req_ctx = skcipher_request_ctx_dma(req);
111662306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
111762306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
111862306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
111962306a36Sopenharmony_ci	struct device *dev = ctx->dev;
112062306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
112162306a36Sopenharmony_ci		       GFP_KERNEL : GFP_ATOMIC;
112262306a36Sopenharmony_ci	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
112362306a36Sopenharmony_ci	struct skcipher_edesc *edesc;
112462306a36Sopenharmony_ci	dma_addr_t iv_dma;
112562306a36Sopenharmony_ci	u8 *iv;
112662306a36Sopenharmony_ci	int ivsize = crypto_skcipher_ivsize(skcipher);
112762306a36Sopenharmony_ci	int dst_sg_idx, qm_sg_ents, qm_sg_bytes;
112862306a36Sopenharmony_ci	struct dpaa2_sg_entry *sg_table;
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	src_nents = sg_nents_for_len(req->src, req->cryptlen);
113162306a36Sopenharmony_ci	if (unlikely(src_nents < 0)) {
113262306a36Sopenharmony_ci		dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
113362306a36Sopenharmony_ci			req->cryptlen);
113462306a36Sopenharmony_ci		return ERR_PTR(src_nents);
113562306a36Sopenharmony_ci	}
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci	if (unlikely(req->dst != req->src)) {
113862306a36Sopenharmony_ci		dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
113962306a36Sopenharmony_ci		if (unlikely(dst_nents < 0)) {
114062306a36Sopenharmony_ci			dev_err(dev, "Insufficient bytes (%d) in dst S/G\n",
114162306a36Sopenharmony_ci				req->cryptlen);
114262306a36Sopenharmony_ci			return ERR_PTR(dst_nents);
114362306a36Sopenharmony_ci		}
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci		mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
114662306a36Sopenharmony_ci					      DMA_TO_DEVICE);
114762306a36Sopenharmony_ci		if (unlikely(!mapped_src_nents)) {
114862306a36Sopenharmony_ci			dev_err(dev, "unable to map source\n");
114962306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
115062306a36Sopenharmony_ci		}
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci		mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents,
115362306a36Sopenharmony_ci					      DMA_FROM_DEVICE);
115462306a36Sopenharmony_ci		if (unlikely(!mapped_dst_nents)) {
115562306a36Sopenharmony_ci			dev_err(dev, "unable to map destination\n");
115662306a36Sopenharmony_ci			dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE);
115762306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
115862306a36Sopenharmony_ci		}
115962306a36Sopenharmony_ci	} else {
116062306a36Sopenharmony_ci		mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
116162306a36Sopenharmony_ci					      DMA_BIDIRECTIONAL);
116262306a36Sopenharmony_ci		if (unlikely(!mapped_src_nents)) {
116362306a36Sopenharmony_ci			dev_err(dev, "unable to map source\n");
116462306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
116562306a36Sopenharmony_ci		}
116662306a36Sopenharmony_ci	}
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci	qm_sg_ents = 1 + mapped_src_nents;
116962306a36Sopenharmony_ci	dst_sg_idx = qm_sg_ents;
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci	/*
117262306a36Sopenharmony_ci	 * Input, output HW S/G tables: [IV, src][dst, IV]
117362306a36Sopenharmony_ci	 * IV entries point to the same buffer
117462306a36Sopenharmony_ci	 * If src == dst, S/G entries are reused (S/G tables overlap)
117562306a36Sopenharmony_ci	 *
117662306a36Sopenharmony_ci	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
117762306a36Sopenharmony_ci	 * the end of the table by allocating more S/G entries.
117862306a36Sopenharmony_ci	 */
117962306a36Sopenharmony_ci	if (req->src != req->dst)
118062306a36Sopenharmony_ci		qm_sg_ents += pad_sg_nents(mapped_dst_nents + 1);
118162306a36Sopenharmony_ci	else
118262306a36Sopenharmony_ci		qm_sg_ents = 1 + pad_sg_nents(qm_sg_ents);
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_ci	qm_sg_bytes = qm_sg_ents * sizeof(struct dpaa2_sg_entry);
118562306a36Sopenharmony_ci	if (unlikely(offsetof(struct skcipher_edesc, sgt) + qm_sg_bytes +
118662306a36Sopenharmony_ci		     ivsize > CAAM_QI_MEMCACHE_SIZE)) {
118762306a36Sopenharmony_ci		dev_err(dev, "No space for %d S/G entries and/or %dB IV\n",
118862306a36Sopenharmony_ci			qm_sg_ents, ivsize);
118962306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
119062306a36Sopenharmony_ci			   0, DMA_NONE, 0, 0);
119162306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
119262306a36Sopenharmony_ci	}
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	/* allocate space for base edesc, link tables and IV */
119562306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
119662306a36Sopenharmony_ci	if (unlikely(!edesc)) {
119762306a36Sopenharmony_ci		dev_err(dev, "could not allocate extended descriptor\n");
119862306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
119962306a36Sopenharmony_ci			   0, DMA_NONE, 0, 0);
120062306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
120162306a36Sopenharmony_ci	}
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	/* Make sure IV is located in a DMAable area */
120462306a36Sopenharmony_ci	sg_table = &edesc->sgt[0];
120562306a36Sopenharmony_ci	iv = (u8 *)(sg_table + qm_sg_ents);
120662306a36Sopenharmony_ci	memcpy(iv, req->iv, ivsize);
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci	iv_dma = dma_map_single(dev, iv, ivsize, DMA_BIDIRECTIONAL);
120962306a36Sopenharmony_ci	if (dma_mapping_error(dev, iv_dma)) {
121062306a36Sopenharmony_ci		dev_err(dev, "unable to map IV\n");
121162306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
121262306a36Sopenharmony_ci			   0, DMA_NONE, 0, 0);
121362306a36Sopenharmony_ci		qi_cache_free(edesc);
121462306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
121562306a36Sopenharmony_ci	}
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci	edesc->src_nents = src_nents;
121862306a36Sopenharmony_ci	edesc->dst_nents = dst_nents;
121962306a36Sopenharmony_ci	edesc->iv_dma = iv_dma;
122062306a36Sopenharmony_ci	edesc->qm_sg_bytes = qm_sg_bytes;
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_ci	dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0);
122362306a36Sopenharmony_ci	sg_to_qm_sg(req->src, req->cryptlen, sg_table + 1, 0);
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ci	if (req->src != req->dst)
122662306a36Sopenharmony_ci		sg_to_qm_sg(req->dst, req->cryptlen, sg_table + dst_sg_idx, 0);
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	dma_to_qm_sg_one(sg_table + dst_sg_idx + mapped_dst_nents, iv_dma,
122962306a36Sopenharmony_ci			 ivsize, 0);
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	edesc->qm_sg_dma = dma_map_single(dev, sg_table, edesc->qm_sg_bytes,
123262306a36Sopenharmony_ci					  DMA_TO_DEVICE);
123362306a36Sopenharmony_ci	if (dma_mapping_error(dev, edesc->qm_sg_dma)) {
123462306a36Sopenharmony_ci		dev_err(dev, "unable to map S/G table\n");
123562306a36Sopenharmony_ci		caam_unmap(dev, req->src, req->dst, src_nents, dst_nents,
123662306a36Sopenharmony_ci			   iv_dma, ivsize, DMA_BIDIRECTIONAL, 0, 0);
123762306a36Sopenharmony_ci		qi_cache_free(edesc);
123862306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
123962306a36Sopenharmony_ci	}
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
124262306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
124362306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, req->cryptlen + ivsize);
124462306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, req->cryptlen + ivsize);
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci	dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
124762306a36Sopenharmony_ci	dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
124862306a36Sopenharmony_ci
124962306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	if (req->src == req->dst)
125262306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma +
125362306a36Sopenharmony_ci				  sizeof(*sg_table));
125462306a36Sopenharmony_ci	else
125562306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + dst_sg_idx *
125662306a36Sopenharmony_ci				  sizeof(*sg_table));
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_ci	return edesc;
125962306a36Sopenharmony_ci}
126062306a36Sopenharmony_ci
126162306a36Sopenharmony_cistatic void aead_unmap(struct device *dev, struct aead_edesc *edesc,
126262306a36Sopenharmony_ci		       struct aead_request *req)
126362306a36Sopenharmony_ci{
126462306a36Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
126562306a36Sopenharmony_ci	int ivsize = crypto_aead_ivsize(aead);
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents,
126862306a36Sopenharmony_ci		   edesc->iv_dma, ivsize, DMA_TO_DEVICE, edesc->qm_sg_dma,
126962306a36Sopenharmony_ci		   edesc->qm_sg_bytes);
127062306a36Sopenharmony_ci	dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
127162306a36Sopenharmony_ci}
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_cistatic void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
127462306a36Sopenharmony_ci			   struct skcipher_request *req)
127562306a36Sopenharmony_ci{
127662306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
127762306a36Sopenharmony_ci	int ivsize = crypto_skcipher_ivsize(skcipher);
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci	caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents,
128062306a36Sopenharmony_ci		   edesc->iv_dma, ivsize, DMA_BIDIRECTIONAL, edesc->qm_sg_dma,
128162306a36Sopenharmony_ci		   edesc->qm_sg_bytes);
128262306a36Sopenharmony_ci}
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_cistatic void aead_encrypt_done(void *cbk_ctx, u32 status)
128562306a36Sopenharmony_ci{
128662306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
128762306a36Sopenharmony_ci	struct aead_request *req = container_of(areq, struct aead_request,
128862306a36Sopenharmony_ci						base);
128962306a36Sopenharmony_ci	struct caam_request *req_ctx = to_caam_req(areq);
129062306a36Sopenharmony_ci	struct aead_edesc *edesc = req_ctx->edesc;
129162306a36Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
129262306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
129362306a36Sopenharmony_ci	int ecode = 0;
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci	if (unlikely(status))
129862306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	aead_unmap(ctx->dev, edesc, req);
130162306a36Sopenharmony_ci	qi_cache_free(edesc);
130262306a36Sopenharmony_ci	aead_request_complete(req, ecode);
130362306a36Sopenharmony_ci}
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_cistatic void aead_decrypt_done(void *cbk_ctx, u32 status)
130662306a36Sopenharmony_ci{
130762306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
130862306a36Sopenharmony_ci	struct aead_request *req = container_of(areq, struct aead_request,
130962306a36Sopenharmony_ci						base);
131062306a36Sopenharmony_ci	struct caam_request *req_ctx = to_caam_req(areq);
131162306a36Sopenharmony_ci	struct aead_edesc *edesc = req_ctx->edesc;
131262306a36Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
131362306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
131462306a36Sopenharmony_ci	int ecode = 0;
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
131762306a36Sopenharmony_ci
131862306a36Sopenharmony_ci	if (unlikely(status))
131962306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	aead_unmap(ctx->dev, edesc, req);
132262306a36Sopenharmony_ci	qi_cache_free(edesc);
132362306a36Sopenharmony_ci	aead_request_complete(req, ecode);
132462306a36Sopenharmony_ci}
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_cistatic int aead_encrypt(struct aead_request *req)
132762306a36Sopenharmony_ci{
132862306a36Sopenharmony_ci	struct aead_edesc *edesc;
132962306a36Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
133062306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
133162306a36Sopenharmony_ci	struct caam_request *caam_req = aead_request_ctx_dma(req);
133262306a36Sopenharmony_ci	int ret;
133362306a36Sopenharmony_ci
133462306a36Sopenharmony_ci	/* allocate extended descriptor */
133562306a36Sopenharmony_ci	edesc = aead_edesc_alloc(req, true);
133662306a36Sopenharmony_ci	if (IS_ERR(edesc))
133762306a36Sopenharmony_ci		return PTR_ERR(edesc);
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	caam_req->flc = &ctx->flc[ENCRYPT];
134062306a36Sopenharmony_ci	caam_req->flc_dma = ctx->flc_dma[ENCRYPT];
134162306a36Sopenharmony_ci	caam_req->cbk = aead_encrypt_done;
134262306a36Sopenharmony_ci	caam_req->ctx = &req->base;
134362306a36Sopenharmony_ci	caam_req->edesc = edesc;
134462306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
134562306a36Sopenharmony_ci	if (ret != -EINPROGRESS &&
134662306a36Sopenharmony_ci	    !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
134762306a36Sopenharmony_ci		aead_unmap(ctx->dev, edesc, req);
134862306a36Sopenharmony_ci		qi_cache_free(edesc);
134962306a36Sopenharmony_ci	}
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	return ret;
135262306a36Sopenharmony_ci}
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_cistatic int aead_decrypt(struct aead_request *req)
135562306a36Sopenharmony_ci{
135662306a36Sopenharmony_ci	struct aead_edesc *edesc;
135762306a36Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
135862306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_aead_ctx_dma(aead);
135962306a36Sopenharmony_ci	struct caam_request *caam_req = aead_request_ctx_dma(req);
136062306a36Sopenharmony_ci	int ret;
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_ci	/* allocate extended descriptor */
136362306a36Sopenharmony_ci	edesc = aead_edesc_alloc(req, false);
136462306a36Sopenharmony_ci	if (IS_ERR(edesc))
136562306a36Sopenharmony_ci		return PTR_ERR(edesc);
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	caam_req->flc = &ctx->flc[DECRYPT];
136862306a36Sopenharmony_ci	caam_req->flc_dma = ctx->flc_dma[DECRYPT];
136962306a36Sopenharmony_ci	caam_req->cbk = aead_decrypt_done;
137062306a36Sopenharmony_ci	caam_req->ctx = &req->base;
137162306a36Sopenharmony_ci	caam_req->edesc = edesc;
137262306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
137362306a36Sopenharmony_ci	if (ret != -EINPROGRESS &&
137462306a36Sopenharmony_ci	    !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
137562306a36Sopenharmony_ci		aead_unmap(ctx->dev, edesc, req);
137662306a36Sopenharmony_ci		qi_cache_free(edesc);
137762306a36Sopenharmony_ci	}
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_ci	return ret;
138062306a36Sopenharmony_ci}
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_cistatic int ipsec_gcm_encrypt(struct aead_request *req)
138362306a36Sopenharmony_ci{
138462306a36Sopenharmony_ci	return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_encrypt(req);
138562306a36Sopenharmony_ci}
138662306a36Sopenharmony_ci
138762306a36Sopenharmony_cistatic int ipsec_gcm_decrypt(struct aead_request *req)
138862306a36Sopenharmony_ci{
138962306a36Sopenharmony_ci	return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_decrypt(req);
139062306a36Sopenharmony_ci}
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_cistatic void skcipher_encrypt_done(void *cbk_ctx, u32 status)
139362306a36Sopenharmony_ci{
139462306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
139562306a36Sopenharmony_ci	struct skcipher_request *req = skcipher_request_cast(areq);
139662306a36Sopenharmony_ci	struct caam_request *req_ctx = to_caam_req(areq);
139762306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
139862306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
139962306a36Sopenharmony_ci	struct skcipher_edesc *edesc = req_ctx->edesc;
140062306a36Sopenharmony_ci	int ecode = 0;
140162306a36Sopenharmony_ci	int ivsize = crypto_skcipher_ivsize(skcipher);
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	if (unlikely(status))
140662306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci	print_hex_dump_debug("dstiv  @" __stringify(__LINE__)": ",
140962306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
141062306a36Sopenharmony_ci			     edesc->src_nents > 1 ? 100 : ivsize, 1);
141162306a36Sopenharmony_ci	caam_dump_sg("dst    @" __stringify(__LINE__)": ",
141262306a36Sopenharmony_ci		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
141362306a36Sopenharmony_ci		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
141462306a36Sopenharmony_ci
141562306a36Sopenharmony_ci	skcipher_unmap(ctx->dev, edesc, req);
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci	/*
141862306a36Sopenharmony_ci	 * The crypto API expects us to set the IV (req->iv) to the last
141962306a36Sopenharmony_ci	 * ciphertext block (CBC mode) or last counter (CTR mode).
142062306a36Sopenharmony_ci	 * This is used e.g. by the CTS mode.
142162306a36Sopenharmony_ci	 */
142262306a36Sopenharmony_ci	if (!ecode)
142362306a36Sopenharmony_ci		memcpy(req->iv, (u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes,
142462306a36Sopenharmony_ci		       ivsize);
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci	qi_cache_free(edesc);
142762306a36Sopenharmony_ci	skcipher_request_complete(req, ecode);
142862306a36Sopenharmony_ci}
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_cistatic void skcipher_decrypt_done(void *cbk_ctx, u32 status)
143162306a36Sopenharmony_ci{
143262306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
143362306a36Sopenharmony_ci	struct skcipher_request *req = skcipher_request_cast(areq);
143462306a36Sopenharmony_ci	struct caam_request *req_ctx = to_caam_req(areq);
143562306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
143662306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
143762306a36Sopenharmony_ci	struct skcipher_edesc *edesc = req_ctx->edesc;
143862306a36Sopenharmony_ci	int ecode = 0;
143962306a36Sopenharmony_ci	int ivsize = crypto_skcipher_ivsize(skcipher);
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci	if (unlikely(status))
144462306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
144562306a36Sopenharmony_ci
144662306a36Sopenharmony_ci	print_hex_dump_debug("dstiv  @" __stringify(__LINE__)": ",
144762306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
144862306a36Sopenharmony_ci			     edesc->src_nents > 1 ? 100 : ivsize, 1);
144962306a36Sopenharmony_ci	caam_dump_sg("dst    @" __stringify(__LINE__)": ",
145062306a36Sopenharmony_ci		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
145162306a36Sopenharmony_ci		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	skcipher_unmap(ctx->dev, edesc, req);
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ci	/*
145662306a36Sopenharmony_ci	 * The crypto API expects us to set the IV (req->iv) to the last
145762306a36Sopenharmony_ci	 * ciphertext block (CBC mode) or last counter (CTR mode).
145862306a36Sopenharmony_ci	 * This is used e.g. by the CTS mode.
145962306a36Sopenharmony_ci	 */
146062306a36Sopenharmony_ci	if (!ecode)
146162306a36Sopenharmony_ci		memcpy(req->iv, (u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes,
146262306a36Sopenharmony_ci		       ivsize);
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci	qi_cache_free(edesc);
146562306a36Sopenharmony_ci	skcipher_request_complete(req, ecode);
146662306a36Sopenharmony_ci}
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_cistatic inline bool xts_skcipher_ivsize(struct skcipher_request *req)
146962306a36Sopenharmony_ci{
147062306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
147162306a36Sopenharmony_ci	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
147262306a36Sopenharmony_ci
147362306a36Sopenharmony_ci	return !!get_unaligned((u64 *)(req->iv + (ivsize / 2)));
147462306a36Sopenharmony_ci}
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_cistatic int skcipher_encrypt(struct skcipher_request *req)
147762306a36Sopenharmony_ci{
147862306a36Sopenharmony_ci	struct skcipher_edesc *edesc;
147962306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
148062306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
148162306a36Sopenharmony_ci	struct caam_request *caam_req = skcipher_request_ctx_dma(req);
148262306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev);
148362306a36Sopenharmony_ci	int ret;
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci	/*
148662306a36Sopenharmony_ci	 * XTS is expected to return an error even for input length = 0
148762306a36Sopenharmony_ci	 * Note that the case input length < block size will be caught during
148862306a36Sopenharmony_ci	 * HW offloading and return an error.
148962306a36Sopenharmony_ci	 */
149062306a36Sopenharmony_ci	if (!req->cryptlen && !ctx->fallback)
149162306a36Sopenharmony_ci		return 0;
149262306a36Sopenharmony_ci
149362306a36Sopenharmony_ci	if (ctx->fallback && ((priv->sec_attr.era <= 8 && xts_skcipher_ivsize(req)) ||
149462306a36Sopenharmony_ci			      ctx->xts_key_fallback)) {
149562306a36Sopenharmony_ci		skcipher_request_set_tfm(&caam_req->fallback_req, ctx->fallback);
149662306a36Sopenharmony_ci		skcipher_request_set_callback(&caam_req->fallback_req,
149762306a36Sopenharmony_ci					      req->base.flags,
149862306a36Sopenharmony_ci					      req->base.complete,
149962306a36Sopenharmony_ci					      req->base.data);
150062306a36Sopenharmony_ci		skcipher_request_set_crypt(&caam_req->fallback_req, req->src,
150162306a36Sopenharmony_ci					   req->dst, req->cryptlen, req->iv);
150262306a36Sopenharmony_ci
150362306a36Sopenharmony_ci		return crypto_skcipher_encrypt(&caam_req->fallback_req);
150462306a36Sopenharmony_ci	}
150562306a36Sopenharmony_ci
150662306a36Sopenharmony_ci	/* allocate extended descriptor */
150762306a36Sopenharmony_ci	edesc = skcipher_edesc_alloc(req);
150862306a36Sopenharmony_ci	if (IS_ERR(edesc))
150962306a36Sopenharmony_ci		return PTR_ERR(edesc);
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	caam_req->flc = &ctx->flc[ENCRYPT];
151262306a36Sopenharmony_ci	caam_req->flc_dma = ctx->flc_dma[ENCRYPT];
151362306a36Sopenharmony_ci	caam_req->cbk = skcipher_encrypt_done;
151462306a36Sopenharmony_ci	caam_req->ctx = &req->base;
151562306a36Sopenharmony_ci	caam_req->edesc = edesc;
151662306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
151762306a36Sopenharmony_ci	if (ret != -EINPROGRESS &&
151862306a36Sopenharmony_ci	    !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
151962306a36Sopenharmony_ci		skcipher_unmap(ctx->dev, edesc, req);
152062306a36Sopenharmony_ci		qi_cache_free(edesc);
152162306a36Sopenharmony_ci	}
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_ci	return ret;
152462306a36Sopenharmony_ci}
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_cistatic int skcipher_decrypt(struct skcipher_request *req)
152762306a36Sopenharmony_ci{
152862306a36Sopenharmony_ci	struct skcipher_edesc *edesc;
152962306a36Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
153062306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher);
153162306a36Sopenharmony_ci	struct caam_request *caam_req = skcipher_request_ctx_dma(req);
153262306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev);
153362306a36Sopenharmony_ci	int ret;
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_ci	/*
153662306a36Sopenharmony_ci	 * XTS is expected to return an error even for input length = 0
153762306a36Sopenharmony_ci	 * Note that the case input length < block size will be caught during
153862306a36Sopenharmony_ci	 * HW offloading and return an error.
153962306a36Sopenharmony_ci	 */
154062306a36Sopenharmony_ci	if (!req->cryptlen && !ctx->fallback)
154162306a36Sopenharmony_ci		return 0;
154262306a36Sopenharmony_ci
154362306a36Sopenharmony_ci	if (ctx->fallback && ((priv->sec_attr.era <= 8 && xts_skcipher_ivsize(req)) ||
154462306a36Sopenharmony_ci			      ctx->xts_key_fallback)) {
154562306a36Sopenharmony_ci		skcipher_request_set_tfm(&caam_req->fallback_req, ctx->fallback);
154662306a36Sopenharmony_ci		skcipher_request_set_callback(&caam_req->fallback_req,
154762306a36Sopenharmony_ci					      req->base.flags,
154862306a36Sopenharmony_ci					      req->base.complete,
154962306a36Sopenharmony_ci					      req->base.data);
155062306a36Sopenharmony_ci		skcipher_request_set_crypt(&caam_req->fallback_req, req->src,
155162306a36Sopenharmony_ci					   req->dst, req->cryptlen, req->iv);
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_ci		return crypto_skcipher_decrypt(&caam_req->fallback_req);
155462306a36Sopenharmony_ci	}
155562306a36Sopenharmony_ci
155662306a36Sopenharmony_ci	/* allocate extended descriptor */
155762306a36Sopenharmony_ci	edesc = skcipher_edesc_alloc(req);
155862306a36Sopenharmony_ci	if (IS_ERR(edesc))
155962306a36Sopenharmony_ci		return PTR_ERR(edesc);
156062306a36Sopenharmony_ci
156162306a36Sopenharmony_ci	caam_req->flc = &ctx->flc[DECRYPT];
156262306a36Sopenharmony_ci	caam_req->flc_dma = ctx->flc_dma[DECRYPT];
156362306a36Sopenharmony_ci	caam_req->cbk = skcipher_decrypt_done;
156462306a36Sopenharmony_ci	caam_req->ctx = &req->base;
156562306a36Sopenharmony_ci	caam_req->edesc = edesc;
156662306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
156762306a36Sopenharmony_ci	if (ret != -EINPROGRESS &&
156862306a36Sopenharmony_ci	    !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
156962306a36Sopenharmony_ci		skcipher_unmap(ctx->dev, edesc, req);
157062306a36Sopenharmony_ci		qi_cache_free(edesc);
157162306a36Sopenharmony_ci	}
157262306a36Sopenharmony_ci
157362306a36Sopenharmony_ci	return ret;
157462306a36Sopenharmony_ci}
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_cistatic int caam_cra_init(struct caam_ctx *ctx, struct caam_alg_entry *caam,
157762306a36Sopenharmony_ci			 bool uses_dkp)
157862306a36Sopenharmony_ci{
157962306a36Sopenharmony_ci	dma_addr_t dma_addr;
158062306a36Sopenharmony_ci	int i;
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci	/* copy descriptor header template value */
158362306a36Sopenharmony_ci	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
158462306a36Sopenharmony_ci	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
158562306a36Sopenharmony_ci
158662306a36Sopenharmony_ci	ctx->dev = caam->dev;
158762306a36Sopenharmony_ci	ctx->dir = uses_dkp ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ci	dma_addr = dma_map_single_attrs(ctx->dev, ctx->flc,
159062306a36Sopenharmony_ci					offsetof(struct caam_ctx, flc_dma),
159162306a36Sopenharmony_ci					ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
159262306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, dma_addr)) {
159362306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map key, shared descriptors\n");
159462306a36Sopenharmony_ci		return -ENOMEM;
159562306a36Sopenharmony_ci	}
159662306a36Sopenharmony_ci
159762306a36Sopenharmony_ci	for (i = 0; i < NUM_OP; i++)
159862306a36Sopenharmony_ci		ctx->flc_dma[i] = dma_addr + i * sizeof(ctx->flc[i]);
159962306a36Sopenharmony_ci	ctx->key_dma = dma_addr + NUM_OP * sizeof(ctx->flc[0]);
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ci	return 0;
160262306a36Sopenharmony_ci}
160362306a36Sopenharmony_ci
160462306a36Sopenharmony_cistatic int caam_cra_init_skcipher(struct crypto_skcipher *tfm)
160562306a36Sopenharmony_ci{
160662306a36Sopenharmony_ci	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
160762306a36Sopenharmony_ci	struct caam_skcipher_alg *caam_alg =
160862306a36Sopenharmony_ci		container_of(alg, typeof(*caam_alg), skcipher);
160962306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(tfm);
161062306a36Sopenharmony_ci	u32 alg_aai = caam_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
161162306a36Sopenharmony_ci	int ret = 0;
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	if (alg_aai == OP_ALG_AAI_XTS) {
161462306a36Sopenharmony_ci		const char *tfm_name = crypto_tfm_alg_name(&tfm->base);
161562306a36Sopenharmony_ci		struct crypto_skcipher *fallback;
161662306a36Sopenharmony_ci
161762306a36Sopenharmony_ci		fallback = crypto_alloc_skcipher(tfm_name, 0,
161862306a36Sopenharmony_ci						 CRYPTO_ALG_NEED_FALLBACK);
161962306a36Sopenharmony_ci		if (IS_ERR(fallback)) {
162062306a36Sopenharmony_ci			dev_err(caam_alg->caam.dev,
162162306a36Sopenharmony_ci				"Failed to allocate %s fallback: %ld\n",
162262306a36Sopenharmony_ci				tfm_name, PTR_ERR(fallback));
162362306a36Sopenharmony_ci			return PTR_ERR(fallback);
162462306a36Sopenharmony_ci		}
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci		ctx->fallback = fallback;
162762306a36Sopenharmony_ci		crypto_skcipher_set_reqsize_dma(
162862306a36Sopenharmony_ci			tfm, sizeof(struct caam_request) +
162962306a36Sopenharmony_ci			     crypto_skcipher_reqsize(fallback));
163062306a36Sopenharmony_ci	} else {
163162306a36Sopenharmony_ci		crypto_skcipher_set_reqsize_dma(tfm,
163262306a36Sopenharmony_ci						sizeof(struct caam_request));
163362306a36Sopenharmony_ci	}
163462306a36Sopenharmony_ci
163562306a36Sopenharmony_ci	ret = caam_cra_init(ctx, &caam_alg->caam, false);
163662306a36Sopenharmony_ci	if (ret && ctx->fallback)
163762306a36Sopenharmony_ci		crypto_free_skcipher(ctx->fallback);
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci	return ret;
164062306a36Sopenharmony_ci}
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_cistatic int caam_cra_init_aead(struct crypto_aead *tfm)
164362306a36Sopenharmony_ci{
164462306a36Sopenharmony_ci	struct aead_alg *alg = crypto_aead_alg(tfm);
164562306a36Sopenharmony_ci	struct caam_aead_alg *caam_alg = container_of(alg, typeof(*caam_alg),
164662306a36Sopenharmony_ci						      aead);
164762306a36Sopenharmony_ci
164862306a36Sopenharmony_ci	crypto_aead_set_reqsize_dma(tfm, sizeof(struct caam_request));
164962306a36Sopenharmony_ci	return caam_cra_init(crypto_aead_ctx_dma(tfm), &caam_alg->caam,
165062306a36Sopenharmony_ci			     !caam_alg->caam.nodkp);
165162306a36Sopenharmony_ci}
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_cistatic void caam_exit_common(struct caam_ctx *ctx)
165462306a36Sopenharmony_ci{
165562306a36Sopenharmony_ci	dma_unmap_single_attrs(ctx->dev, ctx->flc_dma[0],
165662306a36Sopenharmony_ci			       offsetof(struct caam_ctx, flc_dma), ctx->dir,
165762306a36Sopenharmony_ci			       DMA_ATTR_SKIP_CPU_SYNC);
165862306a36Sopenharmony_ci}
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_cistatic void caam_cra_exit(struct crypto_skcipher *tfm)
166162306a36Sopenharmony_ci{
166262306a36Sopenharmony_ci	struct caam_ctx *ctx = crypto_skcipher_ctx_dma(tfm);
166362306a36Sopenharmony_ci
166462306a36Sopenharmony_ci	if (ctx->fallback)
166562306a36Sopenharmony_ci		crypto_free_skcipher(ctx->fallback);
166662306a36Sopenharmony_ci	caam_exit_common(ctx);
166762306a36Sopenharmony_ci}
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_cistatic void caam_cra_exit_aead(struct crypto_aead *tfm)
167062306a36Sopenharmony_ci{
167162306a36Sopenharmony_ci	caam_exit_common(crypto_aead_ctx_dma(tfm));
167262306a36Sopenharmony_ci}
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_cistatic struct caam_skcipher_alg driver_algs[] = {
167562306a36Sopenharmony_ci	{
167662306a36Sopenharmony_ci		.skcipher = {
167762306a36Sopenharmony_ci			.base = {
167862306a36Sopenharmony_ci				.cra_name = "cbc(aes)",
167962306a36Sopenharmony_ci				.cra_driver_name = "cbc-aes-caam-qi2",
168062306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
168162306a36Sopenharmony_ci			},
168262306a36Sopenharmony_ci			.setkey = aes_skcipher_setkey,
168362306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
168462306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
168562306a36Sopenharmony_ci			.min_keysize = AES_MIN_KEY_SIZE,
168662306a36Sopenharmony_ci			.max_keysize = AES_MAX_KEY_SIZE,
168762306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
168862306a36Sopenharmony_ci		},
168962306a36Sopenharmony_ci		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
169062306a36Sopenharmony_ci	},
169162306a36Sopenharmony_ci	{
169262306a36Sopenharmony_ci		.skcipher = {
169362306a36Sopenharmony_ci			.base = {
169462306a36Sopenharmony_ci				.cra_name = "cbc(des3_ede)",
169562306a36Sopenharmony_ci				.cra_driver_name = "cbc-3des-caam-qi2",
169662306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
169762306a36Sopenharmony_ci			},
169862306a36Sopenharmony_ci			.setkey = des3_skcipher_setkey,
169962306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
170062306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
170162306a36Sopenharmony_ci			.min_keysize = DES3_EDE_KEY_SIZE,
170262306a36Sopenharmony_ci			.max_keysize = DES3_EDE_KEY_SIZE,
170362306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
170462306a36Sopenharmony_ci		},
170562306a36Sopenharmony_ci		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
170662306a36Sopenharmony_ci	},
170762306a36Sopenharmony_ci	{
170862306a36Sopenharmony_ci		.skcipher = {
170962306a36Sopenharmony_ci			.base = {
171062306a36Sopenharmony_ci				.cra_name = "cbc(des)",
171162306a36Sopenharmony_ci				.cra_driver_name = "cbc-des-caam-qi2",
171262306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
171362306a36Sopenharmony_ci			},
171462306a36Sopenharmony_ci			.setkey = des_skcipher_setkey,
171562306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
171662306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
171762306a36Sopenharmony_ci			.min_keysize = DES_KEY_SIZE,
171862306a36Sopenharmony_ci			.max_keysize = DES_KEY_SIZE,
171962306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
172062306a36Sopenharmony_ci		},
172162306a36Sopenharmony_ci		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
172262306a36Sopenharmony_ci	},
172362306a36Sopenharmony_ci	{
172462306a36Sopenharmony_ci		.skcipher = {
172562306a36Sopenharmony_ci			.base = {
172662306a36Sopenharmony_ci				.cra_name = "ctr(aes)",
172762306a36Sopenharmony_ci				.cra_driver_name = "ctr-aes-caam-qi2",
172862306a36Sopenharmony_ci				.cra_blocksize = 1,
172962306a36Sopenharmony_ci			},
173062306a36Sopenharmony_ci			.setkey = ctr_skcipher_setkey,
173162306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
173262306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
173362306a36Sopenharmony_ci			.min_keysize = AES_MIN_KEY_SIZE,
173462306a36Sopenharmony_ci			.max_keysize = AES_MAX_KEY_SIZE,
173562306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
173662306a36Sopenharmony_ci			.chunksize = AES_BLOCK_SIZE,
173762306a36Sopenharmony_ci		},
173862306a36Sopenharmony_ci		.caam.class1_alg_type = OP_ALG_ALGSEL_AES |
173962306a36Sopenharmony_ci					OP_ALG_AAI_CTR_MOD128,
174062306a36Sopenharmony_ci	},
174162306a36Sopenharmony_ci	{
174262306a36Sopenharmony_ci		.skcipher = {
174362306a36Sopenharmony_ci			.base = {
174462306a36Sopenharmony_ci				.cra_name = "rfc3686(ctr(aes))",
174562306a36Sopenharmony_ci				.cra_driver_name = "rfc3686-ctr-aes-caam-qi2",
174662306a36Sopenharmony_ci				.cra_blocksize = 1,
174762306a36Sopenharmony_ci			},
174862306a36Sopenharmony_ci			.setkey = rfc3686_skcipher_setkey,
174962306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
175062306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
175162306a36Sopenharmony_ci			.min_keysize = AES_MIN_KEY_SIZE +
175262306a36Sopenharmony_ci				       CTR_RFC3686_NONCE_SIZE,
175362306a36Sopenharmony_ci			.max_keysize = AES_MAX_KEY_SIZE +
175462306a36Sopenharmony_ci				       CTR_RFC3686_NONCE_SIZE,
175562306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
175662306a36Sopenharmony_ci			.chunksize = AES_BLOCK_SIZE,
175762306a36Sopenharmony_ci		},
175862306a36Sopenharmony_ci		.caam = {
175962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
176062306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
176162306a36Sopenharmony_ci			.rfc3686 = true,
176262306a36Sopenharmony_ci		},
176362306a36Sopenharmony_ci	},
176462306a36Sopenharmony_ci	{
176562306a36Sopenharmony_ci		.skcipher = {
176662306a36Sopenharmony_ci			.base = {
176762306a36Sopenharmony_ci				.cra_name = "xts(aes)",
176862306a36Sopenharmony_ci				.cra_driver_name = "xts-aes-caam-qi2",
176962306a36Sopenharmony_ci				.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
177062306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
177162306a36Sopenharmony_ci			},
177262306a36Sopenharmony_ci			.setkey = xts_skcipher_setkey,
177362306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
177462306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
177562306a36Sopenharmony_ci			.min_keysize = 2 * AES_MIN_KEY_SIZE,
177662306a36Sopenharmony_ci			.max_keysize = 2 * AES_MAX_KEY_SIZE,
177762306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
177862306a36Sopenharmony_ci		},
177962306a36Sopenharmony_ci		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
178062306a36Sopenharmony_ci	},
178162306a36Sopenharmony_ci	{
178262306a36Sopenharmony_ci		.skcipher = {
178362306a36Sopenharmony_ci			.base = {
178462306a36Sopenharmony_ci				.cra_name = "chacha20",
178562306a36Sopenharmony_ci				.cra_driver_name = "chacha20-caam-qi2",
178662306a36Sopenharmony_ci				.cra_blocksize = 1,
178762306a36Sopenharmony_ci			},
178862306a36Sopenharmony_ci			.setkey = chacha20_skcipher_setkey,
178962306a36Sopenharmony_ci			.encrypt = skcipher_encrypt,
179062306a36Sopenharmony_ci			.decrypt = skcipher_decrypt,
179162306a36Sopenharmony_ci			.min_keysize = CHACHA_KEY_SIZE,
179262306a36Sopenharmony_ci			.max_keysize = CHACHA_KEY_SIZE,
179362306a36Sopenharmony_ci			.ivsize = CHACHA_IV_SIZE,
179462306a36Sopenharmony_ci		},
179562306a36Sopenharmony_ci		.caam.class1_alg_type = OP_ALG_ALGSEL_CHACHA20,
179662306a36Sopenharmony_ci	},
179762306a36Sopenharmony_ci};
179862306a36Sopenharmony_ci
179962306a36Sopenharmony_cistatic struct caam_aead_alg driver_aeads[] = {
180062306a36Sopenharmony_ci	{
180162306a36Sopenharmony_ci		.aead = {
180262306a36Sopenharmony_ci			.base = {
180362306a36Sopenharmony_ci				.cra_name = "rfc4106(gcm(aes))",
180462306a36Sopenharmony_ci				.cra_driver_name = "rfc4106-gcm-aes-caam-qi2",
180562306a36Sopenharmony_ci				.cra_blocksize = 1,
180662306a36Sopenharmony_ci			},
180762306a36Sopenharmony_ci			.setkey = rfc4106_setkey,
180862306a36Sopenharmony_ci			.setauthsize = rfc4106_setauthsize,
180962306a36Sopenharmony_ci			.encrypt = ipsec_gcm_encrypt,
181062306a36Sopenharmony_ci			.decrypt = ipsec_gcm_decrypt,
181162306a36Sopenharmony_ci			.ivsize = 8,
181262306a36Sopenharmony_ci			.maxauthsize = AES_BLOCK_SIZE,
181362306a36Sopenharmony_ci		},
181462306a36Sopenharmony_ci		.caam = {
181562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
181662306a36Sopenharmony_ci			.nodkp = true,
181762306a36Sopenharmony_ci		},
181862306a36Sopenharmony_ci	},
181962306a36Sopenharmony_ci	{
182062306a36Sopenharmony_ci		.aead = {
182162306a36Sopenharmony_ci			.base = {
182262306a36Sopenharmony_ci				.cra_name = "rfc4543(gcm(aes))",
182362306a36Sopenharmony_ci				.cra_driver_name = "rfc4543-gcm-aes-caam-qi2",
182462306a36Sopenharmony_ci				.cra_blocksize = 1,
182562306a36Sopenharmony_ci			},
182662306a36Sopenharmony_ci			.setkey = rfc4543_setkey,
182762306a36Sopenharmony_ci			.setauthsize = rfc4543_setauthsize,
182862306a36Sopenharmony_ci			.encrypt = ipsec_gcm_encrypt,
182962306a36Sopenharmony_ci			.decrypt = ipsec_gcm_decrypt,
183062306a36Sopenharmony_ci			.ivsize = 8,
183162306a36Sopenharmony_ci			.maxauthsize = AES_BLOCK_SIZE,
183262306a36Sopenharmony_ci		},
183362306a36Sopenharmony_ci		.caam = {
183462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
183562306a36Sopenharmony_ci			.nodkp = true,
183662306a36Sopenharmony_ci		},
183762306a36Sopenharmony_ci	},
183862306a36Sopenharmony_ci	/* Galois Counter Mode */
183962306a36Sopenharmony_ci	{
184062306a36Sopenharmony_ci		.aead = {
184162306a36Sopenharmony_ci			.base = {
184262306a36Sopenharmony_ci				.cra_name = "gcm(aes)",
184362306a36Sopenharmony_ci				.cra_driver_name = "gcm-aes-caam-qi2",
184462306a36Sopenharmony_ci				.cra_blocksize = 1,
184562306a36Sopenharmony_ci			},
184662306a36Sopenharmony_ci			.setkey = gcm_setkey,
184762306a36Sopenharmony_ci			.setauthsize = gcm_setauthsize,
184862306a36Sopenharmony_ci			.encrypt = aead_encrypt,
184962306a36Sopenharmony_ci			.decrypt = aead_decrypt,
185062306a36Sopenharmony_ci			.ivsize = 12,
185162306a36Sopenharmony_ci			.maxauthsize = AES_BLOCK_SIZE,
185262306a36Sopenharmony_ci		},
185362306a36Sopenharmony_ci		.caam = {
185462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
185562306a36Sopenharmony_ci			.nodkp = true,
185662306a36Sopenharmony_ci		}
185762306a36Sopenharmony_ci	},
185862306a36Sopenharmony_ci	/* single-pass ipsec_esp descriptor */
185962306a36Sopenharmony_ci	{
186062306a36Sopenharmony_ci		.aead = {
186162306a36Sopenharmony_ci			.base = {
186262306a36Sopenharmony_ci				.cra_name = "authenc(hmac(md5),cbc(aes))",
186362306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-md5-"
186462306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
186562306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
186662306a36Sopenharmony_ci			},
186762306a36Sopenharmony_ci			.setkey = aead_setkey,
186862306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
186962306a36Sopenharmony_ci			.encrypt = aead_encrypt,
187062306a36Sopenharmony_ci			.decrypt = aead_decrypt,
187162306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
187262306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
187362306a36Sopenharmony_ci		},
187462306a36Sopenharmony_ci		.caam = {
187562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
187662306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
187762306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
187862306a36Sopenharmony_ci		}
187962306a36Sopenharmony_ci	},
188062306a36Sopenharmony_ci	{
188162306a36Sopenharmony_ci		.aead = {
188262306a36Sopenharmony_ci			.base = {
188362306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(md5),"
188462306a36Sopenharmony_ci					    "cbc(aes)))",
188562306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-hmac-md5-"
188662306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
188762306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
188862306a36Sopenharmony_ci			},
188962306a36Sopenharmony_ci			.setkey = aead_setkey,
189062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
189162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
189262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
189362306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
189462306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
189562306a36Sopenharmony_ci		},
189662306a36Sopenharmony_ci		.caam = {
189762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
189862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
189962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
190062306a36Sopenharmony_ci			.geniv = true,
190162306a36Sopenharmony_ci		}
190262306a36Sopenharmony_ci	},
190362306a36Sopenharmony_ci	{
190462306a36Sopenharmony_ci		.aead = {
190562306a36Sopenharmony_ci			.base = {
190662306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha1),cbc(aes))",
190762306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha1-"
190862306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
190962306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
191062306a36Sopenharmony_ci			},
191162306a36Sopenharmony_ci			.setkey = aead_setkey,
191262306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
191362306a36Sopenharmony_ci			.encrypt = aead_encrypt,
191462306a36Sopenharmony_ci			.decrypt = aead_decrypt,
191562306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
191662306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
191762306a36Sopenharmony_ci		},
191862306a36Sopenharmony_ci		.caam = {
191962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
192062306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
192162306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
192262306a36Sopenharmony_ci		}
192362306a36Sopenharmony_ci	},
192462306a36Sopenharmony_ci	{
192562306a36Sopenharmony_ci		.aead = {
192662306a36Sopenharmony_ci			.base = {
192762306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha1),"
192862306a36Sopenharmony_ci					    "cbc(aes)))",
192962306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
193062306a36Sopenharmony_ci						   "hmac-sha1-cbc-aes-caam-qi2",
193162306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
193262306a36Sopenharmony_ci			},
193362306a36Sopenharmony_ci			.setkey = aead_setkey,
193462306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
193562306a36Sopenharmony_ci			.encrypt = aead_encrypt,
193662306a36Sopenharmony_ci			.decrypt = aead_decrypt,
193762306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
193862306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
193962306a36Sopenharmony_ci		},
194062306a36Sopenharmony_ci		.caam = {
194162306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
194262306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
194362306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
194462306a36Sopenharmony_ci			.geniv = true,
194562306a36Sopenharmony_ci		},
194662306a36Sopenharmony_ci	},
194762306a36Sopenharmony_ci	{
194862306a36Sopenharmony_ci		.aead = {
194962306a36Sopenharmony_ci			.base = {
195062306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha224),cbc(aes))",
195162306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha224-"
195262306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
195362306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
195462306a36Sopenharmony_ci			},
195562306a36Sopenharmony_ci			.setkey = aead_setkey,
195662306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
195762306a36Sopenharmony_ci			.encrypt = aead_encrypt,
195862306a36Sopenharmony_ci			.decrypt = aead_decrypt,
195962306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
196062306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
196162306a36Sopenharmony_ci		},
196262306a36Sopenharmony_ci		.caam = {
196362306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
196462306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
196562306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
196662306a36Sopenharmony_ci		}
196762306a36Sopenharmony_ci	},
196862306a36Sopenharmony_ci	{
196962306a36Sopenharmony_ci		.aead = {
197062306a36Sopenharmony_ci			.base = {
197162306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha224),"
197262306a36Sopenharmony_ci					    "cbc(aes)))",
197362306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
197462306a36Sopenharmony_ci						   "hmac-sha224-cbc-aes-caam-qi2",
197562306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
197662306a36Sopenharmony_ci			},
197762306a36Sopenharmony_ci			.setkey = aead_setkey,
197862306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
197962306a36Sopenharmony_ci			.encrypt = aead_encrypt,
198062306a36Sopenharmony_ci			.decrypt = aead_decrypt,
198162306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
198262306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
198362306a36Sopenharmony_ci		},
198462306a36Sopenharmony_ci		.caam = {
198562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
198662306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
198762306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
198862306a36Sopenharmony_ci			.geniv = true,
198962306a36Sopenharmony_ci		}
199062306a36Sopenharmony_ci	},
199162306a36Sopenharmony_ci	{
199262306a36Sopenharmony_ci		.aead = {
199362306a36Sopenharmony_ci			.base = {
199462306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha256),cbc(aes))",
199562306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha256-"
199662306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
199762306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
199862306a36Sopenharmony_ci			},
199962306a36Sopenharmony_ci			.setkey = aead_setkey,
200062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
200162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
200262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
200362306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
200462306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
200562306a36Sopenharmony_ci		},
200662306a36Sopenharmony_ci		.caam = {
200762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
200862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
200962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
201062306a36Sopenharmony_ci		}
201162306a36Sopenharmony_ci	},
201262306a36Sopenharmony_ci	{
201362306a36Sopenharmony_ci		.aead = {
201462306a36Sopenharmony_ci			.base = {
201562306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha256),"
201662306a36Sopenharmony_ci					    "cbc(aes)))",
201762306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
201862306a36Sopenharmony_ci						   "hmac-sha256-cbc-aes-"
201962306a36Sopenharmony_ci						   "caam-qi2",
202062306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
202162306a36Sopenharmony_ci			},
202262306a36Sopenharmony_ci			.setkey = aead_setkey,
202362306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
202462306a36Sopenharmony_ci			.encrypt = aead_encrypt,
202562306a36Sopenharmony_ci			.decrypt = aead_decrypt,
202662306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
202762306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
202862306a36Sopenharmony_ci		},
202962306a36Sopenharmony_ci		.caam = {
203062306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
203162306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
203262306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
203362306a36Sopenharmony_ci			.geniv = true,
203462306a36Sopenharmony_ci		}
203562306a36Sopenharmony_ci	},
203662306a36Sopenharmony_ci	{
203762306a36Sopenharmony_ci		.aead = {
203862306a36Sopenharmony_ci			.base = {
203962306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha384),cbc(aes))",
204062306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha384-"
204162306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
204262306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
204362306a36Sopenharmony_ci			},
204462306a36Sopenharmony_ci			.setkey = aead_setkey,
204562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
204662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
204762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
204862306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
204962306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
205062306a36Sopenharmony_ci		},
205162306a36Sopenharmony_ci		.caam = {
205262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
205362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
205462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
205562306a36Sopenharmony_ci		}
205662306a36Sopenharmony_ci	},
205762306a36Sopenharmony_ci	{
205862306a36Sopenharmony_ci		.aead = {
205962306a36Sopenharmony_ci			.base = {
206062306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha384),"
206162306a36Sopenharmony_ci					    "cbc(aes)))",
206262306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
206362306a36Sopenharmony_ci						   "hmac-sha384-cbc-aes-"
206462306a36Sopenharmony_ci						   "caam-qi2",
206562306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
206662306a36Sopenharmony_ci			},
206762306a36Sopenharmony_ci			.setkey = aead_setkey,
206862306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
206962306a36Sopenharmony_ci			.encrypt = aead_encrypt,
207062306a36Sopenharmony_ci			.decrypt = aead_decrypt,
207162306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
207262306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
207362306a36Sopenharmony_ci		},
207462306a36Sopenharmony_ci		.caam = {
207562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
207662306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
207762306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
207862306a36Sopenharmony_ci			.geniv = true,
207962306a36Sopenharmony_ci		}
208062306a36Sopenharmony_ci	},
208162306a36Sopenharmony_ci	{
208262306a36Sopenharmony_ci		.aead = {
208362306a36Sopenharmony_ci			.base = {
208462306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha512),cbc(aes))",
208562306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha512-"
208662306a36Sopenharmony_ci						   "cbc-aes-caam-qi2",
208762306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
208862306a36Sopenharmony_ci			},
208962306a36Sopenharmony_ci			.setkey = aead_setkey,
209062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
209162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
209262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
209362306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
209462306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
209562306a36Sopenharmony_ci		},
209662306a36Sopenharmony_ci		.caam = {
209762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
209862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
209962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
210062306a36Sopenharmony_ci		}
210162306a36Sopenharmony_ci	},
210262306a36Sopenharmony_ci	{
210362306a36Sopenharmony_ci		.aead = {
210462306a36Sopenharmony_ci			.base = {
210562306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha512),"
210662306a36Sopenharmony_ci					    "cbc(aes)))",
210762306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
210862306a36Sopenharmony_ci						   "hmac-sha512-cbc-aes-"
210962306a36Sopenharmony_ci						   "caam-qi2",
211062306a36Sopenharmony_ci				.cra_blocksize = AES_BLOCK_SIZE,
211162306a36Sopenharmony_ci			},
211262306a36Sopenharmony_ci			.setkey = aead_setkey,
211362306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
211462306a36Sopenharmony_ci			.encrypt = aead_encrypt,
211562306a36Sopenharmony_ci			.decrypt = aead_decrypt,
211662306a36Sopenharmony_ci			.ivsize = AES_BLOCK_SIZE,
211762306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
211862306a36Sopenharmony_ci		},
211962306a36Sopenharmony_ci		.caam = {
212062306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
212162306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
212262306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
212362306a36Sopenharmony_ci			.geniv = true,
212462306a36Sopenharmony_ci		}
212562306a36Sopenharmony_ci	},
212662306a36Sopenharmony_ci	{
212762306a36Sopenharmony_ci		.aead = {
212862306a36Sopenharmony_ci			.base = {
212962306a36Sopenharmony_ci				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
213062306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-md5-"
213162306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
213262306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
213362306a36Sopenharmony_ci			},
213462306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
213562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
213662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
213762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
213862306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
213962306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
214062306a36Sopenharmony_ci		},
214162306a36Sopenharmony_ci		.caam = {
214262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
214362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
214462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
214562306a36Sopenharmony_ci		}
214662306a36Sopenharmony_ci	},
214762306a36Sopenharmony_ci	{
214862306a36Sopenharmony_ci		.aead = {
214962306a36Sopenharmony_ci			.base = {
215062306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(md5),"
215162306a36Sopenharmony_ci					    "cbc(des3_ede)))",
215262306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-hmac-md5-"
215362306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
215462306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
215562306a36Sopenharmony_ci			},
215662306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
215762306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
215862306a36Sopenharmony_ci			.encrypt = aead_encrypt,
215962306a36Sopenharmony_ci			.decrypt = aead_decrypt,
216062306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
216162306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
216262306a36Sopenharmony_ci		},
216362306a36Sopenharmony_ci		.caam = {
216462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
216562306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
216662306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
216762306a36Sopenharmony_ci			.geniv = true,
216862306a36Sopenharmony_ci		}
216962306a36Sopenharmony_ci	},
217062306a36Sopenharmony_ci	{
217162306a36Sopenharmony_ci		.aead = {
217262306a36Sopenharmony_ci			.base = {
217362306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha1),"
217462306a36Sopenharmony_ci					    "cbc(des3_ede))",
217562306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha1-"
217662306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
217762306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
217862306a36Sopenharmony_ci			},
217962306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
218062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
218162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
218262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
218362306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
218462306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
218562306a36Sopenharmony_ci		},
218662306a36Sopenharmony_ci		.caam = {
218762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
218862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
218962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
219062306a36Sopenharmony_ci		},
219162306a36Sopenharmony_ci	},
219262306a36Sopenharmony_ci	{
219362306a36Sopenharmony_ci		.aead = {
219462306a36Sopenharmony_ci			.base = {
219562306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha1),"
219662306a36Sopenharmony_ci					    "cbc(des3_ede)))",
219762306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
219862306a36Sopenharmony_ci						   "hmac-sha1-"
219962306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
220062306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
220162306a36Sopenharmony_ci			},
220262306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
220362306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
220462306a36Sopenharmony_ci			.encrypt = aead_encrypt,
220562306a36Sopenharmony_ci			.decrypt = aead_decrypt,
220662306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
220762306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
220862306a36Sopenharmony_ci		},
220962306a36Sopenharmony_ci		.caam = {
221062306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
221162306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
221262306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
221362306a36Sopenharmony_ci			.geniv = true,
221462306a36Sopenharmony_ci		}
221562306a36Sopenharmony_ci	},
221662306a36Sopenharmony_ci	{
221762306a36Sopenharmony_ci		.aead = {
221862306a36Sopenharmony_ci			.base = {
221962306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha224),"
222062306a36Sopenharmony_ci					    "cbc(des3_ede))",
222162306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha224-"
222262306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
222362306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
222462306a36Sopenharmony_ci			},
222562306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
222662306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
222762306a36Sopenharmony_ci			.encrypt = aead_encrypt,
222862306a36Sopenharmony_ci			.decrypt = aead_decrypt,
222962306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
223062306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
223162306a36Sopenharmony_ci		},
223262306a36Sopenharmony_ci		.caam = {
223362306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
223462306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
223562306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
223662306a36Sopenharmony_ci		},
223762306a36Sopenharmony_ci	},
223862306a36Sopenharmony_ci	{
223962306a36Sopenharmony_ci		.aead = {
224062306a36Sopenharmony_ci			.base = {
224162306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha224),"
224262306a36Sopenharmony_ci					    "cbc(des3_ede)))",
224362306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
224462306a36Sopenharmony_ci						   "hmac-sha224-"
224562306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
224662306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
224762306a36Sopenharmony_ci			},
224862306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
224962306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
225062306a36Sopenharmony_ci			.encrypt = aead_encrypt,
225162306a36Sopenharmony_ci			.decrypt = aead_decrypt,
225262306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
225362306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
225462306a36Sopenharmony_ci		},
225562306a36Sopenharmony_ci		.caam = {
225662306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
225762306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
225862306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
225962306a36Sopenharmony_ci			.geniv = true,
226062306a36Sopenharmony_ci		}
226162306a36Sopenharmony_ci	},
226262306a36Sopenharmony_ci	{
226362306a36Sopenharmony_ci		.aead = {
226462306a36Sopenharmony_ci			.base = {
226562306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha256),"
226662306a36Sopenharmony_ci					    "cbc(des3_ede))",
226762306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha256-"
226862306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
226962306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
227062306a36Sopenharmony_ci			},
227162306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
227262306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
227362306a36Sopenharmony_ci			.encrypt = aead_encrypt,
227462306a36Sopenharmony_ci			.decrypt = aead_decrypt,
227562306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
227662306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
227762306a36Sopenharmony_ci		},
227862306a36Sopenharmony_ci		.caam = {
227962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
228062306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
228162306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
228262306a36Sopenharmony_ci		},
228362306a36Sopenharmony_ci	},
228462306a36Sopenharmony_ci	{
228562306a36Sopenharmony_ci		.aead = {
228662306a36Sopenharmony_ci			.base = {
228762306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha256),"
228862306a36Sopenharmony_ci					    "cbc(des3_ede)))",
228962306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
229062306a36Sopenharmony_ci						   "hmac-sha256-"
229162306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
229262306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
229362306a36Sopenharmony_ci			},
229462306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
229562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
229662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
229762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
229862306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
229962306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
230062306a36Sopenharmony_ci		},
230162306a36Sopenharmony_ci		.caam = {
230262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
230362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
230462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
230562306a36Sopenharmony_ci			.geniv = true,
230662306a36Sopenharmony_ci		}
230762306a36Sopenharmony_ci	},
230862306a36Sopenharmony_ci	{
230962306a36Sopenharmony_ci		.aead = {
231062306a36Sopenharmony_ci			.base = {
231162306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha384),"
231262306a36Sopenharmony_ci					    "cbc(des3_ede))",
231362306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha384-"
231462306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
231562306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
231662306a36Sopenharmony_ci			},
231762306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
231862306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
231962306a36Sopenharmony_ci			.encrypt = aead_encrypt,
232062306a36Sopenharmony_ci			.decrypt = aead_decrypt,
232162306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
232262306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
232362306a36Sopenharmony_ci		},
232462306a36Sopenharmony_ci		.caam = {
232562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
232662306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
232762306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
232862306a36Sopenharmony_ci		},
232962306a36Sopenharmony_ci	},
233062306a36Sopenharmony_ci	{
233162306a36Sopenharmony_ci		.aead = {
233262306a36Sopenharmony_ci			.base = {
233362306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha384),"
233462306a36Sopenharmony_ci					    "cbc(des3_ede)))",
233562306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
233662306a36Sopenharmony_ci						   "hmac-sha384-"
233762306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
233862306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
233962306a36Sopenharmony_ci			},
234062306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
234162306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
234262306a36Sopenharmony_ci			.encrypt = aead_encrypt,
234362306a36Sopenharmony_ci			.decrypt = aead_decrypt,
234462306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
234562306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
234662306a36Sopenharmony_ci		},
234762306a36Sopenharmony_ci		.caam = {
234862306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
234962306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
235062306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
235162306a36Sopenharmony_ci			.geniv = true,
235262306a36Sopenharmony_ci		}
235362306a36Sopenharmony_ci	},
235462306a36Sopenharmony_ci	{
235562306a36Sopenharmony_ci		.aead = {
235662306a36Sopenharmony_ci			.base = {
235762306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha512),"
235862306a36Sopenharmony_ci					    "cbc(des3_ede))",
235962306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha512-"
236062306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
236162306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
236262306a36Sopenharmony_ci			},
236362306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
236462306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
236562306a36Sopenharmony_ci			.encrypt = aead_encrypt,
236662306a36Sopenharmony_ci			.decrypt = aead_decrypt,
236762306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
236862306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
236962306a36Sopenharmony_ci		},
237062306a36Sopenharmony_ci		.caam = {
237162306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
237262306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
237362306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
237462306a36Sopenharmony_ci		},
237562306a36Sopenharmony_ci	},
237662306a36Sopenharmony_ci	{
237762306a36Sopenharmony_ci		.aead = {
237862306a36Sopenharmony_ci			.base = {
237962306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha512),"
238062306a36Sopenharmony_ci					    "cbc(des3_ede)))",
238162306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
238262306a36Sopenharmony_ci						   "hmac-sha512-"
238362306a36Sopenharmony_ci						   "cbc-des3_ede-caam-qi2",
238462306a36Sopenharmony_ci				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
238562306a36Sopenharmony_ci			},
238662306a36Sopenharmony_ci			.setkey = des3_aead_setkey,
238762306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
238862306a36Sopenharmony_ci			.encrypt = aead_encrypt,
238962306a36Sopenharmony_ci			.decrypt = aead_decrypt,
239062306a36Sopenharmony_ci			.ivsize = DES3_EDE_BLOCK_SIZE,
239162306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
239262306a36Sopenharmony_ci		},
239362306a36Sopenharmony_ci		.caam = {
239462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
239562306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
239662306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
239762306a36Sopenharmony_ci			.geniv = true,
239862306a36Sopenharmony_ci		}
239962306a36Sopenharmony_ci	},
240062306a36Sopenharmony_ci	{
240162306a36Sopenharmony_ci		.aead = {
240262306a36Sopenharmony_ci			.base = {
240362306a36Sopenharmony_ci				.cra_name = "authenc(hmac(md5),cbc(des))",
240462306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-md5-"
240562306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
240662306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
240762306a36Sopenharmony_ci			},
240862306a36Sopenharmony_ci			.setkey = aead_setkey,
240962306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
241062306a36Sopenharmony_ci			.encrypt = aead_encrypt,
241162306a36Sopenharmony_ci			.decrypt = aead_decrypt,
241262306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
241362306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
241462306a36Sopenharmony_ci		},
241562306a36Sopenharmony_ci		.caam = {
241662306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
241762306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
241862306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
241962306a36Sopenharmony_ci		},
242062306a36Sopenharmony_ci	},
242162306a36Sopenharmony_ci	{
242262306a36Sopenharmony_ci		.aead = {
242362306a36Sopenharmony_ci			.base = {
242462306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(md5),"
242562306a36Sopenharmony_ci					    "cbc(des)))",
242662306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-hmac-md5-"
242762306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
242862306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
242962306a36Sopenharmony_ci			},
243062306a36Sopenharmony_ci			.setkey = aead_setkey,
243162306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
243262306a36Sopenharmony_ci			.encrypt = aead_encrypt,
243362306a36Sopenharmony_ci			.decrypt = aead_decrypt,
243462306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
243562306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
243662306a36Sopenharmony_ci		},
243762306a36Sopenharmony_ci		.caam = {
243862306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
243962306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
244062306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
244162306a36Sopenharmony_ci			.geniv = true,
244262306a36Sopenharmony_ci		}
244362306a36Sopenharmony_ci	},
244462306a36Sopenharmony_ci	{
244562306a36Sopenharmony_ci		.aead = {
244662306a36Sopenharmony_ci			.base = {
244762306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha1),cbc(des))",
244862306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha1-"
244962306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
245062306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
245162306a36Sopenharmony_ci			},
245262306a36Sopenharmony_ci			.setkey = aead_setkey,
245362306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
245462306a36Sopenharmony_ci			.encrypt = aead_encrypt,
245562306a36Sopenharmony_ci			.decrypt = aead_decrypt,
245662306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
245762306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
245862306a36Sopenharmony_ci		},
245962306a36Sopenharmony_ci		.caam = {
246062306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
246162306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
246262306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
246362306a36Sopenharmony_ci		},
246462306a36Sopenharmony_ci	},
246562306a36Sopenharmony_ci	{
246662306a36Sopenharmony_ci		.aead = {
246762306a36Sopenharmony_ci			.base = {
246862306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha1),"
246962306a36Sopenharmony_ci					    "cbc(des)))",
247062306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
247162306a36Sopenharmony_ci						   "hmac-sha1-cbc-des-caam-qi2",
247262306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
247362306a36Sopenharmony_ci			},
247462306a36Sopenharmony_ci			.setkey = aead_setkey,
247562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
247662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
247762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
247862306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
247962306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
248062306a36Sopenharmony_ci		},
248162306a36Sopenharmony_ci		.caam = {
248262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
248362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
248462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
248562306a36Sopenharmony_ci			.geniv = true,
248662306a36Sopenharmony_ci		}
248762306a36Sopenharmony_ci	},
248862306a36Sopenharmony_ci	{
248962306a36Sopenharmony_ci		.aead = {
249062306a36Sopenharmony_ci			.base = {
249162306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha224),cbc(des))",
249262306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha224-"
249362306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
249462306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
249562306a36Sopenharmony_ci			},
249662306a36Sopenharmony_ci			.setkey = aead_setkey,
249762306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
249862306a36Sopenharmony_ci			.encrypt = aead_encrypt,
249962306a36Sopenharmony_ci			.decrypt = aead_decrypt,
250062306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
250162306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
250262306a36Sopenharmony_ci		},
250362306a36Sopenharmony_ci		.caam = {
250462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
250562306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
250662306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
250762306a36Sopenharmony_ci		},
250862306a36Sopenharmony_ci	},
250962306a36Sopenharmony_ci	{
251062306a36Sopenharmony_ci		.aead = {
251162306a36Sopenharmony_ci			.base = {
251262306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha224),"
251362306a36Sopenharmony_ci					    "cbc(des)))",
251462306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
251562306a36Sopenharmony_ci						   "hmac-sha224-cbc-des-"
251662306a36Sopenharmony_ci						   "caam-qi2",
251762306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
251862306a36Sopenharmony_ci			},
251962306a36Sopenharmony_ci			.setkey = aead_setkey,
252062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
252162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
252262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
252362306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
252462306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
252562306a36Sopenharmony_ci		},
252662306a36Sopenharmony_ci		.caam = {
252762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
252862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
252962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
253062306a36Sopenharmony_ci			.geniv = true,
253162306a36Sopenharmony_ci		}
253262306a36Sopenharmony_ci	},
253362306a36Sopenharmony_ci	{
253462306a36Sopenharmony_ci		.aead = {
253562306a36Sopenharmony_ci			.base = {
253662306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha256),cbc(des))",
253762306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha256-"
253862306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
253962306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
254062306a36Sopenharmony_ci			},
254162306a36Sopenharmony_ci			.setkey = aead_setkey,
254262306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
254362306a36Sopenharmony_ci			.encrypt = aead_encrypt,
254462306a36Sopenharmony_ci			.decrypt = aead_decrypt,
254562306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
254662306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
254762306a36Sopenharmony_ci		},
254862306a36Sopenharmony_ci		.caam = {
254962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
255062306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
255162306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
255262306a36Sopenharmony_ci		},
255362306a36Sopenharmony_ci	},
255462306a36Sopenharmony_ci	{
255562306a36Sopenharmony_ci		.aead = {
255662306a36Sopenharmony_ci			.base = {
255762306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha256),"
255862306a36Sopenharmony_ci					    "cbc(des)))",
255962306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
256062306a36Sopenharmony_ci						   "hmac-sha256-cbc-des-"
256162306a36Sopenharmony_ci						   "caam-qi2",
256262306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
256362306a36Sopenharmony_ci			},
256462306a36Sopenharmony_ci			.setkey = aead_setkey,
256562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
256662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
256762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
256862306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
256962306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
257062306a36Sopenharmony_ci		},
257162306a36Sopenharmony_ci		.caam = {
257262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
257362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
257462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
257562306a36Sopenharmony_ci			.geniv = true,
257662306a36Sopenharmony_ci		},
257762306a36Sopenharmony_ci	},
257862306a36Sopenharmony_ci	{
257962306a36Sopenharmony_ci		.aead = {
258062306a36Sopenharmony_ci			.base = {
258162306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha384),cbc(des))",
258262306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha384-"
258362306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
258462306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
258562306a36Sopenharmony_ci			},
258662306a36Sopenharmony_ci			.setkey = aead_setkey,
258762306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
258862306a36Sopenharmony_ci			.encrypt = aead_encrypt,
258962306a36Sopenharmony_ci			.decrypt = aead_decrypt,
259062306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
259162306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
259262306a36Sopenharmony_ci		},
259362306a36Sopenharmony_ci		.caam = {
259462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
259562306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
259662306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
259762306a36Sopenharmony_ci		},
259862306a36Sopenharmony_ci	},
259962306a36Sopenharmony_ci	{
260062306a36Sopenharmony_ci		.aead = {
260162306a36Sopenharmony_ci			.base = {
260262306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha384),"
260362306a36Sopenharmony_ci					    "cbc(des)))",
260462306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
260562306a36Sopenharmony_ci						   "hmac-sha384-cbc-des-"
260662306a36Sopenharmony_ci						   "caam-qi2",
260762306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
260862306a36Sopenharmony_ci			},
260962306a36Sopenharmony_ci			.setkey = aead_setkey,
261062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
261162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
261262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
261362306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
261462306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
261562306a36Sopenharmony_ci		},
261662306a36Sopenharmony_ci		.caam = {
261762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
261862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
261962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
262062306a36Sopenharmony_ci			.geniv = true,
262162306a36Sopenharmony_ci		}
262262306a36Sopenharmony_ci	},
262362306a36Sopenharmony_ci	{
262462306a36Sopenharmony_ci		.aead = {
262562306a36Sopenharmony_ci			.base = {
262662306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha512),cbc(des))",
262762306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha512-"
262862306a36Sopenharmony_ci						   "cbc-des-caam-qi2",
262962306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
263062306a36Sopenharmony_ci			},
263162306a36Sopenharmony_ci			.setkey = aead_setkey,
263262306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
263362306a36Sopenharmony_ci			.encrypt = aead_encrypt,
263462306a36Sopenharmony_ci			.decrypt = aead_decrypt,
263562306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
263662306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
263762306a36Sopenharmony_ci		},
263862306a36Sopenharmony_ci		.caam = {
263962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
264062306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
264162306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
264262306a36Sopenharmony_ci		}
264362306a36Sopenharmony_ci	},
264462306a36Sopenharmony_ci	{
264562306a36Sopenharmony_ci		.aead = {
264662306a36Sopenharmony_ci			.base = {
264762306a36Sopenharmony_ci				.cra_name = "echainiv(authenc(hmac(sha512),"
264862306a36Sopenharmony_ci					    "cbc(des)))",
264962306a36Sopenharmony_ci				.cra_driver_name = "echainiv-authenc-"
265062306a36Sopenharmony_ci						   "hmac-sha512-cbc-des-"
265162306a36Sopenharmony_ci						   "caam-qi2",
265262306a36Sopenharmony_ci				.cra_blocksize = DES_BLOCK_SIZE,
265362306a36Sopenharmony_ci			},
265462306a36Sopenharmony_ci			.setkey = aead_setkey,
265562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
265662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
265762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
265862306a36Sopenharmony_ci			.ivsize = DES_BLOCK_SIZE,
265962306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
266062306a36Sopenharmony_ci		},
266162306a36Sopenharmony_ci		.caam = {
266262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
266362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
266462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
266562306a36Sopenharmony_ci			.geniv = true,
266662306a36Sopenharmony_ci		}
266762306a36Sopenharmony_ci	},
266862306a36Sopenharmony_ci	{
266962306a36Sopenharmony_ci		.aead = {
267062306a36Sopenharmony_ci			.base = {
267162306a36Sopenharmony_ci				.cra_name = "authenc(hmac(md5),"
267262306a36Sopenharmony_ci					    "rfc3686(ctr(aes)))",
267362306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-md5-"
267462306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
267562306a36Sopenharmony_ci				.cra_blocksize = 1,
267662306a36Sopenharmony_ci			},
267762306a36Sopenharmony_ci			.setkey = aead_setkey,
267862306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
267962306a36Sopenharmony_ci			.encrypt = aead_encrypt,
268062306a36Sopenharmony_ci			.decrypt = aead_decrypt,
268162306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
268262306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
268362306a36Sopenharmony_ci		},
268462306a36Sopenharmony_ci		.caam = {
268562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
268662306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
268762306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
268862306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
268962306a36Sopenharmony_ci			.rfc3686 = true,
269062306a36Sopenharmony_ci		},
269162306a36Sopenharmony_ci	},
269262306a36Sopenharmony_ci	{
269362306a36Sopenharmony_ci		.aead = {
269462306a36Sopenharmony_ci			.base = {
269562306a36Sopenharmony_ci				.cra_name = "seqiv(authenc("
269662306a36Sopenharmony_ci					    "hmac(md5),rfc3686(ctr(aes))))",
269762306a36Sopenharmony_ci				.cra_driver_name = "seqiv-authenc-hmac-md5-"
269862306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
269962306a36Sopenharmony_ci				.cra_blocksize = 1,
270062306a36Sopenharmony_ci			},
270162306a36Sopenharmony_ci			.setkey = aead_setkey,
270262306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
270362306a36Sopenharmony_ci			.encrypt = aead_encrypt,
270462306a36Sopenharmony_ci			.decrypt = aead_decrypt,
270562306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
270662306a36Sopenharmony_ci			.maxauthsize = MD5_DIGEST_SIZE,
270762306a36Sopenharmony_ci		},
270862306a36Sopenharmony_ci		.caam = {
270962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
271062306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
271162306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
271262306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
271362306a36Sopenharmony_ci			.rfc3686 = true,
271462306a36Sopenharmony_ci			.geniv = true,
271562306a36Sopenharmony_ci		},
271662306a36Sopenharmony_ci	},
271762306a36Sopenharmony_ci	{
271862306a36Sopenharmony_ci		.aead = {
271962306a36Sopenharmony_ci			.base = {
272062306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha1),"
272162306a36Sopenharmony_ci					    "rfc3686(ctr(aes)))",
272262306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha1-"
272362306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
272462306a36Sopenharmony_ci				.cra_blocksize = 1,
272562306a36Sopenharmony_ci			},
272662306a36Sopenharmony_ci			.setkey = aead_setkey,
272762306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
272862306a36Sopenharmony_ci			.encrypt = aead_encrypt,
272962306a36Sopenharmony_ci			.decrypt = aead_decrypt,
273062306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
273162306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
273262306a36Sopenharmony_ci		},
273362306a36Sopenharmony_ci		.caam = {
273462306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
273562306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
273662306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
273762306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
273862306a36Sopenharmony_ci			.rfc3686 = true,
273962306a36Sopenharmony_ci		},
274062306a36Sopenharmony_ci	},
274162306a36Sopenharmony_ci	{
274262306a36Sopenharmony_ci		.aead = {
274362306a36Sopenharmony_ci			.base = {
274462306a36Sopenharmony_ci				.cra_name = "seqiv(authenc("
274562306a36Sopenharmony_ci					    "hmac(sha1),rfc3686(ctr(aes))))",
274662306a36Sopenharmony_ci				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
274762306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
274862306a36Sopenharmony_ci				.cra_blocksize = 1,
274962306a36Sopenharmony_ci			},
275062306a36Sopenharmony_ci			.setkey = aead_setkey,
275162306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
275262306a36Sopenharmony_ci			.encrypt = aead_encrypt,
275362306a36Sopenharmony_ci			.decrypt = aead_decrypt,
275462306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
275562306a36Sopenharmony_ci			.maxauthsize = SHA1_DIGEST_SIZE,
275662306a36Sopenharmony_ci		},
275762306a36Sopenharmony_ci		.caam = {
275862306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
275962306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
276062306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
276162306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
276262306a36Sopenharmony_ci			.rfc3686 = true,
276362306a36Sopenharmony_ci			.geniv = true,
276462306a36Sopenharmony_ci		},
276562306a36Sopenharmony_ci	},
276662306a36Sopenharmony_ci	{
276762306a36Sopenharmony_ci		.aead = {
276862306a36Sopenharmony_ci			.base = {
276962306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha224),"
277062306a36Sopenharmony_ci					    "rfc3686(ctr(aes)))",
277162306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha224-"
277262306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
277362306a36Sopenharmony_ci				.cra_blocksize = 1,
277462306a36Sopenharmony_ci			},
277562306a36Sopenharmony_ci			.setkey = aead_setkey,
277662306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
277762306a36Sopenharmony_ci			.encrypt = aead_encrypt,
277862306a36Sopenharmony_ci			.decrypt = aead_decrypt,
277962306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
278062306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
278162306a36Sopenharmony_ci		},
278262306a36Sopenharmony_ci		.caam = {
278362306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
278462306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
278562306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
278662306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
278762306a36Sopenharmony_ci			.rfc3686 = true,
278862306a36Sopenharmony_ci		},
278962306a36Sopenharmony_ci	},
279062306a36Sopenharmony_ci	{
279162306a36Sopenharmony_ci		.aead = {
279262306a36Sopenharmony_ci			.base = {
279362306a36Sopenharmony_ci				.cra_name = "seqiv(authenc("
279462306a36Sopenharmony_ci					    "hmac(sha224),rfc3686(ctr(aes))))",
279562306a36Sopenharmony_ci				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
279662306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
279762306a36Sopenharmony_ci				.cra_blocksize = 1,
279862306a36Sopenharmony_ci			},
279962306a36Sopenharmony_ci			.setkey = aead_setkey,
280062306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
280162306a36Sopenharmony_ci			.encrypt = aead_encrypt,
280262306a36Sopenharmony_ci			.decrypt = aead_decrypt,
280362306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
280462306a36Sopenharmony_ci			.maxauthsize = SHA224_DIGEST_SIZE,
280562306a36Sopenharmony_ci		},
280662306a36Sopenharmony_ci		.caam = {
280762306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
280862306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
280962306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
281062306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
281162306a36Sopenharmony_ci			.rfc3686 = true,
281262306a36Sopenharmony_ci			.geniv = true,
281362306a36Sopenharmony_ci		},
281462306a36Sopenharmony_ci	},
281562306a36Sopenharmony_ci	{
281662306a36Sopenharmony_ci		.aead = {
281762306a36Sopenharmony_ci			.base = {
281862306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha256),"
281962306a36Sopenharmony_ci					    "rfc3686(ctr(aes)))",
282062306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha256-"
282162306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
282262306a36Sopenharmony_ci				.cra_blocksize = 1,
282362306a36Sopenharmony_ci			},
282462306a36Sopenharmony_ci			.setkey = aead_setkey,
282562306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
282662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
282762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
282862306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
282962306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
283062306a36Sopenharmony_ci		},
283162306a36Sopenharmony_ci		.caam = {
283262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
283362306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
283462306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
283562306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
283662306a36Sopenharmony_ci			.rfc3686 = true,
283762306a36Sopenharmony_ci		},
283862306a36Sopenharmony_ci	},
283962306a36Sopenharmony_ci	{
284062306a36Sopenharmony_ci		.aead = {
284162306a36Sopenharmony_ci			.base = {
284262306a36Sopenharmony_ci				.cra_name = "seqiv(authenc(hmac(sha256),"
284362306a36Sopenharmony_ci					    "rfc3686(ctr(aes))))",
284462306a36Sopenharmony_ci				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
284562306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
284662306a36Sopenharmony_ci				.cra_blocksize = 1,
284762306a36Sopenharmony_ci			},
284862306a36Sopenharmony_ci			.setkey = aead_setkey,
284962306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
285062306a36Sopenharmony_ci			.encrypt = aead_encrypt,
285162306a36Sopenharmony_ci			.decrypt = aead_decrypt,
285262306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
285362306a36Sopenharmony_ci			.maxauthsize = SHA256_DIGEST_SIZE,
285462306a36Sopenharmony_ci		},
285562306a36Sopenharmony_ci		.caam = {
285662306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
285762306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
285862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
285962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
286062306a36Sopenharmony_ci			.rfc3686 = true,
286162306a36Sopenharmony_ci			.geniv = true,
286262306a36Sopenharmony_ci		},
286362306a36Sopenharmony_ci	},
286462306a36Sopenharmony_ci	{
286562306a36Sopenharmony_ci		.aead = {
286662306a36Sopenharmony_ci			.base = {
286762306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha384),"
286862306a36Sopenharmony_ci					    "rfc3686(ctr(aes)))",
286962306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha384-"
287062306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
287162306a36Sopenharmony_ci				.cra_blocksize = 1,
287262306a36Sopenharmony_ci			},
287362306a36Sopenharmony_ci			.setkey = aead_setkey,
287462306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
287562306a36Sopenharmony_ci			.encrypt = aead_encrypt,
287662306a36Sopenharmony_ci			.decrypt = aead_decrypt,
287762306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
287862306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
287962306a36Sopenharmony_ci		},
288062306a36Sopenharmony_ci		.caam = {
288162306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
288262306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
288362306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
288462306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
288562306a36Sopenharmony_ci			.rfc3686 = true,
288662306a36Sopenharmony_ci		},
288762306a36Sopenharmony_ci	},
288862306a36Sopenharmony_ci	{
288962306a36Sopenharmony_ci		.aead = {
289062306a36Sopenharmony_ci			.base = {
289162306a36Sopenharmony_ci				.cra_name = "seqiv(authenc(hmac(sha384),"
289262306a36Sopenharmony_ci					    "rfc3686(ctr(aes))))",
289362306a36Sopenharmony_ci				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
289462306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
289562306a36Sopenharmony_ci				.cra_blocksize = 1,
289662306a36Sopenharmony_ci			},
289762306a36Sopenharmony_ci			.setkey = aead_setkey,
289862306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
289962306a36Sopenharmony_ci			.encrypt = aead_encrypt,
290062306a36Sopenharmony_ci			.decrypt = aead_decrypt,
290162306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
290262306a36Sopenharmony_ci			.maxauthsize = SHA384_DIGEST_SIZE,
290362306a36Sopenharmony_ci		},
290462306a36Sopenharmony_ci		.caam = {
290562306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
290662306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
290762306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
290862306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
290962306a36Sopenharmony_ci			.rfc3686 = true,
291062306a36Sopenharmony_ci			.geniv = true,
291162306a36Sopenharmony_ci		},
291262306a36Sopenharmony_ci	},
291362306a36Sopenharmony_ci	{
291462306a36Sopenharmony_ci		.aead = {
291562306a36Sopenharmony_ci			.base = {
291662306a36Sopenharmony_ci				.cra_name = "rfc7539(chacha20,poly1305)",
291762306a36Sopenharmony_ci				.cra_driver_name = "rfc7539-chacha20-poly1305-"
291862306a36Sopenharmony_ci						   "caam-qi2",
291962306a36Sopenharmony_ci				.cra_blocksize = 1,
292062306a36Sopenharmony_ci			},
292162306a36Sopenharmony_ci			.setkey = chachapoly_setkey,
292262306a36Sopenharmony_ci			.setauthsize = chachapoly_setauthsize,
292362306a36Sopenharmony_ci			.encrypt = aead_encrypt,
292462306a36Sopenharmony_ci			.decrypt = aead_decrypt,
292562306a36Sopenharmony_ci			.ivsize = CHACHAPOLY_IV_SIZE,
292662306a36Sopenharmony_ci			.maxauthsize = POLY1305_DIGEST_SIZE,
292762306a36Sopenharmony_ci		},
292862306a36Sopenharmony_ci		.caam = {
292962306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
293062306a36Sopenharmony_ci					   OP_ALG_AAI_AEAD,
293162306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
293262306a36Sopenharmony_ci					   OP_ALG_AAI_AEAD,
293362306a36Sopenharmony_ci			.nodkp = true,
293462306a36Sopenharmony_ci		},
293562306a36Sopenharmony_ci	},
293662306a36Sopenharmony_ci	{
293762306a36Sopenharmony_ci		.aead = {
293862306a36Sopenharmony_ci			.base = {
293962306a36Sopenharmony_ci				.cra_name = "rfc7539esp(chacha20,poly1305)",
294062306a36Sopenharmony_ci				.cra_driver_name = "rfc7539esp-chacha20-"
294162306a36Sopenharmony_ci						   "poly1305-caam-qi2",
294262306a36Sopenharmony_ci				.cra_blocksize = 1,
294362306a36Sopenharmony_ci			},
294462306a36Sopenharmony_ci			.setkey = chachapoly_setkey,
294562306a36Sopenharmony_ci			.setauthsize = chachapoly_setauthsize,
294662306a36Sopenharmony_ci			.encrypt = aead_encrypt,
294762306a36Sopenharmony_ci			.decrypt = aead_decrypt,
294862306a36Sopenharmony_ci			.ivsize = 8,
294962306a36Sopenharmony_ci			.maxauthsize = POLY1305_DIGEST_SIZE,
295062306a36Sopenharmony_ci		},
295162306a36Sopenharmony_ci		.caam = {
295262306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
295362306a36Sopenharmony_ci					   OP_ALG_AAI_AEAD,
295462306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
295562306a36Sopenharmony_ci					   OP_ALG_AAI_AEAD,
295662306a36Sopenharmony_ci			.nodkp = true,
295762306a36Sopenharmony_ci		},
295862306a36Sopenharmony_ci	},
295962306a36Sopenharmony_ci	{
296062306a36Sopenharmony_ci		.aead = {
296162306a36Sopenharmony_ci			.base = {
296262306a36Sopenharmony_ci				.cra_name = "authenc(hmac(sha512),"
296362306a36Sopenharmony_ci					    "rfc3686(ctr(aes)))",
296462306a36Sopenharmony_ci				.cra_driver_name = "authenc-hmac-sha512-"
296562306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
296662306a36Sopenharmony_ci				.cra_blocksize = 1,
296762306a36Sopenharmony_ci			},
296862306a36Sopenharmony_ci			.setkey = aead_setkey,
296962306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
297062306a36Sopenharmony_ci			.encrypt = aead_encrypt,
297162306a36Sopenharmony_ci			.decrypt = aead_decrypt,
297262306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
297362306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
297462306a36Sopenharmony_ci		},
297562306a36Sopenharmony_ci		.caam = {
297662306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
297762306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
297862306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
297962306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
298062306a36Sopenharmony_ci			.rfc3686 = true,
298162306a36Sopenharmony_ci		},
298262306a36Sopenharmony_ci	},
298362306a36Sopenharmony_ci	{
298462306a36Sopenharmony_ci		.aead = {
298562306a36Sopenharmony_ci			.base = {
298662306a36Sopenharmony_ci				.cra_name = "seqiv(authenc(hmac(sha512),"
298762306a36Sopenharmony_ci					    "rfc3686(ctr(aes))))",
298862306a36Sopenharmony_ci				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
298962306a36Sopenharmony_ci						   "rfc3686-ctr-aes-caam-qi2",
299062306a36Sopenharmony_ci				.cra_blocksize = 1,
299162306a36Sopenharmony_ci			},
299262306a36Sopenharmony_ci			.setkey = aead_setkey,
299362306a36Sopenharmony_ci			.setauthsize = aead_setauthsize,
299462306a36Sopenharmony_ci			.encrypt = aead_encrypt,
299562306a36Sopenharmony_ci			.decrypt = aead_decrypt,
299662306a36Sopenharmony_ci			.ivsize = CTR_RFC3686_IV_SIZE,
299762306a36Sopenharmony_ci			.maxauthsize = SHA512_DIGEST_SIZE,
299862306a36Sopenharmony_ci		},
299962306a36Sopenharmony_ci		.caam = {
300062306a36Sopenharmony_ci			.class1_alg_type = OP_ALG_ALGSEL_AES |
300162306a36Sopenharmony_ci					   OP_ALG_AAI_CTR_MOD128,
300262306a36Sopenharmony_ci			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
300362306a36Sopenharmony_ci					   OP_ALG_AAI_HMAC_PRECOMP,
300462306a36Sopenharmony_ci			.rfc3686 = true,
300562306a36Sopenharmony_ci			.geniv = true,
300662306a36Sopenharmony_ci		},
300762306a36Sopenharmony_ci	},
300862306a36Sopenharmony_ci};
300962306a36Sopenharmony_ci
301062306a36Sopenharmony_cistatic void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
301162306a36Sopenharmony_ci{
301262306a36Sopenharmony_ci	struct skcipher_alg *alg = &t_alg->skcipher;
301362306a36Sopenharmony_ci
301462306a36Sopenharmony_ci	alg->base.cra_module = THIS_MODULE;
301562306a36Sopenharmony_ci	alg->base.cra_priority = CAAM_CRA_PRIORITY;
301662306a36Sopenharmony_ci	alg->base.cra_ctxsize = sizeof(struct caam_ctx) + crypto_dma_padding();
301762306a36Sopenharmony_ci	alg->base.cra_flags |= (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
301862306a36Sopenharmony_ci			      CRYPTO_ALG_KERN_DRIVER_ONLY);
301962306a36Sopenharmony_ci
302062306a36Sopenharmony_ci	alg->init = caam_cra_init_skcipher;
302162306a36Sopenharmony_ci	alg->exit = caam_cra_exit;
302262306a36Sopenharmony_ci}
302362306a36Sopenharmony_ci
302462306a36Sopenharmony_cistatic void caam_aead_alg_init(struct caam_aead_alg *t_alg)
302562306a36Sopenharmony_ci{
302662306a36Sopenharmony_ci	struct aead_alg *alg = &t_alg->aead;
302762306a36Sopenharmony_ci
302862306a36Sopenharmony_ci	alg->base.cra_module = THIS_MODULE;
302962306a36Sopenharmony_ci	alg->base.cra_priority = CAAM_CRA_PRIORITY;
303062306a36Sopenharmony_ci	alg->base.cra_ctxsize = sizeof(struct caam_ctx) + crypto_dma_padding();
303162306a36Sopenharmony_ci	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
303262306a36Sopenharmony_ci			      CRYPTO_ALG_KERN_DRIVER_ONLY;
303362306a36Sopenharmony_ci
303462306a36Sopenharmony_ci	alg->init = caam_cra_init_aead;
303562306a36Sopenharmony_ci	alg->exit = caam_cra_exit_aead;
303662306a36Sopenharmony_ci}
303762306a36Sopenharmony_ci
303862306a36Sopenharmony_ci/* max hash key is max split key size */
303962306a36Sopenharmony_ci#define CAAM_MAX_HASH_KEY_SIZE		(SHA512_DIGEST_SIZE * 2)
304062306a36Sopenharmony_ci
304162306a36Sopenharmony_ci#define CAAM_MAX_HASH_BLOCK_SIZE	SHA512_BLOCK_SIZE
304262306a36Sopenharmony_ci
304362306a36Sopenharmony_ci/* caam context sizes for hashes: running digest + 8 */
304462306a36Sopenharmony_ci#define HASH_MSG_LEN			8
304562306a36Sopenharmony_ci#define MAX_CTX_LEN			(HASH_MSG_LEN + SHA512_DIGEST_SIZE)
304662306a36Sopenharmony_ci
304762306a36Sopenharmony_cienum hash_optype {
304862306a36Sopenharmony_ci	UPDATE = 0,
304962306a36Sopenharmony_ci	UPDATE_FIRST,
305062306a36Sopenharmony_ci	FINALIZE,
305162306a36Sopenharmony_ci	DIGEST,
305262306a36Sopenharmony_ci	HASH_NUM_OP
305362306a36Sopenharmony_ci};
305462306a36Sopenharmony_ci
305562306a36Sopenharmony_ci/**
305662306a36Sopenharmony_ci * struct caam_hash_ctx - ahash per-session context
305762306a36Sopenharmony_ci * @flc: Flow Contexts array
305862306a36Sopenharmony_ci * @key: authentication key
305962306a36Sopenharmony_ci * @flc_dma: I/O virtual addresses of the Flow Contexts
306062306a36Sopenharmony_ci * @dev: dpseci device
306162306a36Sopenharmony_ci * @ctx_len: size of Context Register
306262306a36Sopenharmony_ci * @adata: hashing algorithm details
306362306a36Sopenharmony_ci */
306462306a36Sopenharmony_cistruct caam_hash_ctx {
306562306a36Sopenharmony_ci	struct caam_flc flc[HASH_NUM_OP];
306662306a36Sopenharmony_ci	u8 key[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned;
306762306a36Sopenharmony_ci	dma_addr_t flc_dma[HASH_NUM_OP];
306862306a36Sopenharmony_ci	struct device *dev;
306962306a36Sopenharmony_ci	int ctx_len;
307062306a36Sopenharmony_ci	struct alginfo adata;
307162306a36Sopenharmony_ci};
307262306a36Sopenharmony_ci
307362306a36Sopenharmony_ci/* ahash state */
307462306a36Sopenharmony_cistruct caam_hash_state {
307562306a36Sopenharmony_ci	struct caam_request caam_req;
307662306a36Sopenharmony_ci	dma_addr_t buf_dma;
307762306a36Sopenharmony_ci	dma_addr_t ctx_dma;
307862306a36Sopenharmony_ci	int ctx_dma_len;
307962306a36Sopenharmony_ci	u8 buf[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned;
308062306a36Sopenharmony_ci	int buflen;
308162306a36Sopenharmony_ci	int next_buflen;
308262306a36Sopenharmony_ci	u8 caam_ctx[MAX_CTX_LEN] ____cacheline_aligned;
308362306a36Sopenharmony_ci	int (*update)(struct ahash_request *req);
308462306a36Sopenharmony_ci	int (*final)(struct ahash_request *req);
308562306a36Sopenharmony_ci	int (*finup)(struct ahash_request *req);
308662306a36Sopenharmony_ci};
308762306a36Sopenharmony_ci
308862306a36Sopenharmony_cistruct caam_export_state {
308962306a36Sopenharmony_ci	u8 buf[CAAM_MAX_HASH_BLOCK_SIZE];
309062306a36Sopenharmony_ci	u8 caam_ctx[MAX_CTX_LEN];
309162306a36Sopenharmony_ci	int buflen;
309262306a36Sopenharmony_ci	int (*update)(struct ahash_request *req);
309362306a36Sopenharmony_ci	int (*final)(struct ahash_request *req);
309462306a36Sopenharmony_ci	int (*finup)(struct ahash_request *req);
309562306a36Sopenharmony_ci};
309662306a36Sopenharmony_ci
309762306a36Sopenharmony_ci/* Map current buffer in state (if length > 0) and put it in link table */
309862306a36Sopenharmony_cistatic inline int buf_map_to_qm_sg(struct device *dev,
309962306a36Sopenharmony_ci				   struct dpaa2_sg_entry *qm_sg,
310062306a36Sopenharmony_ci				   struct caam_hash_state *state)
310162306a36Sopenharmony_ci{
310262306a36Sopenharmony_ci	int buflen = state->buflen;
310362306a36Sopenharmony_ci
310462306a36Sopenharmony_ci	if (!buflen)
310562306a36Sopenharmony_ci		return 0;
310662306a36Sopenharmony_ci
310762306a36Sopenharmony_ci	state->buf_dma = dma_map_single(dev, state->buf, buflen,
310862306a36Sopenharmony_ci					DMA_TO_DEVICE);
310962306a36Sopenharmony_ci	if (dma_mapping_error(dev, state->buf_dma)) {
311062306a36Sopenharmony_ci		dev_err(dev, "unable to map buf\n");
311162306a36Sopenharmony_ci		state->buf_dma = 0;
311262306a36Sopenharmony_ci		return -ENOMEM;
311362306a36Sopenharmony_ci	}
311462306a36Sopenharmony_ci
311562306a36Sopenharmony_ci	dma_to_qm_sg_one(qm_sg, state->buf_dma, buflen, 0);
311662306a36Sopenharmony_ci
311762306a36Sopenharmony_ci	return 0;
311862306a36Sopenharmony_ci}
311962306a36Sopenharmony_ci
312062306a36Sopenharmony_ci/* Map state->caam_ctx, and add it to link table */
312162306a36Sopenharmony_cistatic inline int ctx_map_to_qm_sg(struct device *dev,
312262306a36Sopenharmony_ci				   struct caam_hash_state *state, int ctx_len,
312362306a36Sopenharmony_ci				   struct dpaa2_sg_entry *qm_sg, u32 flag)
312462306a36Sopenharmony_ci{
312562306a36Sopenharmony_ci	state->ctx_dma_len = ctx_len;
312662306a36Sopenharmony_ci	state->ctx_dma = dma_map_single(dev, state->caam_ctx, ctx_len, flag);
312762306a36Sopenharmony_ci	if (dma_mapping_error(dev, state->ctx_dma)) {
312862306a36Sopenharmony_ci		dev_err(dev, "unable to map ctx\n");
312962306a36Sopenharmony_ci		state->ctx_dma = 0;
313062306a36Sopenharmony_ci		return -ENOMEM;
313162306a36Sopenharmony_ci	}
313262306a36Sopenharmony_ci
313362306a36Sopenharmony_ci	dma_to_qm_sg_one(qm_sg, state->ctx_dma, ctx_len, 0);
313462306a36Sopenharmony_ci
313562306a36Sopenharmony_ci	return 0;
313662306a36Sopenharmony_ci}
313762306a36Sopenharmony_ci
313862306a36Sopenharmony_cistatic int ahash_set_sh_desc(struct crypto_ahash *ahash)
313962306a36Sopenharmony_ci{
314062306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
314162306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
314262306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev);
314362306a36Sopenharmony_ci	struct caam_flc *flc;
314462306a36Sopenharmony_ci	u32 *desc;
314562306a36Sopenharmony_ci
314662306a36Sopenharmony_ci	/* ahash_update shared descriptor */
314762306a36Sopenharmony_ci	flc = &ctx->flc[UPDATE];
314862306a36Sopenharmony_ci	desc = flc->sh_desc;
314962306a36Sopenharmony_ci	cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_UPDATE, ctx->ctx_len,
315062306a36Sopenharmony_ci			  ctx->ctx_len, true, priv->sec_attr.era);
315162306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
315262306a36Sopenharmony_ci	dma_sync_single_for_device(ctx->dev, ctx->flc_dma[UPDATE],
315362306a36Sopenharmony_ci				   desc_bytes(desc), DMA_BIDIRECTIONAL);
315462306a36Sopenharmony_ci	print_hex_dump_debug("ahash update shdesc@" __stringify(__LINE__)": ",
315562306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
315662306a36Sopenharmony_ci			     1);
315762306a36Sopenharmony_ci
315862306a36Sopenharmony_ci	/* ahash_update_first shared descriptor */
315962306a36Sopenharmony_ci	flc = &ctx->flc[UPDATE_FIRST];
316062306a36Sopenharmony_ci	desc = flc->sh_desc;
316162306a36Sopenharmony_ci	cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INIT, ctx->ctx_len,
316262306a36Sopenharmony_ci			  ctx->ctx_len, false, priv->sec_attr.era);
316362306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
316462306a36Sopenharmony_ci	dma_sync_single_for_device(ctx->dev, ctx->flc_dma[UPDATE_FIRST],
316562306a36Sopenharmony_ci				   desc_bytes(desc), DMA_BIDIRECTIONAL);
316662306a36Sopenharmony_ci	print_hex_dump_debug("ahash update first shdesc@" __stringify(__LINE__)": ",
316762306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
316862306a36Sopenharmony_ci			     1);
316962306a36Sopenharmony_ci
317062306a36Sopenharmony_ci	/* ahash_final shared descriptor */
317162306a36Sopenharmony_ci	flc = &ctx->flc[FINALIZE];
317262306a36Sopenharmony_ci	desc = flc->sh_desc;
317362306a36Sopenharmony_ci	cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_FINALIZE, digestsize,
317462306a36Sopenharmony_ci			  ctx->ctx_len, true, priv->sec_attr.era);
317562306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
317662306a36Sopenharmony_ci	dma_sync_single_for_device(ctx->dev, ctx->flc_dma[FINALIZE],
317762306a36Sopenharmony_ci				   desc_bytes(desc), DMA_BIDIRECTIONAL);
317862306a36Sopenharmony_ci	print_hex_dump_debug("ahash final shdesc@" __stringify(__LINE__)": ",
317962306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
318062306a36Sopenharmony_ci			     1);
318162306a36Sopenharmony_ci
318262306a36Sopenharmony_ci	/* ahash_digest shared descriptor */
318362306a36Sopenharmony_ci	flc = &ctx->flc[DIGEST];
318462306a36Sopenharmony_ci	desc = flc->sh_desc;
318562306a36Sopenharmony_ci	cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INITFINAL, digestsize,
318662306a36Sopenharmony_ci			  ctx->ctx_len, false, priv->sec_attr.era);
318762306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
318862306a36Sopenharmony_ci	dma_sync_single_for_device(ctx->dev, ctx->flc_dma[DIGEST],
318962306a36Sopenharmony_ci				   desc_bytes(desc), DMA_BIDIRECTIONAL);
319062306a36Sopenharmony_ci	print_hex_dump_debug("ahash digest shdesc@" __stringify(__LINE__)": ",
319162306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
319262306a36Sopenharmony_ci			     1);
319362306a36Sopenharmony_ci
319462306a36Sopenharmony_ci	return 0;
319562306a36Sopenharmony_ci}
319662306a36Sopenharmony_ci
319762306a36Sopenharmony_cistruct split_key_sh_result {
319862306a36Sopenharmony_ci	struct completion completion;
319962306a36Sopenharmony_ci	int err;
320062306a36Sopenharmony_ci	struct device *dev;
320162306a36Sopenharmony_ci};
320262306a36Sopenharmony_ci
320362306a36Sopenharmony_cistatic void split_key_sh_done(void *cbk_ctx, u32 err)
320462306a36Sopenharmony_ci{
320562306a36Sopenharmony_ci	struct split_key_sh_result *res = cbk_ctx;
320662306a36Sopenharmony_ci
320762306a36Sopenharmony_ci	dev_dbg(res->dev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
320862306a36Sopenharmony_ci
320962306a36Sopenharmony_ci	res->err = err ? caam_qi2_strstatus(res->dev, err) : 0;
321062306a36Sopenharmony_ci	complete(&res->completion);
321162306a36Sopenharmony_ci}
321262306a36Sopenharmony_ci
321362306a36Sopenharmony_ci/* Digest hash size if it is too large */
321462306a36Sopenharmony_cistatic int hash_digest_key(struct caam_hash_ctx *ctx, u32 *keylen, u8 *key,
321562306a36Sopenharmony_ci			   u32 digestsize)
321662306a36Sopenharmony_ci{
321762306a36Sopenharmony_ci	struct caam_request *req_ctx;
321862306a36Sopenharmony_ci	u32 *desc;
321962306a36Sopenharmony_ci	struct split_key_sh_result result;
322062306a36Sopenharmony_ci	dma_addr_t key_dma;
322162306a36Sopenharmony_ci	struct caam_flc *flc;
322262306a36Sopenharmony_ci	dma_addr_t flc_dma;
322362306a36Sopenharmony_ci	int ret = -ENOMEM;
322462306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle, *out_fle;
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_ci	req_ctx = kzalloc(sizeof(*req_ctx), GFP_KERNEL);
322762306a36Sopenharmony_ci	if (!req_ctx)
322862306a36Sopenharmony_ci		return -ENOMEM;
322962306a36Sopenharmony_ci
323062306a36Sopenharmony_ci	in_fle = &req_ctx->fd_flt[1];
323162306a36Sopenharmony_ci	out_fle = &req_ctx->fd_flt[0];
323262306a36Sopenharmony_ci
323362306a36Sopenharmony_ci	flc = kzalloc(sizeof(*flc), GFP_KERNEL);
323462306a36Sopenharmony_ci	if (!flc)
323562306a36Sopenharmony_ci		goto err_flc;
323662306a36Sopenharmony_ci
323762306a36Sopenharmony_ci	key_dma = dma_map_single(ctx->dev, key, *keylen, DMA_BIDIRECTIONAL);
323862306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, key_dma)) {
323962306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map key memory\n");
324062306a36Sopenharmony_ci		goto err_key_dma;
324162306a36Sopenharmony_ci	}
324262306a36Sopenharmony_ci
324362306a36Sopenharmony_ci	desc = flc->sh_desc;
324462306a36Sopenharmony_ci
324562306a36Sopenharmony_ci	init_sh_desc(desc, 0);
324662306a36Sopenharmony_ci
324762306a36Sopenharmony_ci	/* descriptor to perform unkeyed hash on key_in */
324862306a36Sopenharmony_ci	append_operation(desc, ctx->adata.algtype | OP_ALG_ENCRYPT |
324962306a36Sopenharmony_ci			 OP_ALG_AS_INITFINAL);
325062306a36Sopenharmony_ci	append_seq_fifo_load(desc, *keylen, FIFOLD_CLASS_CLASS2 |
325162306a36Sopenharmony_ci			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_MSG);
325262306a36Sopenharmony_ci	append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
325362306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
325462306a36Sopenharmony_ci
325562306a36Sopenharmony_ci	flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
325662306a36Sopenharmony_ci	flc_dma = dma_map_single(ctx->dev, flc, sizeof(flc->flc) +
325762306a36Sopenharmony_ci				 desc_bytes(desc), DMA_TO_DEVICE);
325862306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, flc_dma)) {
325962306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map shared descriptor\n");
326062306a36Sopenharmony_ci		goto err_flc_dma;
326162306a36Sopenharmony_ci	}
326262306a36Sopenharmony_ci
326362306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
326462306a36Sopenharmony_ci	dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
326562306a36Sopenharmony_ci	dpaa2_fl_set_addr(in_fle, key_dma);
326662306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, *keylen);
326762306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
326862306a36Sopenharmony_ci	dpaa2_fl_set_addr(out_fle, key_dma);
326962306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, digestsize);
327062306a36Sopenharmony_ci
327162306a36Sopenharmony_ci	print_hex_dump_debug("key_in@" __stringify(__LINE__)": ",
327262306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1);
327362306a36Sopenharmony_ci	print_hex_dump_debug("shdesc@" __stringify(__LINE__)": ",
327462306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
327562306a36Sopenharmony_ci			     1);
327662306a36Sopenharmony_ci
327762306a36Sopenharmony_ci	result.err = 0;
327862306a36Sopenharmony_ci	init_completion(&result.completion);
327962306a36Sopenharmony_ci	result.dev = ctx->dev;
328062306a36Sopenharmony_ci
328162306a36Sopenharmony_ci	req_ctx->flc = flc;
328262306a36Sopenharmony_ci	req_ctx->flc_dma = flc_dma;
328362306a36Sopenharmony_ci	req_ctx->cbk = split_key_sh_done;
328462306a36Sopenharmony_ci	req_ctx->ctx = &result;
328562306a36Sopenharmony_ci
328662306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
328762306a36Sopenharmony_ci	if (ret == -EINPROGRESS) {
328862306a36Sopenharmony_ci		/* in progress */
328962306a36Sopenharmony_ci		wait_for_completion(&result.completion);
329062306a36Sopenharmony_ci		ret = result.err;
329162306a36Sopenharmony_ci		print_hex_dump_debug("digested key@" __stringify(__LINE__)": ",
329262306a36Sopenharmony_ci				     DUMP_PREFIX_ADDRESS, 16, 4, key,
329362306a36Sopenharmony_ci				     digestsize, 1);
329462306a36Sopenharmony_ci	}
329562306a36Sopenharmony_ci
329662306a36Sopenharmony_ci	dma_unmap_single(ctx->dev, flc_dma, sizeof(flc->flc) + desc_bytes(desc),
329762306a36Sopenharmony_ci			 DMA_TO_DEVICE);
329862306a36Sopenharmony_cierr_flc_dma:
329962306a36Sopenharmony_ci	dma_unmap_single(ctx->dev, key_dma, *keylen, DMA_BIDIRECTIONAL);
330062306a36Sopenharmony_cierr_key_dma:
330162306a36Sopenharmony_ci	kfree(flc);
330262306a36Sopenharmony_cierr_flc:
330362306a36Sopenharmony_ci	kfree(req_ctx);
330462306a36Sopenharmony_ci
330562306a36Sopenharmony_ci	*keylen = digestsize;
330662306a36Sopenharmony_ci
330762306a36Sopenharmony_ci	return ret;
330862306a36Sopenharmony_ci}
330962306a36Sopenharmony_ci
331062306a36Sopenharmony_cistatic int ahash_setkey(struct crypto_ahash *ahash, const u8 *key,
331162306a36Sopenharmony_ci			unsigned int keylen)
331262306a36Sopenharmony_ci{
331362306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
331462306a36Sopenharmony_ci	unsigned int blocksize = crypto_tfm_alg_blocksize(&ahash->base);
331562306a36Sopenharmony_ci	unsigned int digestsize = crypto_ahash_digestsize(ahash);
331662306a36Sopenharmony_ci	int ret;
331762306a36Sopenharmony_ci	u8 *hashed_key = NULL;
331862306a36Sopenharmony_ci
331962306a36Sopenharmony_ci	dev_dbg(ctx->dev, "keylen %d blocksize %d\n", keylen, blocksize);
332062306a36Sopenharmony_ci
332162306a36Sopenharmony_ci	if (keylen > blocksize) {
332262306a36Sopenharmony_ci		unsigned int aligned_len =
332362306a36Sopenharmony_ci			ALIGN(keylen, dma_get_cache_alignment());
332462306a36Sopenharmony_ci
332562306a36Sopenharmony_ci		if (aligned_len < keylen)
332662306a36Sopenharmony_ci			return -EOVERFLOW;
332762306a36Sopenharmony_ci
332862306a36Sopenharmony_ci		hashed_key = kmemdup(key, aligned_len, GFP_KERNEL);
332962306a36Sopenharmony_ci		if (!hashed_key)
333062306a36Sopenharmony_ci			return -ENOMEM;
333162306a36Sopenharmony_ci		ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize);
333262306a36Sopenharmony_ci		if (ret)
333362306a36Sopenharmony_ci			goto bad_free_key;
333462306a36Sopenharmony_ci		key = hashed_key;
333562306a36Sopenharmony_ci	}
333662306a36Sopenharmony_ci
333762306a36Sopenharmony_ci	ctx->adata.keylen = keylen;
333862306a36Sopenharmony_ci	ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
333962306a36Sopenharmony_ci					      OP_ALG_ALGSEL_MASK);
334062306a36Sopenharmony_ci	if (ctx->adata.keylen_pad > CAAM_MAX_HASH_KEY_SIZE)
334162306a36Sopenharmony_ci		goto bad_free_key;
334262306a36Sopenharmony_ci
334362306a36Sopenharmony_ci	ctx->adata.key_virt = key;
334462306a36Sopenharmony_ci	ctx->adata.key_inline = true;
334562306a36Sopenharmony_ci
334662306a36Sopenharmony_ci	/*
334762306a36Sopenharmony_ci	 * In case |user key| > |derived key|, using DKP<imm,imm> would result
334862306a36Sopenharmony_ci	 * in invalid opcodes (last bytes of user key) in the resulting
334962306a36Sopenharmony_ci	 * descriptor. Use DKP<ptr,imm> instead => both virtual and dma key
335062306a36Sopenharmony_ci	 * addresses are needed.
335162306a36Sopenharmony_ci	 */
335262306a36Sopenharmony_ci	if (keylen > ctx->adata.keylen_pad) {
335362306a36Sopenharmony_ci		memcpy(ctx->key, key, keylen);
335462306a36Sopenharmony_ci		dma_sync_single_for_device(ctx->dev, ctx->adata.key_dma,
335562306a36Sopenharmony_ci					   ctx->adata.keylen_pad,
335662306a36Sopenharmony_ci					   DMA_TO_DEVICE);
335762306a36Sopenharmony_ci	}
335862306a36Sopenharmony_ci
335962306a36Sopenharmony_ci	ret = ahash_set_sh_desc(ahash);
336062306a36Sopenharmony_ci	kfree(hashed_key);
336162306a36Sopenharmony_ci	return ret;
336262306a36Sopenharmony_cibad_free_key:
336362306a36Sopenharmony_ci	kfree(hashed_key);
336462306a36Sopenharmony_ci	return -EINVAL;
336562306a36Sopenharmony_ci}
336662306a36Sopenharmony_ci
336762306a36Sopenharmony_cistatic inline void ahash_unmap(struct device *dev, struct ahash_edesc *edesc,
336862306a36Sopenharmony_ci			       struct ahash_request *req)
336962306a36Sopenharmony_ci{
337062306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
337162306a36Sopenharmony_ci
337262306a36Sopenharmony_ci	if (edesc->src_nents)
337362306a36Sopenharmony_ci		dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE);
337462306a36Sopenharmony_ci
337562306a36Sopenharmony_ci	if (edesc->qm_sg_bytes)
337662306a36Sopenharmony_ci		dma_unmap_single(dev, edesc->qm_sg_dma, edesc->qm_sg_bytes,
337762306a36Sopenharmony_ci				 DMA_TO_DEVICE);
337862306a36Sopenharmony_ci
337962306a36Sopenharmony_ci	if (state->buf_dma) {
338062306a36Sopenharmony_ci		dma_unmap_single(dev, state->buf_dma, state->buflen,
338162306a36Sopenharmony_ci				 DMA_TO_DEVICE);
338262306a36Sopenharmony_ci		state->buf_dma = 0;
338362306a36Sopenharmony_ci	}
338462306a36Sopenharmony_ci}
338562306a36Sopenharmony_ci
338662306a36Sopenharmony_cistatic inline void ahash_unmap_ctx(struct device *dev,
338762306a36Sopenharmony_ci				   struct ahash_edesc *edesc,
338862306a36Sopenharmony_ci				   struct ahash_request *req, u32 flag)
338962306a36Sopenharmony_ci{
339062306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
339162306a36Sopenharmony_ci
339262306a36Sopenharmony_ci	if (state->ctx_dma) {
339362306a36Sopenharmony_ci		dma_unmap_single(dev, state->ctx_dma, state->ctx_dma_len, flag);
339462306a36Sopenharmony_ci		state->ctx_dma = 0;
339562306a36Sopenharmony_ci	}
339662306a36Sopenharmony_ci	ahash_unmap(dev, edesc, req);
339762306a36Sopenharmony_ci}
339862306a36Sopenharmony_ci
339962306a36Sopenharmony_cistatic void ahash_done(void *cbk_ctx, u32 status)
340062306a36Sopenharmony_ci{
340162306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
340262306a36Sopenharmony_ci	struct ahash_request *req = ahash_request_cast(areq);
340362306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
340462306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
340562306a36Sopenharmony_ci	struct ahash_edesc *edesc = state->caam_req.edesc;
340662306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
340762306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
340862306a36Sopenharmony_ci	int ecode = 0;
340962306a36Sopenharmony_ci
341062306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
341162306a36Sopenharmony_ci
341262306a36Sopenharmony_ci	if (unlikely(status))
341362306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
341462306a36Sopenharmony_ci
341562306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE);
341662306a36Sopenharmony_ci	memcpy(req->result, state->caam_ctx, digestsize);
341762306a36Sopenharmony_ci	qi_cache_free(edesc);
341862306a36Sopenharmony_ci
341962306a36Sopenharmony_ci	print_hex_dump_debug("ctx@" __stringify(__LINE__)": ",
342062306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
342162306a36Sopenharmony_ci			     ctx->ctx_len, 1);
342262306a36Sopenharmony_ci
342362306a36Sopenharmony_ci	ahash_request_complete(req, ecode);
342462306a36Sopenharmony_ci}
342562306a36Sopenharmony_ci
342662306a36Sopenharmony_cistatic void ahash_done_bi(void *cbk_ctx, u32 status)
342762306a36Sopenharmony_ci{
342862306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
342962306a36Sopenharmony_ci	struct ahash_request *req = ahash_request_cast(areq);
343062306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
343162306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
343262306a36Sopenharmony_ci	struct ahash_edesc *edesc = state->caam_req.edesc;
343362306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
343462306a36Sopenharmony_ci	int ecode = 0;
343562306a36Sopenharmony_ci
343662306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
343762306a36Sopenharmony_ci
343862306a36Sopenharmony_ci	if (unlikely(status))
343962306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
344062306a36Sopenharmony_ci
344162306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL);
344262306a36Sopenharmony_ci	qi_cache_free(edesc);
344362306a36Sopenharmony_ci
344462306a36Sopenharmony_ci	scatterwalk_map_and_copy(state->buf, req->src,
344562306a36Sopenharmony_ci				 req->nbytes - state->next_buflen,
344662306a36Sopenharmony_ci				 state->next_buflen, 0);
344762306a36Sopenharmony_ci	state->buflen = state->next_buflen;
344862306a36Sopenharmony_ci
344962306a36Sopenharmony_ci	print_hex_dump_debug("buf@" __stringify(__LINE__)": ",
345062306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, state->buf,
345162306a36Sopenharmony_ci			     state->buflen, 1);
345262306a36Sopenharmony_ci
345362306a36Sopenharmony_ci	print_hex_dump_debug("ctx@" __stringify(__LINE__)": ",
345462306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
345562306a36Sopenharmony_ci			     ctx->ctx_len, 1);
345662306a36Sopenharmony_ci	if (req->result)
345762306a36Sopenharmony_ci		print_hex_dump_debug("result@" __stringify(__LINE__)": ",
345862306a36Sopenharmony_ci				     DUMP_PREFIX_ADDRESS, 16, 4, req->result,
345962306a36Sopenharmony_ci				     crypto_ahash_digestsize(ahash), 1);
346062306a36Sopenharmony_ci
346162306a36Sopenharmony_ci	ahash_request_complete(req, ecode);
346262306a36Sopenharmony_ci}
346362306a36Sopenharmony_ci
346462306a36Sopenharmony_cistatic void ahash_done_ctx_src(void *cbk_ctx, u32 status)
346562306a36Sopenharmony_ci{
346662306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
346762306a36Sopenharmony_ci	struct ahash_request *req = ahash_request_cast(areq);
346862306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
346962306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
347062306a36Sopenharmony_ci	struct ahash_edesc *edesc = state->caam_req.edesc;
347162306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
347262306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
347362306a36Sopenharmony_ci	int ecode = 0;
347462306a36Sopenharmony_ci
347562306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
347662306a36Sopenharmony_ci
347762306a36Sopenharmony_ci	if (unlikely(status))
347862306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
347962306a36Sopenharmony_ci
348062306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL);
348162306a36Sopenharmony_ci	memcpy(req->result, state->caam_ctx, digestsize);
348262306a36Sopenharmony_ci	qi_cache_free(edesc);
348362306a36Sopenharmony_ci
348462306a36Sopenharmony_ci	print_hex_dump_debug("ctx@" __stringify(__LINE__)": ",
348562306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
348662306a36Sopenharmony_ci			     ctx->ctx_len, 1);
348762306a36Sopenharmony_ci
348862306a36Sopenharmony_ci	ahash_request_complete(req, ecode);
348962306a36Sopenharmony_ci}
349062306a36Sopenharmony_ci
349162306a36Sopenharmony_cistatic void ahash_done_ctx_dst(void *cbk_ctx, u32 status)
349262306a36Sopenharmony_ci{
349362306a36Sopenharmony_ci	struct crypto_async_request *areq = cbk_ctx;
349462306a36Sopenharmony_ci	struct ahash_request *req = ahash_request_cast(areq);
349562306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
349662306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
349762306a36Sopenharmony_ci	struct ahash_edesc *edesc = state->caam_req.edesc;
349862306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
349962306a36Sopenharmony_ci	int ecode = 0;
350062306a36Sopenharmony_ci
350162306a36Sopenharmony_ci	dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
350262306a36Sopenharmony_ci
350362306a36Sopenharmony_ci	if (unlikely(status))
350462306a36Sopenharmony_ci		ecode = caam_qi2_strstatus(ctx->dev, status);
350562306a36Sopenharmony_ci
350662306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE);
350762306a36Sopenharmony_ci	qi_cache_free(edesc);
350862306a36Sopenharmony_ci
350962306a36Sopenharmony_ci	scatterwalk_map_and_copy(state->buf, req->src,
351062306a36Sopenharmony_ci				 req->nbytes - state->next_buflen,
351162306a36Sopenharmony_ci				 state->next_buflen, 0);
351262306a36Sopenharmony_ci	state->buflen = state->next_buflen;
351362306a36Sopenharmony_ci
351462306a36Sopenharmony_ci	print_hex_dump_debug("buf@" __stringify(__LINE__)": ",
351562306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, state->buf,
351662306a36Sopenharmony_ci			     state->buflen, 1);
351762306a36Sopenharmony_ci
351862306a36Sopenharmony_ci	print_hex_dump_debug("ctx@" __stringify(__LINE__)": ",
351962306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
352062306a36Sopenharmony_ci			     ctx->ctx_len, 1);
352162306a36Sopenharmony_ci	if (req->result)
352262306a36Sopenharmony_ci		print_hex_dump_debug("result@" __stringify(__LINE__)": ",
352362306a36Sopenharmony_ci				     DUMP_PREFIX_ADDRESS, 16, 4, req->result,
352462306a36Sopenharmony_ci				     crypto_ahash_digestsize(ahash), 1);
352562306a36Sopenharmony_ci
352662306a36Sopenharmony_ci	ahash_request_complete(req, ecode);
352762306a36Sopenharmony_ci}
352862306a36Sopenharmony_ci
352962306a36Sopenharmony_cistatic int ahash_update_ctx(struct ahash_request *req)
353062306a36Sopenharmony_ci{
353162306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
353262306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
353362306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
353462306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
353562306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
353662306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
353762306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
353862306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
353962306a36Sopenharmony_ci	u8 *buf = state->buf;
354062306a36Sopenharmony_ci	int *buflen = &state->buflen;
354162306a36Sopenharmony_ci	int *next_buflen = &state->next_buflen;
354262306a36Sopenharmony_ci	int in_len = *buflen + req->nbytes, to_hash;
354362306a36Sopenharmony_ci	int src_nents, mapped_nents, qm_sg_bytes, qm_sg_src_index;
354462306a36Sopenharmony_ci	struct ahash_edesc *edesc;
354562306a36Sopenharmony_ci	int ret = 0;
354662306a36Sopenharmony_ci
354762306a36Sopenharmony_ci	*next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1);
354862306a36Sopenharmony_ci	to_hash = in_len - *next_buflen;
354962306a36Sopenharmony_ci
355062306a36Sopenharmony_ci	if (to_hash) {
355162306a36Sopenharmony_ci		struct dpaa2_sg_entry *sg_table;
355262306a36Sopenharmony_ci		int src_len = req->nbytes - *next_buflen;
355362306a36Sopenharmony_ci
355462306a36Sopenharmony_ci		src_nents = sg_nents_for_len(req->src, src_len);
355562306a36Sopenharmony_ci		if (src_nents < 0) {
355662306a36Sopenharmony_ci			dev_err(ctx->dev, "Invalid number of src SG.\n");
355762306a36Sopenharmony_ci			return src_nents;
355862306a36Sopenharmony_ci		}
355962306a36Sopenharmony_ci
356062306a36Sopenharmony_ci		if (src_nents) {
356162306a36Sopenharmony_ci			mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
356262306a36Sopenharmony_ci						  DMA_TO_DEVICE);
356362306a36Sopenharmony_ci			if (!mapped_nents) {
356462306a36Sopenharmony_ci				dev_err(ctx->dev, "unable to DMA map source\n");
356562306a36Sopenharmony_ci				return -ENOMEM;
356662306a36Sopenharmony_ci			}
356762306a36Sopenharmony_ci		} else {
356862306a36Sopenharmony_ci			mapped_nents = 0;
356962306a36Sopenharmony_ci		}
357062306a36Sopenharmony_ci
357162306a36Sopenharmony_ci		/* allocate space for base edesc and link tables */
357262306a36Sopenharmony_ci		edesc = qi_cache_zalloc(flags);
357362306a36Sopenharmony_ci		if (!edesc) {
357462306a36Sopenharmony_ci			dma_unmap_sg(ctx->dev, req->src, src_nents,
357562306a36Sopenharmony_ci				     DMA_TO_DEVICE);
357662306a36Sopenharmony_ci			return -ENOMEM;
357762306a36Sopenharmony_ci		}
357862306a36Sopenharmony_ci
357962306a36Sopenharmony_ci		edesc->src_nents = src_nents;
358062306a36Sopenharmony_ci		qm_sg_src_index = 1 + (*buflen ? 1 : 0);
358162306a36Sopenharmony_ci		qm_sg_bytes = pad_sg_nents(qm_sg_src_index + mapped_nents) *
358262306a36Sopenharmony_ci			      sizeof(*sg_table);
358362306a36Sopenharmony_ci		sg_table = &edesc->sgt[0];
358462306a36Sopenharmony_ci
358562306a36Sopenharmony_ci		ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table,
358662306a36Sopenharmony_ci				       DMA_BIDIRECTIONAL);
358762306a36Sopenharmony_ci		if (ret)
358862306a36Sopenharmony_ci			goto unmap_ctx;
358962306a36Sopenharmony_ci
359062306a36Sopenharmony_ci		ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state);
359162306a36Sopenharmony_ci		if (ret)
359262306a36Sopenharmony_ci			goto unmap_ctx;
359362306a36Sopenharmony_ci
359462306a36Sopenharmony_ci		if (mapped_nents) {
359562306a36Sopenharmony_ci			sg_to_qm_sg_last(req->src, src_len,
359662306a36Sopenharmony_ci					 sg_table + qm_sg_src_index, 0);
359762306a36Sopenharmony_ci		} else {
359862306a36Sopenharmony_ci			dpaa2_sg_set_final(sg_table + qm_sg_src_index - 1,
359962306a36Sopenharmony_ci					   true);
360062306a36Sopenharmony_ci		}
360162306a36Sopenharmony_ci
360262306a36Sopenharmony_ci		edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
360362306a36Sopenharmony_ci						  qm_sg_bytes, DMA_TO_DEVICE);
360462306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
360562306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map S/G table\n");
360662306a36Sopenharmony_ci			ret = -ENOMEM;
360762306a36Sopenharmony_ci			goto unmap_ctx;
360862306a36Sopenharmony_ci		}
360962306a36Sopenharmony_ci		edesc->qm_sg_bytes = qm_sg_bytes;
361062306a36Sopenharmony_ci
361162306a36Sopenharmony_ci		memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
361262306a36Sopenharmony_ci		dpaa2_fl_set_final(in_fle, true);
361362306a36Sopenharmony_ci		dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
361462306a36Sopenharmony_ci		dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
361562306a36Sopenharmony_ci		dpaa2_fl_set_len(in_fle, ctx->ctx_len + to_hash);
361662306a36Sopenharmony_ci		dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
361762306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, state->ctx_dma);
361862306a36Sopenharmony_ci		dpaa2_fl_set_len(out_fle, ctx->ctx_len);
361962306a36Sopenharmony_ci
362062306a36Sopenharmony_ci		req_ctx->flc = &ctx->flc[UPDATE];
362162306a36Sopenharmony_ci		req_ctx->flc_dma = ctx->flc_dma[UPDATE];
362262306a36Sopenharmony_ci		req_ctx->cbk = ahash_done_bi;
362362306a36Sopenharmony_ci		req_ctx->ctx = &req->base;
362462306a36Sopenharmony_ci		req_ctx->edesc = edesc;
362562306a36Sopenharmony_ci
362662306a36Sopenharmony_ci		ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
362762306a36Sopenharmony_ci		if (ret != -EINPROGRESS &&
362862306a36Sopenharmony_ci		    !(ret == -EBUSY &&
362962306a36Sopenharmony_ci		      req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
363062306a36Sopenharmony_ci			goto unmap_ctx;
363162306a36Sopenharmony_ci	} else if (*next_buflen) {
363262306a36Sopenharmony_ci		scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
363362306a36Sopenharmony_ci					 req->nbytes, 0);
363462306a36Sopenharmony_ci		*buflen = *next_buflen;
363562306a36Sopenharmony_ci
363662306a36Sopenharmony_ci		print_hex_dump_debug("buf@" __stringify(__LINE__)": ",
363762306a36Sopenharmony_ci				     DUMP_PREFIX_ADDRESS, 16, 4, buf,
363862306a36Sopenharmony_ci				     *buflen, 1);
363962306a36Sopenharmony_ci	}
364062306a36Sopenharmony_ci
364162306a36Sopenharmony_ci	return ret;
364262306a36Sopenharmony_ciunmap_ctx:
364362306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL);
364462306a36Sopenharmony_ci	qi_cache_free(edesc);
364562306a36Sopenharmony_ci	return ret;
364662306a36Sopenharmony_ci}
364762306a36Sopenharmony_ci
364862306a36Sopenharmony_cistatic int ahash_final_ctx(struct ahash_request *req)
364962306a36Sopenharmony_ci{
365062306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
365162306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
365262306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
365362306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
365462306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
365562306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
365662306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
365762306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
365862306a36Sopenharmony_ci	int buflen = state->buflen;
365962306a36Sopenharmony_ci	int qm_sg_bytes;
366062306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
366162306a36Sopenharmony_ci	struct ahash_edesc *edesc;
366262306a36Sopenharmony_ci	struct dpaa2_sg_entry *sg_table;
366362306a36Sopenharmony_ci	int ret;
366462306a36Sopenharmony_ci
366562306a36Sopenharmony_ci	/* allocate space for base edesc and link tables */
366662306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
366762306a36Sopenharmony_ci	if (!edesc)
366862306a36Sopenharmony_ci		return -ENOMEM;
366962306a36Sopenharmony_ci
367062306a36Sopenharmony_ci	qm_sg_bytes = pad_sg_nents(1 + (buflen ? 1 : 0)) * sizeof(*sg_table);
367162306a36Sopenharmony_ci	sg_table = &edesc->sgt[0];
367262306a36Sopenharmony_ci
367362306a36Sopenharmony_ci	ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table,
367462306a36Sopenharmony_ci			       DMA_BIDIRECTIONAL);
367562306a36Sopenharmony_ci	if (ret)
367662306a36Sopenharmony_ci		goto unmap_ctx;
367762306a36Sopenharmony_ci
367862306a36Sopenharmony_ci	ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state);
367962306a36Sopenharmony_ci	if (ret)
368062306a36Sopenharmony_ci		goto unmap_ctx;
368162306a36Sopenharmony_ci
368262306a36Sopenharmony_ci	dpaa2_sg_set_final(sg_table + (buflen ? 1 : 0), true);
368362306a36Sopenharmony_ci
368462306a36Sopenharmony_ci	edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes,
368562306a36Sopenharmony_ci					  DMA_TO_DEVICE);
368662306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
368762306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map S/G table\n");
368862306a36Sopenharmony_ci		ret = -ENOMEM;
368962306a36Sopenharmony_ci		goto unmap_ctx;
369062306a36Sopenharmony_ci	}
369162306a36Sopenharmony_ci	edesc->qm_sg_bytes = qm_sg_bytes;
369262306a36Sopenharmony_ci
369362306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
369462306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
369562306a36Sopenharmony_ci	dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
369662306a36Sopenharmony_ci	dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
369762306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen);
369862306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
369962306a36Sopenharmony_ci	dpaa2_fl_set_addr(out_fle, state->ctx_dma);
370062306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, digestsize);
370162306a36Sopenharmony_ci
370262306a36Sopenharmony_ci	req_ctx->flc = &ctx->flc[FINALIZE];
370362306a36Sopenharmony_ci	req_ctx->flc_dma = ctx->flc_dma[FINALIZE];
370462306a36Sopenharmony_ci	req_ctx->cbk = ahash_done_ctx_src;
370562306a36Sopenharmony_ci	req_ctx->ctx = &req->base;
370662306a36Sopenharmony_ci	req_ctx->edesc = edesc;
370762306a36Sopenharmony_ci
370862306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
370962306a36Sopenharmony_ci	if (ret == -EINPROGRESS ||
371062306a36Sopenharmony_ci	    (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
371162306a36Sopenharmony_ci		return ret;
371262306a36Sopenharmony_ci
371362306a36Sopenharmony_ciunmap_ctx:
371462306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL);
371562306a36Sopenharmony_ci	qi_cache_free(edesc);
371662306a36Sopenharmony_ci	return ret;
371762306a36Sopenharmony_ci}
371862306a36Sopenharmony_ci
371962306a36Sopenharmony_cistatic int ahash_finup_ctx(struct ahash_request *req)
372062306a36Sopenharmony_ci{
372162306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
372262306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
372362306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
372462306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
372562306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
372662306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
372762306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
372862306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
372962306a36Sopenharmony_ci	int buflen = state->buflen;
373062306a36Sopenharmony_ci	int qm_sg_bytes, qm_sg_src_index;
373162306a36Sopenharmony_ci	int src_nents, mapped_nents;
373262306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
373362306a36Sopenharmony_ci	struct ahash_edesc *edesc;
373462306a36Sopenharmony_ci	struct dpaa2_sg_entry *sg_table;
373562306a36Sopenharmony_ci	int ret;
373662306a36Sopenharmony_ci
373762306a36Sopenharmony_ci	src_nents = sg_nents_for_len(req->src, req->nbytes);
373862306a36Sopenharmony_ci	if (src_nents < 0) {
373962306a36Sopenharmony_ci		dev_err(ctx->dev, "Invalid number of src SG.\n");
374062306a36Sopenharmony_ci		return src_nents;
374162306a36Sopenharmony_ci	}
374262306a36Sopenharmony_ci
374362306a36Sopenharmony_ci	if (src_nents) {
374462306a36Sopenharmony_ci		mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
374562306a36Sopenharmony_ci					  DMA_TO_DEVICE);
374662306a36Sopenharmony_ci		if (!mapped_nents) {
374762306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to DMA map source\n");
374862306a36Sopenharmony_ci			return -ENOMEM;
374962306a36Sopenharmony_ci		}
375062306a36Sopenharmony_ci	} else {
375162306a36Sopenharmony_ci		mapped_nents = 0;
375262306a36Sopenharmony_ci	}
375362306a36Sopenharmony_ci
375462306a36Sopenharmony_ci	/* allocate space for base edesc and link tables */
375562306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
375662306a36Sopenharmony_ci	if (!edesc) {
375762306a36Sopenharmony_ci		dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE);
375862306a36Sopenharmony_ci		return -ENOMEM;
375962306a36Sopenharmony_ci	}
376062306a36Sopenharmony_ci
376162306a36Sopenharmony_ci	edesc->src_nents = src_nents;
376262306a36Sopenharmony_ci	qm_sg_src_index = 1 + (buflen ? 1 : 0);
376362306a36Sopenharmony_ci	qm_sg_bytes = pad_sg_nents(qm_sg_src_index + mapped_nents) *
376462306a36Sopenharmony_ci		      sizeof(*sg_table);
376562306a36Sopenharmony_ci	sg_table = &edesc->sgt[0];
376662306a36Sopenharmony_ci
376762306a36Sopenharmony_ci	ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table,
376862306a36Sopenharmony_ci			       DMA_BIDIRECTIONAL);
376962306a36Sopenharmony_ci	if (ret)
377062306a36Sopenharmony_ci		goto unmap_ctx;
377162306a36Sopenharmony_ci
377262306a36Sopenharmony_ci	ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state);
377362306a36Sopenharmony_ci	if (ret)
377462306a36Sopenharmony_ci		goto unmap_ctx;
377562306a36Sopenharmony_ci
377662306a36Sopenharmony_ci	sg_to_qm_sg_last(req->src, req->nbytes, sg_table + qm_sg_src_index, 0);
377762306a36Sopenharmony_ci
377862306a36Sopenharmony_ci	edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes,
377962306a36Sopenharmony_ci					  DMA_TO_DEVICE);
378062306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
378162306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map S/G table\n");
378262306a36Sopenharmony_ci		ret = -ENOMEM;
378362306a36Sopenharmony_ci		goto unmap_ctx;
378462306a36Sopenharmony_ci	}
378562306a36Sopenharmony_ci	edesc->qm_sg_bytes = qm_sg_bytes;
378662306a36Sopenharmony_ci
378762306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
378862306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
378962306a36Sopenharmony_ci	dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
379062306a36Sopenharmony_ci	dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
379162306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen + req->nbytes);
379262306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
379362306a36Sopenharmony_ci	dpaa2_fl_set_addr(out_fle, state->ctx_dma);
379462306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, digestsize);
379562306a36Sopenharmony_ci
379662306a36Sopenharmony_ci	req_ctx->flc = &ctx->flc[FINALIZE];
379762306a36Sopenharmony_ci	req_ctx->flc_dma = ctx->flc_dma[FINALIZE];
379862306a36Sopenharmony_ci	req_ctx->cbk = ahash_done_ctx_src;
379962306a36Sopenharmony_ci	req_ctx->ctx = &req->base;
380062306a36Sopenharmony_ci	req_ctx->edesc = edesc;
380162306a36Sopenharmony_ci
380262306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
380362306a36Sopenharmony_ci	if (ret == -EINPROGRESS ||
380462306a36Sopenharmony_ci	    (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
380562306a36Sopenharmony_ci		return ret;
380662306a36Sopenharmony_ci
380762306a36Sopenharmony_ciunmap_ctx:
380862306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL);
380962306a36Sopenharmony_ci	qi_cache_free(edesc);
381062306a36Sopenharmony_ci	return ret;
381162306a36Sopenharmony_ci}
381262306a36Sopenharmony_ci
381362306a36Sopenharmony_cistatic int ahash_digest(struct ahash_request *req)
381462306a36Sopenharmony_ci{
381562306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
381662306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
381762306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
381862306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
381962306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
382062306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
382162306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
382262306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
382362306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
382462306a36Sopenharmony_ci	int src_nents, mapped_nents;
382562306a36Sopenharmony_ci	struct ahash_edesc *edesc;
382662306a36Sopenharmony_ci	int ret = -ENOMEM;
382762306a36Sopenharmony_ci
382862306a36Sopenharmony_ci	state->buf_dma = 0;
382962306a36Sopenharmony_ci
383062306a36Sopenharmony_ci	src_nents = sg_nents_for_len(req->src, req->nbytes);
383162306a36Sopenharmony_ci	if (src_nents < 0) {
383262306a36Sopenharmony_ci		dev_err(ctx->dev, "Invalid number of src SG.\n");
383362306a36Sopenharmony_ci		return src_nents;
383462306a36Sopenharmony_ci	}
383562306a36Sopenharmony_ci
383662306a36Sopenharmony_ci	if (src_nents) {
383762306a36Sopenharmony_ci		mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
383862306a36Sopenharmony_ci					  DMA_TO_DEVICE);
383962306a36Sopenharmony_ci		if (!mapped_nents) {
384062306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map source for DMA\n");
384162306a36Sopenharmony_ci			return ret;
384262306a36Sopenharmony_ci		}
384362306a36Sopenharmony_ci	} else {
384462306a36Sopenharmony_ci		mapped_nents = 0;
384562306a36Sopenharmony_ci	}
384662306a36Sopenharmony_ci
384762306a36Sopenharmony_ci	/* allocate space for base edesc and link tables */
384862306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
384962306a36Sopenharmony_ci	if (!edesc) {
385062306a36Sopenharmony_ci		dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE);
385162306a36Sopenharmony_ci		return ret;
385262306a36Sopenharmony_ci	}
385362306a36Sopenharmony_ci
385462306a36Sopenharmony_ci	edesc->src_nents = src_nents;
385562306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
385662306a36Sopenharmony_ci
385762306a36Sopenharmony_ci	if (mapped_nents > 1) {
385862306a36Sopenharmony_ci		int qm_sg_bytes;
385962306a36Sopenharmony_ci		struct dpaa2_sg_entry *sg_table = &edesc->sgt[0];
386062306a36Sopenharmony_ci
386162306a36Sopenharmony_ci		qm_sg_bytes = pad_sg_nents(mapped_nents) * sizeof(*sg_table);
386262306a36Sopenharmony_ci		sg_to_qm_sg_last(req->src, req->nbytes, sg_table, 0);
386362306a36Sopenharmony_ci		edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
386462306a36Sopenharmony_ci						  qm_sg_bytes, DMA_TO_DEVICE);
386562306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
386662306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map S/G table\n");
386762306a36Sopenharmony_ci			goto unmap;
386862306a36Sopenharmony_ci		}
386962306a36Sopenharmony_ci		edesc->qm_sg_bytes = qm_sg_bytes;
387062306a36Sopenharmony_ci		dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
387162306a36Sopenharmony_ci		dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
387262306a36Sopenharmony_ci	} else {
387362306a36Sopenharmony_ci		dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
387462306a36Sopenharmony_ci		dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src));
387562306a36Sopenharmony_ci	}
387662306a36Sopenharmony_ci
387762306a36Sopenharmony_ci	state->ctx_dma_len = digestsize;
387862306a36Sopenharmony_ci	state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize,
387962306a36Sopenharmony_ci					DMA_FROM_DEVICE);
388062306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
388162306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map ctx\n");
388262306a36Sopenharmony_ci		state->ctx_dma = 0;
388362306a36Sopenharmony_ci		goto unmap;
388462306a36Sopenharmony_ci	}
388562306a36Sopenharmony_ci
388662306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
388762306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, req->nbytes);
388862306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
388962306a36Sopenharmony_ci	dpaa2_fl_set_addr(out_fle, state->ctx_dma);
389062306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, digestsize);
389162306a36Sopenharmony_ci
389262306a36Sopenharmony_ci	req_ctx->flc = &ctx->flc[DIGEST];
389362306a36Sopenharmony_ci	req_ctx->flc_dma = ctx->flc_dma[DIGEST];
389462306a36Sopenharmony_ci	req_ctx->cbk = ahash_done;
389562306a36Sopenharmony_ci	req_ctx->ctx = &req->base;
389662306a36Sopenharmony_ci	req_ctx->edesc = edesc;
389762306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
389862306a36Sopenharmony_ci	if (ret == -EINPROGRESS ||
389962306a36Sopenharmony_ci	    (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
390062306a36Sopenharmony_ci		return ret;
390162306a36Sopenharmony_ci
390262306a36Sopenharmony_ciunmap:
390362306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE);
390462306a36Sopenharmony_ci	qi_cache_free(edesc);
390562306a36Sopenharmony_ci	return ret;
390662306a36Sopenharmony_ci}
390762306a36Sopenharmony_ci
390862306a36Sopenharmony_cistatic int ahash_final_no_ctx(struct ahash_request *req)
390962306a36Sopenharmony_ci{
391062306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
391162306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
391262306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
391362306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
391462306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
391562306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
391662306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
391762306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
391862306a36Sopenharmony_ci	u8 *buf = state->buf;
391962306a36Sopenharmony_ci	int buflen = state->buflen;
392062306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
392162306a36Sopenharmony_ci	struct ahash_edesc *edesc;
392262306a36Sopenharmony_ci	int ret = -ENOMEM;
392362306a36Sopenharmony_ci
392462306a36Sopenharmony_ci	/* allocate space for base edesc and link tables */
392562306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
392662306a36Sopenharmony_ci	if (!edesc)
392762306a36Sopenharmony_ci		return ret;
392862306a36Sopenharmony_ci
392962306a36Sopenharmony_ci	if (buflen) {
393062306a36Sopenharmony_ci		state->buf_dma = dma_map_single(ctx->dev, buf, buflen,
393162306a36Sopenharmony_ci						DMA_TO_DEVICE);
393262306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, state->buf_dma)) {
393362306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map src\n");
393462306a36Sopenharmony_ci			goto unmap;
393562306a36Sopenharmony_ci		}
393662306a36Sopenharmony_ci	}
393762306a36Sopenharmony_ci
393862306a36Sopenharmony_ci	state->ctx_dma_len = digestsize;
393962306a36Sopenharmony_ci	state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize,
394062306a36Sopenharmony_ci					DMA_FROM_DEVICE);
394162306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
394262306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map ctx\n");
394362306a36Sopenharmony_ci		state->ctx_dma = 0;
394462306a36Sopenharmony_ci		goto unmap;
394562306a36Sopenharmony_ci	}
394662306a36Sopenharmony_ci
394762306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
394862306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
394962306a36Sopenharmony_ci	/*
395062306a36Sopenharmony_ci	 * crypto engine requires the input entry to be present when
395162306a36Sopenharmony_ci	 * "frame list" FD is used.
395262306a36Sopenharmony_ci	 * Since engine does not support FMT=2'b11 (unused entry type), leaving
395362306a36Sopenharmony_ci	 * in_fle zeroized (except for "Final" flag) is the best option.
395462306a36Sopenharmony_ci	 */
395562306a36Sopenharmony_ci	if (buflen) {
395662306a36Sopenharmony_ci		dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
395762306a36Sopenharmony_ci		dpaa2_fl_set_addr(in_fle, state->buf_dma);
395862306a36Sopenharmony_ci		dpaa2_fl_set_len(in_fle, buflen);
395962306a36Sopenharmony_ci	}
396062306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
396162306a36Sopenharmony_ci	dpaa2_fl_set_addr(out_fle, state->ctx_dma);
396262306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, digestsize);
396362306a36Sopenharmony_ci
396462306a36Sopenharmony_ci	req_ctx->flc = &ctx->flc[DIGEST];
396562306a36Sopenharmony_ci	req_ctx->flc_dma = ctx->flc_dma[DIGEST];
396662306a36Sopenharmony_ci	req_ctx->cbk = ahash_done;
396762306a36Sopenharmony_ci	req_ctx->ctx = &req->base;
396862306a36Sopenharmony_ci	req_ctx->edesc = edesc;
396962306a36Sopenharmony_ci
397062306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
397162306a36Sopenharmony_ci	if (ret == -EINPROGRESS ||
397262306a36Sopenharmony_ci	    (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
397362306a36Sopenharmony_ci		return ret;
397462306a36Sopenharmony_ci
397562306a36Sopenharmony_ciunmap:
397662306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE);
397762306a36Sopenharmony_ci	qi_cache_free(edesc);
397862306a36Sopenharmony_ci	return ret;
397962306a36Sopenharmony_ci}
398062306a36Sopenharmony_ci
398162306a36Sopenharmony_cistatic int ahash_update_no_ctx(struct ahash_request *req)
398262306a36Sopenharmony_ci{
398362306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
398462306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
398562306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
398662306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
398762306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
398862306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
398962306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
399062306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
399162306a36Sopenharmony_ci	u8 *buf = state->buf;
399262306a36Sopenharmony_ci	int *buflen = &state->buflen;
399362306a36Sopenharmony_ci	int *next_buflen = &state->next_buflen;
399462306a36Sopenharmony_ci	int in_len = *buflen + req->nbytes, to_hash;
399562306a36Sopenharmony_ci	int qm_sg_bytes, src_nents, mapped_nents;
399662306a36Sopenharmony_ci	struct ahash_edesc *edesc;
399762306a36Sopenharmony_ci	int ret = 0;
399862306a36Sopenharmony_ci
399962306a36Sopenharmony_ci	*next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1);
400062306a36Sopenharmony_ci	to_hash = in_len - *next_buflen;
400162306a36Sopenharmony_ci
400262306a36Sopenharmony_ci	if (to_hash) {
400362306a36Sopenharmony_ci		struct dpaa2_sg_entry *sg_table;
400462306a36Sopenharmony_ci		int src_len = req->nbytes - *next_buflen;
400562306a36Sopenharmony_ci
400662306a36Sopenharmony_ci		src_nents = sg_nents_for_len(req->src, src_len);
400762306a36Sopenharmony_ci		if (src_nents < 0) {
400862306a36Sopenharmony_ci			dev_err(ctx->dev, "Invalid number of src SG.\n");
400962306a36Sopenharmony_ci			return src_nents;
401062306a36Sopenharmony_ci		}
401162306a36Sopenharmony_ci
401262306a36Sopenharmony_ci		if (src_nents) {
401362306a36Sopenharmony_ci			mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
401462306a36Sopenharmony_ci						  DMA_TO_DEVICE);
401562306a36Sopenharmony_ci			if (!mapped_nents) {
401662306a36Sopenharmony_ci				dev_err(ctx->dev, "unable to DMA map source\n");
401762306a36Sopenharmony_ci				return -ENOMEM;
401862306a36Sopenharmony_ci			}
401962306a36Sopenharmony_ci		} else {
402062306a36Sopenharmony_ci			mapped_nents = 0;
402162306a36Sopenharmony_ci		}
402262306a36Sopenharmony_ci
402362306a36Sopenharmony_ci		/* allocate space for base edesc and link tables */
402462306a36Sopenharmony_ci		edesc = qi_cache_zalloc(flags);
402562306a36Sopenharmony_ci		if (!edesc) {
402662306a36Sopenharmony_ci			dma_unmap_sg(ctx->dev, req->src, src_nents,
402762306a36Sopenharmony_ci				     DMA_TO_DEVICE);
402862306a36Sopenharmony_ci			return -ENOMEM;
402962306a36Sopenharmony_ci		}
403062306a36Sopenharmony_ci
403162306a36Sopenharmony_ci		edesc->src_nents = src_nents;
403262306a36Sopenharmony_ci		qm_sg_bytes = pad_sg_nents(1 + mapped_nents) *
403362306a36Sopenharmony_ci			      sizeof(*sg_table);
403462306a36Sopenharmony_ci		sg_table = &edesc->sgt[0];
403562306a36Sopenharmony_ci
403662306a36Sopenharmony_ci		ret = buf_map_to_qm_sg(ctx->dev, sg_table, state);
403762306a36Sopenharmony_ci		if (ret)
403862306a36Sopenharmony_ci			goto unmap_ctx;
403962306a36Sopenharmony_ci
404062306a36Sopenharmony_ci		sg_to_qm_sg_last(req->src, src_len, sg_table + 1, 0);
404162306a36Sopenharmony_ci
404262306a36Sopenharmony_ci		edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
404362306a36Sopenharmony_ci						  qm_sg_bytes, DMA_TO_DEVICE);
404462306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
404562306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map S/G table\n");
404662306a36Sopenharmony_ci			ret = -ENOMEM;
404762306a36Sopenharmony_ci			goto unmap_ctx;
404862306a36Sopenharmony_ci		}
404962306a36Sopenharmony_ci		edesc->qm_sg_bytes = qm_sg_bytes;
405062306a36Sopenharmony_ci
405162306a36Sopenharmony_ci		state->ctx_dma_len = ctx->ctx_len;
405262306a36Sopenharmony_ci		state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx,
405362306a36Sopenharmony_ci						ctx->ctx_len, DMA_FROM_DEVICE);
405462306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
405562306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map ctx\n");
405662306a36Sopenharmony_ci			state->ctx_dma = 0;
405762306a36Sopenharmony_ci			ret = -ENOMEM;
405862306a36Sopenharmony_ci			goto unmap_ctx;
405962306a36Sopenharmony_ci		}
406062306a36Sopenharmony_ci
406162306a36Sopenharmony_ci		memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
406262306a36Sopenharmony_ci		dpaa2_fl_set_final(in_fle, true);
406362306a36Sopenharmony_ci		dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
406462306a36Sopenharmony_ci		dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
406562306a36Sopenharmony_ci		dpaa2_fl_set_len(in_fle, to_hash);
406662306a36Sopenharmony_ci		dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
406762306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, state->ctx_dma);
406862306a36Sopenharmony_ci		dpaa2_fl_set_len(out_fle, ctx->ctx_len);
406962306a36Sopenharmony_ci
407062306a36Sopenharmony_ci		req_ctx->flc = &ctx->flc[UPDATE_FIRST];
407162306a36Sopenharmony_ci		req_ctx->flc_dma = ctx->flc_dma[UPDATE_FIRST];
407262306a36Sopenharmony_ci		req_ctx->cbk = ahash_done_ctx_dst;
407362306a36Sopenharmony_ci		req_ctx->ctx = &req->base;
407462306a36Sopenharmony_ci		req_ctx->edesc = edesc;
407562306a36Sopenharmony_ci
407662306a36Sopenharmony_ci		ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
407762306a36Sopenharmony_ci		if (ret != -EINPROGRESS &&
407862306a36Sopenharmony_ci		    !(ret == -EBUSY &&
407962306a36Sopenharmony_ci		      req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
408062306a36Sopenharmony_ci			goto unmap_ctx;
408162306a36Sopenharmony_ci
408262306a36Sopenharmony_ci		state->update = ahash_update_ctx;
408362306a36Sopenharmony_ci		state->finup = ahash_finup_ctx;
408462306a36Sopenharmony_ci		state->final = ahash_final_ctx;
408562306a36Sopenharmony_ci	} else if (*next_buflen) {
408662306a36Sopenharmony_ci		scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
408762306a36Sopenharmony_ci					 req->nbytes, 0);
408862306a36Sopenharmony_ci		*buflen = *next_buflen;
408962306a36Sopenharmony_ci
409062306a36Sopenharmony_ci		print_hex_dump_debug("buf@" __stringify(__LINE__)": ",
409162306a36Sopenharmony_ci				     DUMP_PREFIX_ADDRESS, 16, 4, buf,
409262306a36Sopenharmony_ci				     *buflen, 1);
409362306a36Sopenharmony_ci	}
409462306a36Sopenharmony_ci
409562306a36Sopenharmony_ci	return ret;
409662306a36Sopenharmony_ciunmap_ctx:
409762306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_TO_DEVICE);
409862306a36Sopenharmony_ci	qi_cache_free(edesc);
409962306a36Sopenharmony_ci	return ret;
410062306a36Sopenharmony_ci}
410162306a36Sopenharmony_ci
410262306a36Sopenharmony_cistatic int ahash_finup_no_ctx(struct ahash_request *req)
410362306a36Sopenharmony_ci{
410462306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
410562306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
410662306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
410762306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
410862306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
410962306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
411062306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
411162306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
411262306a36Sopenharmony_ci	int buflen = state->buflen;
411362306a36Sopenharmony_ci	int qm_sg_bytes, src_nents, mapped_nents;
411462306a36Sopenharmony_ci	int digestsize = crypto_ahash_digestsize(ahash);
411562306a36Sopenharmony_ci	struct ahash_edesc *edesc;
411662306a36Sopenharmony_ci	struct dpaa2_sg_entry *sg_table;
411762306a36Sopenharmony_ci	int ret = -ENOMEM;
411862306a36Sopenharmony_ci
411962306a36Sopenharmony_ci	src_nents = sg_nents_for_len(req->src, req->nbytes);
412062306a36Sopenharmony_ci	if (src_nents < 0) {
412162306a36Sopenharmony_ci		dev_err(ctx->dev, "Invalid number of src SG.\n");
412262306a36Sopenharmony_ci		return src_nents;
412362306a36Sopenharmony_ci	}
412462306a36Sopenharmony_ci
412562306a36Sopenharmony_ci	if (src_nents) {
412662306a36Sopenharmony_ci		mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
412762306a36Sopenharmony_ci					  DMA_TO_DEVICE);
412862306a36Sopenharmony_ci		if (!mapped_nents) {
412962306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to DMA map source\n");
413062306a36Sopenharmony_ci			return ret;
413162306a36Sopenharmony_ci		}
413262306a36Sopenharmony_ci	} else {
413362306a36Sopenharmony_ci		mapped_nents = 0;
413462306a36Sopenharmony_ci	}
413562306a36Sopenharmony_ci
413662306a36Sopenharmony_ci	/* allocate space for base edesc and link tables */
413762306a36Sopenharmony_ci	edesc = qi_cache_zalloc(flags);
413862306a36Sopenharmony_ci	if (!edesc) {
413962306a36Sopenharmony_ci		dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE);
414062306a36Sopenharmony_ci		return ret;
414162306a36Sopenharmony_ci	}
414262306a36Sopenharmony_ci
414362306a36Sopenharmony_ci	edesc->src_nents = src_nents;
414462306a36Sopenharmony_ci	qm_sg_bytes = pad_sg_nents(2 + mapped_nents) * sizeof(*sg_table);
414562306a36Sopenharmony_ci	sg_table = &edesc->sgt[0];
414662306a36Sopenharmony_ci
414762306a36Sopenharmony_ci	ret = buf_map_to_qm_sg(ctx->dev, sg_table, state);
414862306a36Sopenharmony_ci	if (ret)
414962306a36Sopenharmony_ci		goto unmap;
415062306a36Sopenharmony_ci
415162306a36Sopenharmony_ci	sg_to_qm_sg_last(req->src, req->nbytes, sg_table + 1, 0);
415262306a36Sopenharmony_ci
415362306a36Sopenharmony_ci	edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes,
415462306a36Sopenharmony_ci					  DMA_TO_DEVICE);
415562306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
415662306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map S/G table\n");
415762306a36Sopenharmony_ci		ret = -ENOMEM;
415862306a36Sopenharmony_ci		goto unmap;
415962306a36Sopenharmony_ci	}
416062306a36Sopenharmony_ci	edesc->qm_sg_bytes = qm_sg_bytes;
416162306a36Sopenharmony_ci
416262306a36Sopenharmony_ci	state->ctx_dma_len = digestsize;
416362306a36Sopenharmony_ci	state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize,
416462306a36Sopenharmony_ci					DMA_FROM_DEVICE);
416562306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
416662306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map ctx\n");
416762306a36Sopenharmony_ci		state->ctx_dma = 0;
416862306a36Sopenharmony_ci		ret = -ENOMEM;
416962306a36Sopenharmony_ci		goto unmap;
417062306a36Sopenharmony_ci	}
417162306a36Sopenharmony_ci
417262306a36Sopenharmony_ci	memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
417362306a36Sopenharmony_ci	dpaa2_fl_set_final(in_fle, true);
417462306a36Sopenharmony_ci	dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
417562306a36Sopenharmony_ci	dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
417662306a36Sopenharmony_ci	dpaa2_fl_set_len(in_fle, buflen + req->nbytes);
417762306a36Sopenharmony_ci	dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
417862306a36Sopenharmony_ci	dpaa2_fl_set_addr(out_fle, state->ctx_dma);
417962306a36Sopenharmony_ci	dpaa2_fl_set_len(out_fle, digestsize);
418062306a36Sopenharmony_ci
418162306a36Sopenharmony_ci	req_ctx->flc = &ctx->flc[DIGEST];
418262306a36Sopenharmony_ci	req_ctx->flc_dma = ctx->flc_dma[DIGEST];
418362306a36Sopenharmony_ci	req_ctx->cbk = ahash_done;
418462306a36Sopenharmony_ci	req_ctx->ctx = &req->base;
418562306a36Sopenharmony_ci	req_ctx->edesc = edesc;
418662306a36Sopenharmony_ci	ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
418762306a36Sopenharmony_ci	if (ret != -EINPROGRESS &&
418862306a36Sopenharmony_ci	    !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
418962306a36Sopenharmony_ci		goto unmap;
419062306a36Sopenharmony_ci
419162306a36Sopenharmony_ci	return ret;
419262306a36Sopenharmony_ciunmap:
419362306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE);
419462306a36Sopenharmony_ci	qi_cache_free(edesc);
419562306a36Sopenharmony_ci	return ret;
419662306a36Sopenharmony_ci}
419762306a36Sopenharmony_ci
419862306a36Sopenharmony_cistatic int ahash_update_first(struct ahash_request *req)
419962306a36Sopenharmony_ci{
420062306a36Sopenharmony_ci	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
420162306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash);
420262306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
420362306a36Sopenharmony_ci	struct caam_request *req_ctx = &state->caam_req;
420462306a36Sopenharmony_ci	struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
420562306a36Sopenharmony_ci	struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
420662306a36Sopenharmony_ci	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
420762306a36Sopenharmony_ci		      GFP_KERNEL : GFP_ATOMIC;
420862306a36Sopenharmony_ci	u8 *buf = state->buf;
420962306a36Sopenharmony_ci	int *buflen = &state->buflen;
421062306a36Sopenharmony_ci	int *next_buflen = &state->next_buflen;
421162306a36Sopenharmony_ci	int to_hash;
421262306a36Sopenharmony_ci	int src_nents, mapped_nents;
421362306a36Sopenharmony_ci	struct ahash_edesc *edesc;
421462306a36Sopenharmony_ci	int ret = 0;
421562306a36Sopenharmony_ci
421662306a36Sopenharmony_ci	*next_buflen = req->nbytes & (crypto_tfm_alg_blocksize(&ahash->base) -
421762306a36Sopenharmony_ci				      1);
421862306a36Sopenharmony_ci	to_hash = req->nbytes - *next_buflen;
421962306a36Sopenharmony_ci
422062306a36Sopenharmony_ci	if (to_hash) {
422162306a36Sopenharmony_ci		struct dpaa2_sg_entry *sg_table;
422262306a36Sopenharmony_ci		int src_len = req->nbytes - *next_buflen;
422362306a36Sopenharmony_ci
422462306a36Sopenharmony_ci		src_nents = sg_nents_for_len(req->src, src_len);
422562306a36Sopenharmony_ci		if (src_nents < 0) {
422662306a36Sopenharmony_ci			dev_err(ctx->dev, "Invalid number of src SG.\n");
422762306a36Sopenharmony_ci			return src_nents;
422862306a36Sopenharmony_ci		}
422962306a36Sopenharmony_ci
423062306a36Sopenharmony_ci		if (src_nents) {
423162306a36Sopenharmony_ci			mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
423262306a36Sopenharmony_ci						  DMA_TO_DEVICE);
423362306a36Sopenharmony_ci			if (!mapped_nents) {
423462306a36Sopenharmony_ci				dev_err(ctx->dev, "unable to map source for DMA\n");
423562306a36Sopenharmony_ci				return -ENOMEM;
423662306a36Sopenharmony_ci			}
423762306a36Sopenharmony_ci		} else {
423862306a36Sopenharmony_ci			mapped_nents = 0;
423962306a36Sopenharmony_ci		}
424062306a36Sopenharmony_ci
424162306a36Sopenharmony_ci		/* allocate space for base edesc and link tables */
424262306a36Sopenharmony_ci		edesc = qi_cache_zalloc(flags);
424362306a36Sopenharmony_ci		if (!edesc) {
424462306a36Sopenharmony_ci			dma_unmap_sg(ctx->dev, req->src, src_nents,
424562306a36Sopenharmony_ci				     DMA_TO_DEVICE);
424662306a36Sopenharmony_ci			return -ENOMEM;
424762306a36Sopenharmony_ci		}
424862306a36Sopenharmony_ci
424962306a36Sopenharmony_ci		edesc->src_nents = src_nents;
425062306a36Sopenharmony_ci		sg_table = &edesc->sgt[0];
425162306a36Sopenharmony_ci
425262306a36Sopenharmony_ci		memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
425362306a36Sopenharmony_ci		dpaa2_fl_set_final(in_fle, true);
425462306a36Sopenharmony_ci		dpaa2_fl_set_len(in_fle, to_hash);
425562306a36Sopenharmony_ci
425662306a36Sopenharmony_ci		if (mapped_nents > 1) {
425762306a36Sopenharmony_ci			int qm_sg_bytes;
425862306a36Sopenharmony_ci
425962306a36Sopenharmony_ci			sg_to_qm_sg_last(req->src, src_len, sg_table, 0);
426062306a36Sopenharmony_ci			qm_sg_bytes = pad_sg_nents(mapped_nents) *
426162306a36Sopenharmony_ci				      sizeof(*sg_table);
426262306a36Sopenharmony_ci			edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
426362306a36Sopenharmony_ci							  qm_sg_bytes,
426462306a36Sopenharmony_ci							  DMA_TO_DEVICE);
426562306a36Sopenharmony_ci			if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
426662306a36Sopenharmony_ci				dev_err(ctx->dev, "unable to map S/G table\n");
426762306a36Sopenharmony_ci				ret = -ENOMEM;
426862306a36Sopenharmony_ci				goto unmap_ctx;
426962306a36Sopenharmony_ci			}
427062306a36Sopenharmony_ci			edesc->qm_sg_bytes = qm_sg_bytes;
427162306a36Sopenharmony_ci			dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
427262306a36Sopenharmony_ci			dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
427362306a36Sopenharmony_ci		} else {
427462306a36Sopenharmony_ci			dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
427562306a36Sopenharmony_ci			dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src));
427662306a36Sopenharmony_ci		}
427762306a36Sopenharmony_ci
427862306a36Sopenharmony_ci		state->ctx_dma_len = ctx->ctx_len;
427962306a36Sopenharmony_ci		state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx,
428062306a36Sopenharmony_ci						ctx->ctx_len, DMA_FROM_DEVICE);
428162306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
428262306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map ctx\n");
428362306a36Sopenharmony_ci			state->ctx_dma = 0;
428462306a36Sopenharmony_ci			ret = -ENOMEM;
428562306a36Sopenharmony_ci			goto unmap_ctx;
428662306a36Sopenharmony_ci		}
428762306a36Sopenharmony_ci
428862306a36Sopenharmony_ci		dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
428962306a36Sopenharmony_ci		dpaa2_fl_set_addr(out_fle, state->ctx_dma);
429062306a36Sopenharmony_ci		dpaa2_fl_set_len(out_fle, ctx->ctx_len);
429162306a36Sopenharmony_ci
429262306a36Sopenharmony_ci		req_ctx->flc = &ctx->flc[UPDATE_FIRST];
429362306a36Sopenharmony_ci		req_ctx->flc_dma = ctx->flc_dma[UPDATE_FIRST];
429462306a36Sopenharmony_ci		req_ctx->cbk = ahash_done_ctx_dst;
429562306a36Sopenharmony_ci		req_ctx->ctx = &req->base;
429662306a36Sopenharmony_ci		req_ctx->edesc = edesc;
429762306a36Sopenharmony_ci
429862306a36Sopenharmony_ci		ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
429962306a36Sopenharmony_ci		if (ret != -EINPROGRESS &&
430062306a36Sopenharmony_ci		    !(ret == -EBUSY && req->base.flags &
430162306a36Sopenharmony_ci		      CRYPTO_TFM_REQ_MAY_BACKLOG))
430262306a36Sopenharmony_ci			goto unmap_ctx;
430362306a36Sopenharmony_ci
430462306a36Sopenharmony_ci		state->update = ahash_update_ctx;
430562306a36Sopenharmony_ci		state->finup = ahash_finup_ctx;
430662306a36Sopenharmony_ci		state->final = ahash_final_ctx;
430762306a36Sopenharmony_ci	} else if (*next_buflen) {
430862306a36Sopenharmony_ci		state->update = ahash_update_no_ctx;
430962306a36Sopenharmony_ci		state->finup = ahash_finup_no_ctx;
431062306a36Sopenharmony_ci		state->final = ahash_final_no_ctx;
431162306a36Sopenharmony_ci		scatterwalk_map_and_copy(buf, req->src, 0,
431262306a36Sopenharmony_ci					 req->nbytes, 0);
431362306a36Sopenharmony_ci		*buflen = *next_buflen;
431462306a36Sopenharmony_ci
431562306a36Sopenharmony_ci		print_hex_dump_debug("buf@" __stringify(__LINE__)": ",
431662306a36Sopenharmony_ci				     DUMP_PREFIX_ADDRESS, 16, 4, buf,
431762306a36Sopenharmony_ci				     *buflen, 1);
431862306a36Sopenharmony_ci	}
431962306a36Sopenharmony_ci
432062306a36Sopenharmony_ci	return ret;
432162306a36Sopenharmony_ciunmap_ctx:
432262306a36Sopenharmony_ci	ahash_unmap_ctx(ctx->dev, edesc, req, DMA_TO_DEVICE);
432362306a36Sopenharmony_ci	qi_cache_free(edesc);
432462306a36Sopenharmony_ci	return ret;
432562306a36Sopenharmony_ci}
432662306a36Sopenharmony_ci
432762306a36Sopenharmony_cistatic int ahash_finup_first(struct ahash_request *req)
432862306a36Sopenharmony_ci{
432962306a36Sopenharmony_ci	return ahash_digest(req);
433062306a36Sopenharmony_ci}
433162306a36Sopenharmony_ci
433262306a36Sopenharmony_cistatic int ahash_init(struct ahash_request *req)
433362306a36Sopenharmony_ci{
433462306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
433562306a36Sopenharmony_ci
433662306a36Sopenharmony_ci	state->update = ahash_update_first;
433762306a36Sopenharmony_ci	state->finup = ahash_finup_first;
433862306a36Sopenharmony_ci	state->final = ahash_final_no_ctx;
433962306a36Sopenharmony_ci
434062306a36Sopenharmony_ci	state->ctx_dma = 0;
434162306a36Sopenharmony_ci	state->ctx_dma_len = 0;
434262306a36Sopenharmony_ci	state->buf_dma = 0;
434362306a36Sopenharmony_ci	state->buflen = 0;
434462306a36Sopenharmony_ci	state->next_buflen = 0;
434562306a36Sopenharmony_ci
434662306a36Sopenharmony_ci	return 0;
434762306a36Sopenharmony_ci}
434862306a36Sopenharmony_ci
434962306a36Sopenharmony_cistatic int ahash_update(struct ahash_request *req)
435062306a36Sopenharmony_ci{
435162306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
435262306a36Sopenharmony_ci
435362306a36Sopenharmony_ci	return state->update(req);
435462306a36Sopenharmony_ci}
435562306a36Sopenharmony_ci
435662306a36Sopenharmony_cistatic int ahash_finup(struct ahash_request *req)
435762306a36Sopenharmony_ci{
435862306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
435962306a36Sopenharmony_ci
436062306a36Sopenharmony_ci	return state->finup(req);
436162306a36Sopenharmony_ci}
436262306a36Sopenharmony_ci
436362306a36Sopenharmony_cistatic int ahash_final(struct ahash_request *req)
436462306a36Sopenharmony_ci{
436562306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
436662306a36Sopenharmony_ci
436762306a36Sopenharmony_ci	return state->final(req);
436862306a36Sopenharmony_ci}
436962306a36Sopenharmony_ci
437062306a36Sopenharmony_cistatic int ahash_export(struct ahash_request *req, void *out)
437162306a36Sopenharmony_ci{
437262306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
437362306a36Sopenharmony_ci	struct caam_export_state *export = out;
437462306a36Sopenharmony_ci	u8 *buf = state->buf;
437562306a36Sopenharmony_ci	int len = state->buflen;
437662306a36Sopenharmony_ci
437762306a36Sopenharmony_ci	memcpy(export->buf, buf, len);
437862306a36Sopenharmony_ci	memcpy(export->caam_ctx, state->caam_ctx, sizeof(export->caam_ctx));
437962306a36Sopenharmony_ci	export->buflen = len;
438062306a36Sopenharmony_ci	export->update = state->update;
438162306a36Sopenharmony_ci	export->final = state->final;
438262306a36Sopenharmony_ci	export->finup = state->finup;
438362306a36Sopenharmony_ci
438462306a36Sopenharmony_ci	return 0;
438562306a36Sopenharmony_ci}
438662306a36Sopenharmony_ci
438762306a36Sopenharmony_cistatic int ahash_import(struct ahash_request *req, const void *in)
438862306a36Sopenharmony_ci{
438962306a36Sopenharmony_ci	struct caam_hash_state *state = ahash_request_ctx_dma(req);
439062306a36Sopenharmony_ci	const struct caam_export_state *export = in;
439162306a36Sopenharmony_ci
439262306a36Sopenharmony_ci	memset(state, 0, sizeof(*state));
439362306a36Sopenharmony_ci	memcpy(state->buf, export->buf, export->buflen);
439462306a36Sopenharmony_ci	memcpy(state->caam_ctx, export->caam_ctx, sizeof(state->caam_ctx));
439562306a36Sopenharmony_ci	state->buflen = export->buflen;
439662306a36Sopenharmony_ci	state->update = export->update;
439762306a36Sopenharmony_ci	state->final = export->final;
439862306a36Sopenharmony_ci	state->finup = export->finup;
439962306a36Sopenharmony_ci
440062306a36Sopenharmony_ci	return 0;
440162306a36Sopenharmony_ci}
440262306a36Sopenharmony_ci
440362306a36Sopenharmony_cistruct caam_hash_template {
440462306a36Sopenharmony_ci	char name[CRYPTO_MAX_ALG_NAME];
440562306a36Sopenharmony_ci	char driver_name[CRYPTO_MAX_ALG_NAME];
440662306a36Sopenharmony_ci	char hmac_name[CRYPTO_MAX_ALG_NAME];
440762306a36Sopenharmony_ci	char hmac_driver_name[CRYPTO_MAX_ALG_NAME];
440862306a36Sopenharmony_ci	unsigned int blocksize;
440962306a36Sopenharmony_ci	struct ahash_alg template_ahash;
441062306a36Sopenharmony_ci	u32 alg_type;
441162306a36Sopenharmony_ci};
441262306a36Sopenharmony_ci
441362306a36Sopenharmony_ci/* ahash descriptors */
441462306a36Sopenharmony_cistatic struct caam_hash_template driver_hash[] = {
441562306a36Sopenharmony_ci	{
441662306a36Sopenharmony_ci		.name = "sha1",
441762306a36Sopenharmony_ci		.driver_name = "sha1-caam-qi2",
441862306a36Sopenharmony_ci		.hmac_name = "hmac(sha1)",
441962306a36Sopenharmony_ci		.hmac_driver_name = "hmac-sha1-caam-qi2",
442062306a36Sopenharmony_ci		.blocksize = SHA1_BLOCK_SIZE,
442162306a36Sopenharmony_ci		.template_ahash = {
442262306a36Sopenharmony_ci			.init = ahash_init,
442362306a36Sopenharmony_ci			.update = ahash_update,
442462306a36Sopenharmony_ci			.final = ahash_final,
442562306a36Sopenharmony_ci			.finup = ahash_finup,
442662306a36Sopenharmony_ci			.digest = ahash_digest,
442762306a36Sopenharmony_ci			.export = ahash_export,
442862306a36Sopenharmony_ci			.import = ahash_import,
442962306a36Sopenharmony_ci			.setkey = ahash_setkey,
443062306a36Sopenharmony_ci			.halg = {
443162306a36Sopenharmony_ci				.digestsize = SHA1_DIGEST_SIZE,
443262306a36Sopenharmony_ci				.statesize = sizeof(struct caam_export_state),
443362306a36Sopenharmony_ci			},
443462306a36Sopenharmony_ci		},
443562306a36Sopenharmony_ci		.alg_type = OP_ALG_ALGSEL_SHA1,
443662306a36Sopenharmony_ci	}, {
443762306a36Sopenharmony_ci		.name = "sha224",
443862306a36Sopenharmony_ci		.driver_name = "sha224-caam-qi2",
443962306a36Sopenharmony_ci		.hmac_name = "hmac(sha224)",
444062306a36Sopenharmony_ci		.hmac_driver_name = "hmac-sha224-caam-qi2",
444162306a36Sopenharmony_ci		.blocksize = SHA224_BLOCK_SIZE,
444262306a36Sopenharmony_ci		.template_ahash = {
444362306a36Sopenharmony_ci			.init = ahash_init,
444462306a36Sopenharmony_ci			.update = ahash_update,
444562306a36Sopenharmony_ci			.final = ahash_final,
444662306a36Sopenharmony_ci			.finup = ahash_finup,
444762306a36Sopenharmony_ci			.digest = ahash_digest,
444862306a36Sopenharmony_ci			.export = ahash_export,
444962306a36Sopenharmony_ci			.import = ahash_import,
445062306a36Sopenharmony_ci			.setkey = ahash_setkey,
445162306a36Sopenharmony_ci			.halg = {
445262306a36Sopenharmony_ci				.digestsize = SHA224_DIGEST_SIZE,
445362306a36Sopenharmony_ci				.statesize = sizeof(struct caam_export_state),
445462306a36Sopenharmony_ci			},
445562306a36Sopenharmony_ci		},
445662306a36Sopenharmony_ci		.alg_type = OP_ALG_ALGSEL_SHA224,
445762306a36Sopenharmony_ci	}, {
445862306a36Sopenharmony_ci		.name = "sha256",
445962306a36Sopenharmony_ci		.driver_name = "sha256-caam-qi2",
446062306a36Sopenharmony_ci		.hmac_name = "hmac(sha256)",
446162306a36Sopenharmony_ci		.hmac_driver_name = "hmac-sha256-caam-qi2",
446262306a36Sopenharmony_ci		.blocksize = SHA256_BLOCK_SIZE,
446362306a36Sopenharmony_ci		.template_ahash = {
446462306a36Sopenharmony_ci			.init = ahash_init,
446562306a36Sopenharmony_ci			.update = ahash_update,
446662306a36Sopenharmony_ci			.final = ahash_final,
446762306a36Sopenharmony_ci			.finup = ahash_finup,
446862306a36Sopenharmony_ci			.digest = ahash_digest,
446962306a36Sopenharmony_ci			.export = ahash_export,
447062306a36Sopenharmony_ci			.import = ahash_import,
447162306a36Sopenharmony_ci			.setkey = ahash_setkey,
447262306a36Sopenharmony_ci			.halg = {
447362306a36Sopenharmony_ci				.digestsize = SHA256_DIGEST_SIZE,
447462306a36Sopenharmony_ci				.statesize = sizeof(struct caam_export_state),
447562306a36Sopenharmony_ci			},
447662306a36Sopenharmony_ci		},
447762306a36Sopenharmony_ci		.alg_type = OP_ALG_ALGSEL_SHA256,
447862306a36Sopenharmony_ci	}, {
447962306a36Sopenharmony_ci		.name = "sha384",
448062306a36Sopenharmony_ci		.driver_name = "sha384-caam-qi2",
448162306a36Sopenharmony_ci		.hmac_name = "hmac(sha384)",
448262306a36Sopenharmony_ci		.hmac_driver_name = "hmac-sha384-caam-qi2",
448362306a36Sopenharmony_ci		.blocksize = SHA384_BLOCK_SIZE,
448462306a36Sopenharmony_ci		.template_ahash = {
448562306a36Sopenharmony_ci			.init = ahash_init,
448662306a36Sopenharmony_ci			.update = ahash_update,
448762306a36Sopenharmony_ci			.final = ahash_final,
448862306a36Sopenharmony_ci			.finup = ahash_finup,
448962306a36Sopenharmony_ci			.digest = ahash_digest,
449062306a36Sopenharmony_ci			.export = ahash_export,
449162306a36Sopenharmony_ci			.import = ahash_import,
449262306a36Sopenharmony_ci			.setkey = ahash_setkey,
449362306a36Sopenharmony_ci			.halg = {
449462306a36Sopenharmony_ci				.digestsize = SHA384_DIGEST_SIZE,
449562306a36Sopenharmony_ci				.statesize = sizeof(struct caam_export_state),
449662306a36Sopenharmony_ci			},
449762306a36Sopenharmony_ci		},
449862306a36Sopenharmony_ci		.alg_type = OP_ALG_ALGSEL_SHA384,
449962306a36Sopenharmony_ci	}, {
450062306a36Sopenharmony_ci		.name = "sha512",
450162306a36Sopenharmony_ci		.driver_name = "sha512-caam-qi2",
450262306a36Sopenharmony_ci		.hmac_name = "hmac(sha512)",
450362306a36Sopenharmony_ci		.hmac_driver_name = "hmac-sha512-caam-qi2",
450462306a36Sopenharmony_ci		.blocksize = SHA512_BLOCK_SIZE,
450562306a36Sopenharmony_ci		.template_ahash = {
450662306a36Sopenharmony_ci			.init = ahash_init,
450762306a36Sopenharmony_ci			.update = ahash_update,
450862306a36Sopenharmony_ci			.final = ahash_final,
450962306a36Sopenharmony_ci			.finup = ahash_finup,
451062306a36Sopenharmony_ci			.digest = ahash_digest,
451162306a36Sopenharmony_ci			.export = ahash_export,
451262306a36Sopenharmony_ci			.import = ahash_import,
451362306a36Sopenharmony_ci			.setkey = ahash_setkey,
451462306a36Sopenharmony_ci			.halg = {
451562306a36Sopenharmony_ci				.digestsize = SHA512_DIGEST_SIZE,
451662306a36Sopenharmony_ci				.statesize = sizeof(struct caam_export_state),
451762306a36Sopenharmony_ci			},
451862306a36Sopenharmony_ci		},
451962306a36Sopenharmony_ci		.alg_type = OP_ALG_ALGSEL_SHA512,
452062306a36Sopenharmony_ci	}, {
452162306a36Sopenharmony_ci		.name = "md5",
452262306a36Sopenharmony_ci		.driver_name = "md5-caam-qi2",
452362306a36Sopenharmony_ci		.hmac_name = "hmac(md5)",
452462306a36Sopenharmony_ci		.hmac_driver_name = "hmac-md5-caam-qi2",
452562306a36Sopenharmony_ci		.blocksize = MD5_BLOCK_WORDS * 4,
452662306a36Sopenharmony_ci		.template_ahash = {
452762306a36Sopenharmony_ci			.init = ahash_init,
452862306a36Sopenharmony_ci			.update = ahash_update,
452962306a36Sopenharmony_ci			.final = ahash_final,
453062306a36Sopenharmony_ci			.finup = ahash_finup,
453162306a36Sopenharmony_ci			.digest = ahash_digest,
453262306a36Sopenharmony_ci			.export = ahash_export,
453362306a36Sopenharmony_ci			.import = ahash_import,
453462306a36Sopenharmony_ci			.setkey = ahash_setkey,
453562306a36Sopenharmony_ci			.halg = {
453662306a36Sopenharmony_ci				.digestsize = MD5_DIGEST_SIZE,
453762306a36Sopenharmony_ci				.statesize = sizeof(struct caam_export_state),
453862306a36Sopenharmony_ci			},
453962306a36Sopenharmony_ci		},
454062306a36Sopenharmony_ci		.alg_type = OP_ALG_ALGSEL_MD5,
454162306a36Sopenharmony_ci	}
454262306a36Sopenharmony_ci};
454362306a36Sopenharmony_ci
454462306a36Sopenharmony_cistruct caam_hash_alg {
454562306a36Sopenharmony_ci	struct list_head entry;
454662306a36Sopenharmony_ci	struct device *dev;
454762306a36Sopenharmony_ci	int alg_type;
454862306a36Sopenharmony_ci	struct ahash_alg ahash_alg;
454962306a36Sopenharmony_ci};
455062306a36Sopenharmony_ci
455162306a36Sopenharmony_cistatic int caam_hash_cra_init(struct crypto_tfm *tfm)
455262306a36Sopenharmony_ci{
455362306a36Sopenharmony_ci	struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
455462306a36Sopenharmony_ci	struct crypto_alg *base = tfm->__crt_alg;
455562306a36Sopenharmony_ci	struct hash_alg_common *halg =
455662306a36Sopenharmony_ci		 container_of(base, struct hash_alg_common, base);
455762306a36Sopenharmony_ci	struct ahash_alg *alg =
455862306a36Sopenharmony_ci		 container_of(halg, struct ahash_alg, halg);
455962306a36Sopenharmony_ci	struct caam_hash_alg *caam_hash =
456062306a36Sopenharmony_ci		 container_of(alg, struct caam_hash_alg, ahash_alg);
456162306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_tfm_ctx_dma(tfm);
456262306a36Sopenharmony_ci	/* Sizes for MDHA running digests: MD5, SHA1, 224, 256, 384, 512 */
456362306a36Sopenharmony_ci	static const u8 runninglen[] = { HASH_MSG_LEN + MD5_DIGEST_SIZE,
456462306a36Sopenharmony_ci					 HASH_MSG_LEN + SHA1_DIGEST_SIZE,
456562306a36Sopenharmony_ci					 HASH_MSG_LEN + 32,
456662306a36Sopenharmony_ci					 HASH_MSG_LEN + SHA256_DIGEST_SIZE,
456762306a36Sopenharmony_ci					 HASH_MSG_LEN + 64,
456862306a36Sopenharmony_ci					 HASH_MSG_LEN + SHA512_DIGEST_SIZE };
456962306a36Sopenharmony_ci	dma_addr_t dma_addr;
457062306a36Sopenharmony_ci	int i;
457162306a36Sopenharmony_ci
457262306a36Sopenharmony_ci	ctx->dev = caam_hash->dev;
457362306a36Sopenharmony_ci
457462306a36Sopenharmony_ci	if (alg->setkey) {
457562306a36Sopenharmony_ci		ctx->adata.key_dma = dma_map_single_attrs(ctx->dev, ctx->key,
457662306a36Sopenharmony_ci							  ARRAY_SIZE(ctx->key),
457762306a36Sopenharmony_ci							  DMA_TO_DEVICE,
457862306a36Sopenharmony_ci							  DMA_ATTR_SKIP_CPU_SYNC);
457962306a36Sopenharmony_ci		if (dma_mapping_error(ctx->dev, ctx->adata.key_dma)) {
458062306a36Sopenharmony_ci			dev_err(ctx->dev, "unable to map key\n");
458162306a36Sopenharmony_ci			return -ENOMEM;
458262306a36Sopenharmony_ci		}
458362306a36Sopenharmony_ci	}
458462306a36Sopenharmony_ci
458562306a36Sopenharmony_ci	dma_addr = dma_map_single_attrs(ctx->dev, ctx->flc, sizeof(ctx->flc),
458662306a36Sopenharmony_ci					DMA_BIDIRECTIONAL,
458762306a36Sopenharmony_ci					DMA_ATTR_SKIP_CPU_SYNC);
458862306a36Sopenharmony_ci	if (dma_mapping_error(ctx->dev, dma_addr)) {
458962306a36Sopenharmony_ci		dev_err(ctx->dev, "unable to map shared descriptors\n");
459062306a36Sopenharmony_ci		if (ctx->adata.key_dma)
459162306a36Sopenharmony_ci			dma_unmap_single_attrs(ctx->dev, ctx->adata.key_dma,
459262306a36Sopenharmony_ci					       ARRAY_SIZE(ctx->key),
459362306a36Sopenharmony_ci					       DMA_TO_DEVICE,
459462306a36Sopenharmony_ci					       DMA_ATTR_SKIP_CPU_SYNC);
459562306a36Sopenharmony_ci		return -ENOMEM;
459662306a36Sopenharmony_ci	}
459762306a36Sopenharmony_ci
459862306a36Sopenharmony_ci	for (i = 0; i < HASH_NUM_OP; i++)
459962306a36Sopenharmony_ci		ctx->flc_dma[i] = dma_addr + i * sizeof(ctx->flc[i]);
460062306a36Sopenharmony_ci
460162306a36Sopenharmony_ci	/* copy descriptor header template value */
460262306a36Sopenharmony_ci	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam_hash->alg_type;
460362306a36Sopenharmony_ci
460462306a36Sopenharmony_ci	ctx->ctx_len = runninglen[(ctx->adata.algtype &
460562306a36Sopenharmony_ci				   OP_ALG_ALGSEL_SUBMASK) >>
460662306a36Sopenharmony_ci				  OP_ALG_ALGSEL_SHIFT];
460762306a36Sopenharmony_ci
460862306a36Sopenharmony_ci	crypto_ahash_set_reqsize_dma(ahash, sizeof(struct caam_hash_state));
460962306a36Sopenharmony_ci
461062306a36Sopenharmony_ci	/*
461162306a36Sopenharmony_ci	 * For keyed hash algorithms shared descriptors
461262306a36Sopenharmony_ci	 * will be created later in setkey() callback
461362306a36Sopenharmony_ci	 */
461462306a36Sopenharmony_ci	return alg->setkey ? 0 : ahash_set_sh_desc(ahash);
461562306a36Sopenharmony_ci}
461662306a36Sopenharmony_ci
461762306a36Sopenharmony_cistatic void caam_hash_cra_exit(struct crypto_tfm *tfm)
461862306a36Sopenharmony_ci{
461962306a36Sopenharmony_ci	struct caam_hash_ctx *ctx = crypto_tfm_ctx_dma(tfm);
462062306a36Sopenharmony_ci
462162306a36Sopenharmony_ci	dma_unmap_single_attrs(ctx->dev, ctx->flc_dma[0], sizeof(ctx->flc),
462262306a36Sopenharmony_ci			       DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC);
462362306a36Sopenharmony_ci	if (ctx->adata.key_dma)
462462306a36Sopenharmony_ci		dma_unmap_single_attrs(ctx->dev, ctx->adata.key_dma,
462562306a36Sopenharmony_ci				       ARRAY_SIZE(ctx->key), DMA_TO_DEVICE,
462662306a36Sopenharmony_ci				       DMA_ATTR_SKIP_CPU_SYNC);
462762306a36Sopenharmony_ci}
462862306a36Sopenharmony_ci
462962306a36Sopenharmony_cistatic struct caam_hash_alg *caam_hash_alloc(struct device *dev,
463062306a36Sopenharmony_ci	struct caam_hash_template *template, bool keyed)
463162306a36Sopenharmony_ci{
463262306a36Sopenharmony_ci	struct caam_hash_alg *t_alg;
463362306a36Sopenharmony_ci	struct ahash_alg *halg;
463462306a36Sopenharmony_ci	struct crypto_alg *alg;
463562306a36Sopenharmony_ci
463662306a36Sopenharmony_ci	t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
463762306a36Sopenharmony_ci	if (!t_alg)
463862306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
463962306a36Sopenharmony_ci
464062306a36Sopenharmony_ci	t_alg->ahash_alg = template->template_ahash;
464162306a36Sopenharmony_ci	halg = &t_alg->ahash_alg;
464262306a36Sopenharmony_ci	alg = &halg->halg.base;
464362306a36Sopenharmony_ci
464462306a36Sopenharmony_ci	if (keyed) {
464562306a36Sopenharmony_ci		snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s",
464662306a36Sopenharmony_ci			 template->hmac_name);
464762306a36Sopenharmony_ci		snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
464862306a36Sopenharmony_ci			 template->hmac_driver_name);
464962306a36Sopenharmony_ci	} else {
465062306a36Sopenharmony_ci		snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s",
465162306a36Sopenharmony_ci			 template->name);
465262306a36Sopenharmony_ci		snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
465362306a36Sopenharmony_ci			 template->driver_name);
465462306a36Sopenharmony_ci		t_alg->ahash_alg.setkey = NULL;
465562306a36Sopenharmony_ci	}
465662306a36Sopenharmony_ci	alg->cra_module = THIS_MODULE;
465762306a36Sopenharmony_ci	alg->cra_init = caam_hash_cra_init;
465862306a36Sopenharmony_ci	alg->cra_exit = caam_hash_cra_exit;
465962306a36Sopenharmony_ci	alg->cra_ctxsize = sizeof(struct caam_hash_ctx) + crypto_dma_padding();
466062306a36Sopenharmony_ci	alg->cra_priority = CAAM_CRA_PRIORITY;
466162306a36Sopenharmony_ci	alg->cra_blocksize = template->blocksize;
466262306a36Sopenharmony_ci	alg->cra_alignmask = 0;
466362306a36Sopenharmony_ci	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY;
466462306a36Sopenharmony_ci
466562306a36Sopenharmony_ci	t_alg->alg_type = template->alg_type;
466662306a36Sopenharmony_ci	t_alg->dev = dev;
466762306a36Sopenharmony_ci
466862306a36Sopenharmony_ci	return t_alg;
466962306a36Sopenharmony_ci}
467062306a36Sopenharmony_ci
467162306a36Sopenharmony_cistatic void dpaa2_caam_fqdan_cb(struct dpaa2_io_notification_ctx *nctx)
467262306a36Sopenharmony_ci{
467362306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
467462306a36Sopenharmony_ci
467562306a36Sopenharmony_ci	ppriv = container_of(nctx, struct dpaa2_caam_priv_per_cpu, nctx);
467662306a36Sopenharmony_ci	napi_schedule_irqoff(&ppriv->napi);
467762306a36Sopenharmony_ci}
467862306a36Sopenharmony_ci
467962306a36Sopenharmony_cistatic int __cold dpaa2_dpseci_dpio_setup(struct dpaa2_caam_priv *priv)
468062306a36Sopenharmony_ci{
468162306a36Sopenharmony_ci	struct device *dev = priv->dev;
468262306a36Sopenharmony_ci	struct dpaa2_io_notification_ctx *nctx;
468362306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
468462306a36Sopenharmony_ci	int err, i = 0, cpu;
468562306a36Sopenharmony_ci
468662306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
468762306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, cpu);
468862306a36Sopenharmony_ci		ppriv->priv = priv;
468962306a36Sopenharmony_ci		nctx = &ppriv->nctx;
469062306a36Sopenharmony_ci		nctx->is_cdan = 0;
469162306a36Sopenharmony_ci		nctx->id = ppriv->rsp_fqid;
469262306a36Sopenharmony_ci		nctx->desired_cpu = cpu;
469362306a36Sopenharmony_ci		nctx->cb = dpaa2_caam_fqdan_cb;
469462306a36Sopenharmony_ci
469562306a36Sopenharmony_ci		/* Register notification callbacks */
469662306a36Sopenharmony_ci		ppriv->dpio = dpaa2_io_service_select(cpu);
469762306a36Sopenharmony_ci		err = dpaa2_io_service_register(ppriv->dpio, nctx, dev);
469862306a36Sopenharmony_ci		if (unlikely(err)) {
469962306a36Sopenharmony_ci			dev_dbg(dev, "No affine DPIO for cpu %d\n", cpu);
470062306a36Sopenharmony_ci			nctx->cb = NULL;
470162306a36Sopenharmony_ci			/*
470262306a36Sopenharmony_ci			 * If no affine DPIO for this core, there's probably
470362306a36Sopenharmony_ci			 * none available for next cores either. Signal we want
470462306a36Sopenharmony_ci			 * to retry later, in case the DPIO devices weren't
470562306a36Sopenharmony_ci			 * probed yet.
470662306a36Sopenharmony_ci			 */
470762306a36Sopenharmony_ci			err = -EPROBE_DEFER;
470862306a36Sopenharmony_ci			goto err;
470962306a36Sopenharmony_ci		}
471062306a36Sopenharmony_ci
471162306a36Sopenharmony_ci		ppriv->store = dpaa2_io_store_create(DPAA2_CAAM_STORE_SIZE,
471262306a36Sopenharmony_ci						     dev);
471362306a36Sopenharmony_ci		if (unlikely(!ppriv->store)) {
471462306a36Sopenharmony_ci			dev_err(dev, "dpaa2_io_store_create() failed\n");
471562306a36Sopenharmony_ci			err = -ENOMEM;
471662306a36Sopenharmony_ci			goto err;
471762306a36Sopenharmony_ci		}
471862306a36Sopenharmony_ci
471962306a36Sopenharmony_ci		if (++i == priv->num_pairs)
472062306a36Sopenharmony_ci			break;
472162306a36Sopenharmony_ci	}
472262306a36Sopenharmony_ci
472362306a36Sopenharmony_ci	return 0;
472462306a36Sopenharmony_ci
472562306a36Sopenharmony_cierr:
472662306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
472762306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, cpu);
472862306a36Sopenharmony_ci		if (!ppriv->nctx.cb)
472962306a36Sopenharmony_ci			break;
473062306a36Sopenharmony_ci		dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev);
473162306a36Sopenharmony_ci	}
473262306a36Sopenharmony_ci
473362306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
473462306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, cpu);
473562306a36Sopenharmony_ci		if (!ppriv->store)
473662306a36Sopenharmony_ci			break;
473762306a36Sopenharmony_ci		dpaa2_io_store_destroy(ppriv->store);
473862306a36Sopenharmony_ci	}
473962306a36Sopenharmony_ci
474062306a36Sopenharmony_ci	return err;
474162306a36Sopenharmony_ci}
474262306a36Sopenharmony_ci
474362306a36Sopenharmony_cistatic void __cold dpaa2_dpseci_dpio_free(struct dpaa2_caam_priv *priv)
474462306a36Sopenharmony_ci{
474562306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
474662306a36Sopenharmony_ci	int i = 0, cpu;
474762306a36Sopenharmony_ci
474862306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
474962306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, cpu);
475062306a36Sopenharmony_ci		dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx,
475162306a36Sopenharmony_ci					    priv->dev);
475262306a36Sopenharmony_ci		dpaa2_io_store_destroy(ppriv->store);
475362306a36Sopenharmony_ci
475462306a36Sopenharmony_ci		if (++i == priv->num_pairs)
475562306a36Sopenharmony_ci			return;
475662306a36Sopenharmony_ci	}
475762306a36Sopenharmony_ci}
475862306a36Sopenharmony_ci
475962306a36Sopenharmony_cistatic int dpaa2_dpseci_bind(struct dpaa2_caam_priv *priv)
476062306a36Sopenharmony_ci{
476162306a36Sopenharmony_ci	struct dpseci_rx_queue_cfg rx_queue_cfg;
476262306a36Sopenharmony_ci	struct device *dev = priv->dev;
476362306a36Sopenharmony_ci	struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
476462306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
476562306a36Sopenharmony_ci	int err = 0, i = 0, cpu;
476662306a36Sopenharmony_ci
476762306a36Sopenharmony_ci	/* Configure Rx queues */
476862306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
476962306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, cpu);
477062306a36Sopenharmony_ci
477162306a36Sopenharmony_ci		rx_queue_cfg.options = DPSECI_QUEUE_OPT_DEST |
477262306a36Sopenharmony_ci				       DPSECI_QUEUE_OPT_USER_CTX;
477362306a36Sopenharmony_ci		rx_queue_cfg.order_preservation_en = 0;
477462306a36Sopenharmony_ci		rx_queue_cfg.dest_cfg.dest_type = DPSECI_DEST_DPIO;
477562306a36Sopenharmony_ci		rx_queue_cfg.dest_cfg.dest_id = ppriv->nctx.dpio_id;
477662306a36Sopenharmony_ci		/*
477762306a36Sopenharmony_ci		 * Rx priority (WQ) doesn't really matter, since we use
477862306a36Sopenharmony_ci		 * pull mode, i.e. volatile dequeues from specific FQs
477962306a36Sopenharmony_ci		 */
478062306a36Sopenharmony_ci		rx_queue_cfg.dest_cfg.priority = 0;
478162306a36Sopenharmony_ci		rx_queue_cfg.user_ctx = ppriv->nctx.qman64;
478262306a36Sopenharmony_ci
478362306a36Sopenharmony_ci		err = dpseci_set_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
478462306a36Sopenharmony_ci					  &rx_queue_cfg);
478562306a36Sopenharmony_ci		if (err) {
478662306a36Sopenharmony_ci			dev_err(dev, "dpseci_set_rx_queue() failed with err %d\n",
478762306a36Sopenharmony_ci				err);
478862306a36Sopenharmony_ci			return err;
478962306a36Sopenharmony_ci		}
479062306a36Sopenharmony_ci
479162306a36Sopenharmony_ci		if (++i == priv->num_pairs)
479262306a36Sopenharmony_ci			break;
479362306a36Sopenharmony_ci	}
479462306a36Sopenharmony_ci
479562306a36Sopenharmony_ci	return err;
479662306a36Sopenharmony_ci}
479762306a36Sopenharmony_ci
479862306a36Sopenharmony_cistatic void dpaa2_dpseci_congestion_free(struct dpaa2_caam_priv *priv)
479962306a36Sopenharmony_ci{
480062306a36Sopenharmony_ci	struct device *dev = priv->dev;
480162306a36Sopenharmony_ci
480262306a36Sopenharmony_ci	if (!priv->cscn_mem)
480362306a36Sopenharmony_ci		return;
480462306a36Sopenharmony_ci
480562306a36Sopenharmony_ci	dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
480662306a36Sopenharmony_ci	kfree(priv->cscn_mem);
480762306a36Sopenharmony_ci}
480862306a36Sopenharmony_ci
480962306a36Sopenharmony_cistatic void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)
481062306a36Sopenharmony_ci{
481162306a36Sopenharmony_ci	struct device *dev = priv->dev;
481262306a36Sopenharmony_ci	struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
481362306a36Sopenharmony_ci	int err;
481462306a36Sopenharmony_ci
481562306a36Sopenharmony_ci	if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) {
481662306a36Sopenharmony_ci		err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle);
481762306a36Sopenharmony_ci		if (err)
481862306a36Sopenharmony_ci			dev_err(dev, "dpseci_reset() failed\n");
481962306a36Sopenharmony_ci	}
482062306a36Sopenharmony_ci
482162306a36Sopenharmony_ci	dpaa2_dpseci_congestion_free(priv);
482262306a36Sopenharmony_ci	dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
482362306a36Sopenharmony_ci}
482462306a36Sopenharmony_ci
482562306a36Sopenharmony_cistatic void dpaa2_caam_process_fd(struct dpaa2_caam_priv *priv,
482662306a36Sopenharmony_ci				  const struct dpaa2_fd *fd)
482762306a36Sopenharmony_ci{
482862306a36Sopenharmony_ci	struct caam_request *req;
482962306a36Sopenharmony_ci	u32 fd_err;
483062306a36Sopenharmony_ci
483162306a36Sopenharmony_ci	if (dpaa2_fd_get_format(fd) != dpaa2_fd_list) {
483262306a36Sopenharmony_ci		dev_err(priv->dev, "Only Frame List FD format is supported!\n");
483362306a36Sopenharmony_ci		return;
483462306a36Sopenharmony_ci	}
483562306a36Sopenharmony_ci
483662306a36Sopenharmony_ci	fd_err = dpaa2_fd_get_ctrl(fd) & FD_CTRL_ERR_MASK;
483762306a36Sopenharmony_ci	if (unlikely(fd_err))
483862306a36Sopenharmony_ci		dev_err_ratelimited(priv->dev, "FD error: %08x\n", fd_err);
483962306a36Sopenharmony_ci
484062306a36Sopenharmony_ci	/*
484162306a36Sopenharmony_ci	 * FD[ADDR] is guaranteed to be valid, irrespective of errors reported
484262306a36Sopenharmony_ci	 * in FD[ERR] or FD[FRC].
484362306a36Sopenharmony_ci	 */
484462306a36Sopenharmony_ci	req = dpaa2_caam_iova_to_virt(priv, dpaa2_fd_get_addr(fd));
484562306a36Sopenharmony_ci	dma_unmap_single(priv->dev, req->fd_flt_dma, sizeof(req->fd_flt),
484662306a36Sopenharmony_ci			 DMA_BIDIRECTIONAL);
484762306a36Sopenharmony_ci	req->cbk(req->ctx, dpaa2_fd_get_frc(fd));
484862306a36Sopenharmony_ci}
484962306a36Sopenharmony_ci
485062306a36Sopenharmony_cistatic int dpaa2_caam_pull_fq(struct dpaa2_caam_priv_per_cpu *ppriv)
485162306a36Sopenharmony_ci{
485262306a36Sopenharmony_ci	int err;
485362306a36Sopenharmony_ci
485462306a36Sopenharmony_ci	/* Retry while portal is busy */
485562306a36Sopenharmony_ci	do {
485662306a36Sopenharmony_ci		err = dpaa2_io_service_pull_fq(ppriv->dpio, ppriv->rsp_fqid,
485762306a36Sopenharmony_ci					       ppriv->store);
485862306a36Sopenharmony_ci	} while (err == -EBUSY);
485962306a36Sopenharmony_ci
486062306a36Sopenharmony_ci	if (unlikely(err))
486162306a36Sopenharmony_ci		dev_err(ppriv->priv->dev, "dpaa2_io_service_pull err %d", err);
486262306a36Sopenharmony_ci
486362306a36Sopenharmony_ci	return err;
486462306a36Sopenharmony_ci}
486562306a36Sopenharmony_ci
486662306a36Sopenharmony_cistatic int dpaa2_caam_store_consume(struct dpaa2_caam_priv_per_cpu *ppriv)
486762306a36Sopenharmony_ci{
486862306a36Sopenharmony_ci	struct dpaa2_dq *dq;
486962306a36Sopenharmony_ci	int cleaned = 0, is_last;
487062306a36Sopenharmony_ci
487162306a36Sopenharmony_ci	do {
487262306a36Sopenharmony_ci		dq = dpaa2_io_store_next(ppriv->store, &is_last);
487362306a36Sopenharmony_ci		if (unlikely(!dq)) {
487462306a36Sopenharmony_ci			if (unlikely(!is_last)) {
487562306a36Sopenharmony_ci				dev_dbg(ppriv->priv->dev,
487662306a36Sopenharmony_ci					"FQ %d returned no valid frames\n",
487762306a36Sopenharmony_ci					ppriv->rsp_fqid);
487862306a36Sopenharmony_ci				/*
487962306a36Sopenharmony_ci				 * MUST retry until we get some sort of
488062306a36Sopenharmony_ci				 * valid response token (be it "empty dequeue"
488162306a36Sopenharmony_ci				 * or a valid frame).
488262306a36Sopenharmony_ci				 */
488362306a36Sopenharmony_ci				continue;
488462306a36Sopenharmony_ci			}
488562306a36Sopenharmony_ci			break;
488662306a36Sopenharmony_ci		}
488762306a36Sopenharmony_ci
488862306a36Sopenharmony_ci		/* Process FD */
488962306a36Sopenharmony_ci		dpaa2_caam_process_fd(ppriv->priv, dpaa2_dq_fd(dq));
489062306a36Sopenharmony_ci		cleaned++;
489162306a36Sopenharmony_ci	} while (!is_last);
489262306a36Sopenharmony_ci
489362306a36Sopenharmony_ci	return cleaned;
489462306a36Sopenharmony_ci}
489562306a36Sopenharmony_ci
489662306a36Sopenharmony_cistatic int dpaa2_dpseci_poll(struct napi_struct *napi, int budget)
489762306a36Sopenharmony_ci{
489862306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
489962306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv;
490062306a36Sopenharmony_ci	int err, cleaned = 0, store_cleaned;
490162306a36Sopenharmony_ci
490262306a36Sopenharmony_ci	ppriv = container_of(napi, struct dpaa2_caam_priv_per_cpu, napi);
490362306a36Sopenharmony_ci	priv = ppriv->priv;
490462306a36Sopenharmony_ci
490562306a36Sopenharmony_ci	if (unlikely(dpaa2_caam_pull_fq(ppriv)))
490662306a36Sopenharmony_ci		return 0;
490762306a36Sopenharmony_ci
490862306a36Sopenharmony_ci	do {
490962306a36Sopenharmony_ci		store_cleaned = dpaa2_caam_store_consume(ppriv);
491062306a36Sopenharmony_ci		cleaned += store_cleaned;
491162306a36Sopenharmony_ci
491262306a36Sopenharmony_ci		if (store_cleaned == 0 ||
491362306a36Sopenharmony_ci		    cleaned > budget - DPAA2_CAAM_STORE_SIZE)
491462306a36Sopenharmony_ci			break;
491562306a36Sopenharmony_ci
491662306a36Sopenharmony_ci		/* Try to dequeue some more */
491762306a36Sopenharmony_ci		err = dpaa2_caam_pull_fq(ppriv);
491862306a36Sopenharmony_ci		if (unlikely(err))
491962306a36Sopenharmony_ci			break;
492062306a36Sopenharmony_ci	} while (1);
492162306a36Sopenharmony_ci
492262306a36Sopenharmony_ci	if (cleaned < budget) {
492362306a36Sopenharmony_ci		napi_complete_done(napi, cleaned);
492462306a36Sopenharmony_ci		err = dpaa2_io_service_rearm(ppriv->dpio, &ppriv->nctx);
492562306a36Sopenharmony_ci		if (unlikely(err))
492662306a36Sopenharmony_ci			dev_err(priv->dev, "Notification rearm failed: %d\n",
492762306a36Sopenharmony_ci				err);
492862306a36Sopenharmony_ci	}
492962306a36Sopenharmony_ci
493062306a36Sopenharmony_ci	return cleaned;
493162306a36Sopenharmony_ci}
493262306a36Sopenharmony_ci
493362306a36Sopenharmony_cistatic int dpaa2_dpseci_congestion_setup(struct dpaa2_caam_priv *priv,
493462306a36Sopenharmony_ci					 u16 token)
493562306a36Sopenharmony_ci{
493662306a36Sopenharmony_ci	struct dpseci_congestion_notification_cfg cong_notif_cfg = { 0 };
493762306a36Sopenharmony_ci	struct device *dev = priv->dev;
493862306a36Sopenharmony_ci	unsigned int alignmask;
493962306a36Sopenharmony_ci	int err;
494062306a36Sopenharmony_ci
494162306a36Sopenharmony_ci	/*
494262306a36Sopenharmony_ci	 * Congestion group feature supported starting with DPSECI API v5.1
494362306a36Sopenharmony_ci	 * and only when object has been created with this capability.
494462306a36Sopenharmony_ci	 */
494562306a36Sopenharmony_ci	if ((DPSECI_VER(priv->major_ver, priv->minor_ver) < DPSECI_VER(5, 1)) ||
494662306a36Sopenharmony_ci	    !(priv->dpseci_attr.options & DPSECI_OPT_HAS_CG))
494762306a36Sopenharmony_ci		return 0;
494862306a36Sopenharmony_ci
494962306a36Sopenharmony_ci	alignmask = DPAA2_CSCN_ALIGN - 1;
495062306a36Sopenharmony_ci	alignmask |= dma_get_cache_alignment() - 1;
495162306a36Sopenharmony_ci	priv->cscn_mem = kzalloc(ALIGN(DPAA2_CSCN_SIZE, alignmask + 1),
495262306a36Sopenharmony_ci				 GFP_KERNEL);
495362306a36Sopenharmony_ci	if (!priv->cscn_mem)
495462306a36Sopenharmony_ci		return -ENOMEM;
495562306a36Sopenharmony_ci
495662306a36Sopenharmony_ci	priv->cscn_dma = dma_map_single(dev, priv->cscn_mem,
495762306a36Sopenharmony_ci					DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
495862306a36Sopenharmony_ci	if (dma_mapping_error(dev, priv->cscn_dma)) {
495962306a36Sopenharmony_ci		dev_err(dev, "Error mapping CSCN memory area\n");
496062306a36Sopenharmony_ci		err = -ENOMEM;
496162306a36Sopenharmony_ci		goto err_dma_map;
496262306a36Sopenharmony_ci	}
496362306a36Sopenharmony_ci
496462306a36Sopenharmony_ci	cong_notif_cfg.units = DPSECI_CONGESTION_UNIT_BYTES;
496562306a36Sopenharmony_ci	cong_notif_cfg.threshold_entry = DPAA2_SEC_CONG_ENTRY_THRESH;
496662306a36Sopenharmony_ci	cong_notif_cfg.threshold_exit = DPAA2_SEC_CONG_EXIT_THRESH;
496762306a36Sopenharmony_ci	cong_notif_cfg.message_ctx = (uintptr_t)priv;
496862306a36Sopenharmony_ci	cong_notif_cfg.message_iova = priv->cscn_dma;
496962306a36Sopenharmony_ci	cong_notif_cfg.notification_mode = DPSECI_CGN_MODE_WRITE_MEM_ON_ENTER |
497062306a36Sopenharmony_ci					DPSECI_CGN_MODE_WRITE_MEM_ON_EXIT |
497162306a36Sopenharmony_ci					DPSECI_CGN_MODE_COHERENT_WRITE;
497262306a36Sopenharmony_ci
497362306a36Sopenharmony_ci	err = dpseci_set_congestion_notification(priv->mc_io, 0, token,
497462306a36Sopenharmony_ci						 &cong_notif_cfg);
497562306a36Sopenharmony_ci	if (err) {
497662306a36Sopenharmony_ci		dev_err(dev, "dpseci_set_congestion_notification failed\n");
497762306a36Sopenharmony_ci		goto err_set_cong;
497862306a36Sopenharmony_ci	}
497962306a36Sopenharmony_ci
498062306a36Sopenharmony_ci	return 0;
498162306a36Sopenharmony_ci
498262306a36Sopenharmony_cierr_set_cong:
498362306a36Sopenharmony_ci	dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
498462306a36Sopenharmony_cierr_dma_map:
498562306a36Sopenharmony_ci	kfree(priv->cscn_mem);
498662306a36Sopenharmony_ci
498762306a36Sopenharmony_ci	return err;
498862306a36Sopenharmony_ci}
498962306a36Sopenharmony_ci
499062306a36Sopenharmony_cistatic int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
499162306a36Sopenharmony_ci{
499262306a36Sopenharmony_ci	struct device *dev = &ls_dev->dev;
499362306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv;
499462306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
499562306a36Sopenharmony_ci	int err, cpu;
499662306a36Sopenharmony_ci	u8 i;
499762306a36Sopenharmony_ci
499862306a36Sopenharmony_ci	priv = dev_get_drvdata(dev);
499962306a36Sopenharmony_ci
500062306a36Sopenharmony_ci	priv->dev = dev;
500162306a36Sopenharmony_ci	priv->dpsec_id = ls_dev->obj_desc.id;
500262306a36Sopenharmony_ci
500362306a36Sopenharmony_ci	/* Get a handle for the DPSECI this interface is associate with */
500462306a36Sopenharmony_ci	err = dpseci_open(priv->mc_io, 0, priv->dpsec_id, &ls_dev->mc_handle);
500562306a36Sopenharmony_ci	if (err) {
500662306a36Sopenharmony_ci		dev_err(dev, "dpseci_open() failed: %d\n", err);
500762306a36Sopenharmony_ci		goto err_open;
500862306a36Sopenharmony_ci	}
500962306a36Sopenharmony_ci
501062306a36Sopenharmony_ci	err = dpseci_get_api_version(priv->mc_io, 0, &priv->major_ver,
501162306a36Sopenharmony_ci				     &priv->minor_ver);
501262306a36Sopenharmony_ci	if (err) {
501362306a36Sopenharmony_ci		dev_err(dev, "dpseci_get_api_version() failed\n");
501462306a36Sopenharmony_ci		goto err_get_vers;
501562306a36Sopenharmony_ci	}
501662306a36Sopenharmony_ci
501762306a36Sopenharmony_ci	dev_info(dev, "dpseci v%d.%d\n", priv->major_ver, priv->minor_ver);
501862306a36Sopenharmony_ci
501962306a36Sopenharmony_ci	if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) {
502062306a36Sopenharmony_ci		err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle);
502162306a36Sopenharmony_ci		if (err) {
502262306a36Sopenharmony_ci			dev_err(dev, "dpseci_reset() failed\n");
502362306a36Sopenharmony_ci			goto err_get_vers;
502462306a36Sopenharmony_ci		}
502562306a36Sopenharmony_ci	}
502662306a36Sopenharmony_ci
502762306a36Sopenharmony_ci	err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle,
502862306a36Sopenharmony_ci				    &priv->dpseci_attr);
502962306a36Sopenharmony_ci	if (err) {
503062306a36Sopenharmony_ci		dev_err(dev, "dpseci_get_attributes() failed\n");
503162306a36Sopenharmony_ci		goto err_get_vers;
503262306a36Sopenharmony_ci	}
503362306a36Sopenharmony_ci
503462306a36Sopenharmony_ci	err = dpseci_get_sec_attr(priv->mc_io, 0, ls_dev->mc_handle,
503562306a36Sopenharmony_ci				  &priv->sec_attr);
503662306a36Sopenharmony_ci	if (err) {
503762306a36Sopenharmony_ci		dev_err(dev, "dpseci_get_sec_attr() failed\n");
503862306a36Sopenharmony_ci		goto err_get_vers;
503962306a36Sopenharmony_ci	}
504062306a36Sopenharmony_ci
504162306a36Sopenharmony_ci	err = dpaa2_dpseci_congestion_setup(priv, ls_dev->mc_handle);
504262306a36Sopenharmony_ci	if (err) {
504362306a36Sopenharmony_ci		dev_err(dev, "setup_congestion() failed\n");
504462306a36Sopenharmony_ci		goto err_get_vers;
504562306a36Sopenharmony_ci	}
504662306a36Sopenharmony_ci
504762306a36Sopenharmony_ci	priv->num_pairs = min(priv->dpseci_attr.num_rx_queues,
504862306a36Sopenharmony_ci			      priv->dpseci_attr.num_tx_queues);
504962306a36Sopenharmony_ci	if (priv->num_pairs > num_online_cpus()) {
505062306a36Sopenharmony_ci		dev_warn(dev, "%d queues won't be used\n",
505162306a36Sopenharmony_ci			 priv->num_pairs - num_online_cpus());
505262306a36Sopenharmony_ci		priv->num_pairs = num_online_cpus();
505362306a36Sopenharmony_ci	}
505462306a36Sopenharmony_ci
505562306a36Sopenharmony_ci	for (i = 0; i < priv->dpseci_attr.num_rx_queues; i++) {
505662306a36Sopenharmony_ci		err = dpseci_get_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
505762306a36Sopenharmony_ci					  &priv->rx_queue_attr[i]);
505862306a36Sopenharmony_ci		if (err) {
505962306a36Sopenharmony_ci			dev_err(dev, "dpseci_get_rx_queue() failed\n");
506062306a36Sopenharmony_ci			goto err_get_rx_queue;
506162306a36Sopenharmony_ci		}
506262306a36Sopenharmony_ci	}
506362306a36Sopenharmony_ci
506462306a36Sopenharmony_ci	for (i = 0; i < priv->dpseci_attr.num_tx_queues; i++) {
506562306a36Sopenharmony_ci		err = dpseci_get_tx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
506662306a36Sopenharmony_ci					  &priv->tx_queue_attr[i]);
506762306a36Sopenharmony_ci		if (err) {
506862306a36Sopenharmony_ci			dev_err(dev, "dpseci_get_tx_queue() failed\n");
506962306a36Sopenharmony_ci			goto err_get_rx_queue;
507062306a36Sopenharmony_ci		}
507162306a36Sopenharmony_ci	}
507262306a36Sopenharmony_ci
507362306a36Sopenharmony_ci	i = 0;
507462306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
507562306a36Sopenharmony_ci		u8 j;
507662306a36Sopenharmony_ci
507762306a36Sopenharmony_ci		j = i % priv->num_pairs;
507862306a36Sopenharmony_ci
507962306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, cpu);
508062306a36Sopenharmony_ci		ppriv->req_fqid = priv->tx_queue_attr[j].fqid;
508162306a36Sopenharmony_ci
508262306a36Sopenharmony_ci		/*
508362306a36Sopenharmony_ci		 * Allow all cores to enqueue, while only some of them
508462306a36Sopenharmony_ci		 * will take part in dequeuing.
508562306a36Sopenharmony_ci		 */
508662306a36Sopenharmony_ci		if (++i > priv->num_pairs)
508762306a36Sopenharmony_ci			continue;
508862306a36Sopenharmony_ci
508962306a36Sopenharmony_ci		ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid;
509062306a36Sopenharmony_ci		ppriv->prio = j;
509162306a36Sopenharmony_ci
509262306a36Sopenharmony_ci		dev_dbg(dev, "pair %d: rx queue %d, tx queue %d\n", j,
509362306a36Sopenharmony_ci			priv->rx_queue_attr[j].fqid,
509462306a36Sopenharmony_ci			priv->tx_queue_attr[j].fqid);
509562306a36Sopenharmony_ci
509662306a36Sopenharmony_ci		ppriv->net_dev.dev = *dev;
509762306a36Sopenharmony_ci		INIT_LIST_HEAD(&ppriv->net_dev.napi_list);
509862306a36Sopenharmony_ci		netif_napi_add_tx_weight(&ppriv->net_dev, &ppriv->napi,
509962306a36Sopenharmony_ci					 dpaa2_dpseci_poll,
510062306a36Sopenharmony_ci					 DPAA2_CAAM_NAPI_WEIGHT);
510162306a36Sopenharmony_ci	}
510262306a36Sopenharmony_ci
510362306a36Sopenharmony_ci	return 0;
510462306a36Sopenharmony_ci
510562306a36Sopenharmony_cierr_get_rx_queue:
510662306a36Sopenharmony_ci	dpaa2_dpseci_congestion_free(priv);
510762306a36Sopenharmony_cierr_get_vers:
510862306a36Sopenharmony_ci	dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
510962306a36Sopenharmony_cierr_open:
511062306a36Sopenharmony_ci	return err;
511162306a36Sopenharmony_ci}
511262306a36Sopenharmony_ci
511362306a36Sopenharmony_cistatic int dpaa2_dpseci_enable(struct dpaa2_caam_priv *priv)
511462306a36Sopenharmony_ci{
511562306a36Sopenharmony_ci	struct device *dev = priv->dev;
511662306a36Sopenharmony_ci	struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
511762306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
511862306a36Sopenharmony_ci	int i;
511962306a36Sopenharmony_ci
512062306a36Sopenharmony_ci	for (i = 0; i < priv->num_pairs; i++) {
512162306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, i);
512262306a36Sopenharmony_ci		napi_enable(&ppriv->napi);
512362306a36Sopenharmony_ci	}
512462306a36Sopenharmony_ci
512562306a36Sopenharmony_ci	return dpseci_enable(priv->mc_io, 0, ls_dev->mc_handle);
512662306a36Sopenharmony_ci}
512762306a36Sopenharmony_ci
512862306a36Sopenharmony_cistatic int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv)
512962306a36Sopenharmony_ci{
513062306a36Sopenharmony_ci	struct device *dev = priv->dev;
513162306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
513262306a36Sopenharmony_ci	struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
513362306a36Sopenharmony_ci	int i, err = 0, enabled;
513462306a36Sopenharmony_ci
513562306a36Sopenharmony_ci	err = dpseci_disable(priv->mc_io, 0, ls_dev->mc_handle);
513662306a36Sopenharmony_ci	if (err) {
513762306a36Sopenharmony_ci		dev_err(dev, "dpseci_disable() failed\n");
513862306a36Sopenharmony_ci		return err;
513962306a36Sopenharmony_ci	}
514062306a36Sopenharmony_ci
514162306a36Sopenharmony_ci	err = dpseci_is_enabled(priv->mc_io, 0, ls_dev->mc_handle, &enabled);
514262306a36Sopenharmony_ci	if (err) {
514362306a36Sopenharmony_ci		dev_err(dev, "dpseci_is_enabled() failed\n");
514462306a36Sopenharmony_ci		return err;
514562306a36Sopenharmony_ci	}
514662306a36Sopenharmony_ci
514762306a36Sopenharmony_ci	dev_dbg(dev, "disable: %s\n", enabled ? "false" : "true");
514862306a36Sopenharmony_ci
514962306a36Sopenharmony_ci	for (i = 0; i < priv->num_pairs; i++) {
515062306a36Sopenharmony_ci		ppriv = per_cpu_ptr(priv->ppriv, i);
515162306a36Sopenharmony_ci		napi_disable(&ppriv->napi);
515262306a36Sopenharmony_ci		netif_napi_del(&ppriv->napi);
515362306a36Sopenharmony_ci	}
515462306a36Sopenharmony_ci
515562306a36Sopenharmony_ci	return 0;
515662306a36Sopenharmony_ci}
515762306a36Sopenharmony_ci
515862306a36Sopenharmony_cistatic struct list_head hash_list;
515962306a36Sopenharmony_ci
516062306a36Sopenharmony_cistatic int dpaa2_caam_probe(struct fsl_mc_device *dpseci_dev)
516162306a36Sopenharmony_ci{
516262306a36Sopenharmony_ci	struct device *dev;
516362306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv;
516462306a36Sopenharmony_ci	int i, err = 0;
516562306a36Sopenharmony_ci	bool registered = false;
516662306a36Sopenharmony_ci
516762306a36Sopenharmony_ci	/*
516862306a36Sopenharmony_ci	 * There is no way to get CAAM endianness - there is no direct register
516962306a36Sopenharmony_ci	 * space access and MC f/w does not provide this attribute.
517062306a36Sopenharmony_ci	 * All DPAA2-based SoCs have little endian CAAM, thus hard-code this
517162306a36Sopenharmony_ci	 * property.
517262306a36Sopenharmony_ci	 */
517362306a36Sopenharmony_ci	caam_little_end = true;
517462306a36Sopenharmony_ci
517562306a36Sopenharmony_ci	caam_imx = false;
517662306a36Sopenharmony_ci
517762306a36Sopenharmony_ci	dev = &dpseci_dev->dev;
517862306a36Sopenharmony_ci
517962306a36Sopenharmony_ci	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
518062306a36Sopenharmony_ci	if (!priv)
518162306a36Sopenharmony_ci		return -ENOMEM;
518262306a36Sopenharmony_ci
518362306a36Sopenharmony_ci	dev_set_drvdata(dev, priv);
518462306a36Sopenharmony_ci
518562306a36Sopenharmony_ci	priv->domain = iommu_get_domain_for_dev(dev);
518662306a36Sopenharmony_ci
518762306a36Sopenharmony_ci	qi_cache = kmem_cache_create("dpaa2_caamqicache", CAAM_QI_MEMCACHE_SIZE,
518862306a36Sopenharmony_ci				     0, 0, NULL);
518962306a36Sopenharmony_ci	if (!qi_cache) {
519062306a36Sopenharmony_ci		dev_err(dev, "Can't allocate SEC cache\n");
519162306a36Sopenharmony_ci		return -ENOMEM;
519262306a36Sopenharmony_ci	}
519362306a36Sopenharmony_ci
519462306a36Sopenharmony_ci	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(49));
519562306a36Sopenharmony_ci	if (err) {
519662306a36Sopenharmony_ci		dev_err(dev, "dma_set_mask_and_coherent() failed\n");
519762306a36Sopenharmony_ci		goto err_dma_mask;
519862306a36Sopenharmony_ci	}
519962306a36Sopenharmony_ci
520062306a36Sopenharmony_ci	/* Obtain a MC portal */
520162306a36Sopenharmony_ci	err = fsl_mc_portal_allocate(dpseci_dev, 0, &priv->mc_io);
520262306a36Sopenharmony_ci	if (err) {
520362306a36Sopenharmony_ci		if (err == -ENXIO)
520462306a36Sopenharmony_ci			err = -EPROBE_DEFER;
520562306a36Sopenharmony_ci		else
520662306a36Sopenharmony_ci			dev_err(dev, "MC portal allocation failed\n");
520762306a36Sopenharmony_ci
520862306a36Sopenharmony_ci		goto err_dma_mask;
520962306a36Sopenharmony_ci	}
521062306a36Sopenharmony_ci
521162306a36Sopenharmony_ci	priv->ppriv = alloc_percpu(*priv->ppriv);
521262306a36Sopenharmony_ci	if (!priv->ppriv) {
521362306a36Sopenharmony_ci		dev_err(dev, "alloc_percpu() failed\n");
521462306a36Sopenharmony_ci		err = -ENOMEM;
521562306a36Sopenharmony_ci		goto err_alloc_ppriv;
521662306a36Sopenharmony_ci	}
521762306a36Sopenharmony_ci
521862306a36Sopenharmony_ci	/* DPSECI initialization */
521962306a36Sopenharmony_ci	err = dpaa2_dpseci_setup(dpseci_dev);
522062306a36Sopenharmony_ci	if (err) {
522162306a36Sopenharmony_ci		dev_err(dev, "dpaa2_dpseci_setup() failed\n");
522262306a36Sopenharmony_ci		goto err_dpseci_setup;
522362306a36Sopenharmony_ci	}
522462306a36Sopenharmony_ci
522562306a36Sopenharmony_ci	/* DPIO */
522662306a36Sopenharmony_ci	err = dpaa2_dpseci_dpio_setup(priv);
522762306a36Sopenharmony_ci	if (err) {
522862306a36Sopenharmony_ci		dev_err_probe(dev, err, "dpaa2_dpseci_dpio_setup() failed\n");
522962306a36Sopenharmony_ci		goto err_dpio_setup;
523062306a36Sopenharmony_ci	}
523162306a36Sopenharmony_ci
523262306a36Sopenharmony_ci	/* DPSECI binding to DPIO */
523362306a36Sopenharmony_ci	err = dpaa2_dpseci_bind(priv);
523462306a36Sopenharmony_ci	if (err) {
523562306a36Sopenharmony_ci		dev_err(dev, "dpaa2_dpseci_bind() failed\n");
523662306a36Sopenharmony_ci		goto err_bind;
523762306a36Sopenharmony_ci	}
523862306a36Sopenharmony_ci
523962306a36Sopenharmony_ci	/* DPSECI enable */
524062306a36Sopenharmony_ci	err = dpaa2_dpseci_enable(priv);
524162306a36Sopenharmony_ci	if (err) {
524262306a36Sopenharmony_ci		dev_err(dev, "dpaa2_dpseci_enable() failed\n");
524362306a36Sopenharmony_ci		goto err_bind;
524462306a36Sopenharmony_ci	}
524562306a36Sopenharmony_ci
524662306a36Sopenharmony_ci	dpaa2_dpseci_debugfs_init(priv);
524762306a36Sopenharmony_ci
524862306a36Sopenharmony_ci	/* register crypto algorithms the device supports */
524962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
525062306a36Sopenharmony_ci		struct caam_skcipher_alg *t_alg = driver_algs + i;
525162306a36Sopenharmony_ci		u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
525262306a36Sopenharmony_ci
525362306a36Sopenharmony_ci		/* Skip DES algorithms if not supported by device */
525462306a36Sopenharmony_ci		if (!priv->sec_attr.des_acc_num &&
525562306a36Sopenharmony_ci		    (alg_sel == OP_ALG_ALGSEL_3DES ||
525662306a36Sopenharmony_ci		     alg_sel == OP_ALG_ALGSEL_DES))
525762306a36Sopenharmony_ci			continue;
525862306a36Sopenharmony_ci
525962306a36Sopenharmony_ci		/* Skip AES algorithms if not supported by device */
526062306a36Sopenharmony_ci		if (!priv->sec_attr.aes_acc_num &&
526162306a36Sopenharmony_ci		    alg_sel == OP_ALG_ALGSEL_AES)
526262306a36Sopenharmony_ci			continue;
526362306a36Sopenharmony_ci
526462306a36Sopenharmony_ci		/* Skip CHACHA20 algorithms if not supported by device */
526562306a36Sopenharmony_ci		if (alg_sel == OP_ALG_ALGSEL_CHACHA20 &&
526662306a36Sopenharmony_ci		    !priv->sec_attr.ccha_acc_num)
526762306a36Sopenharmony_ci			continue;
526862306a36Sopenharmony_ci
526962306a36Sopenharmony_ci		t_alg->caam.dev = dev;
527062306a36Sopenharmony_ci		caam_skcipher_alg_init(t_alg);
527162306a36Sopenharmony_ci
527262306a36Sopenharmony_ci		err = crypto_register_skcipher(&t_alg->skcipher);
527362306a36Sopenharmony_ci		if (err) {
527462306a36Sopenharmony_ci			dev_warn(dev, "%s alg registration failed: %d\n",
527562306a36Sopenharmony_ci				 t_alg->skcipher.base.cra_driver_name, err);
527662306a36Sopenharmony_ci			continue;
527762306a36Sopenharmony_ci		}
527862306a36Sopenharmony_ci
527962306a36Sopenharmony_ci		t_alg->registered = true;
528062306a36Sopenharmony_ci		registered = true;
528162306a36Sopenharmony_ci	}
528262306a36Sopenharmony_ci
528362306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
528462306a36Sopenharmony_ci		struct caam_aead_alg *t_alg = driver_aeads + i;
528562306a36Sopenharmony_ci		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
528662306a36Sopenharmony_ci				 OP_ALG_ALGSEL_MASK;
528762306a36Sopenharmony_ci		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
528862306a36Sopenharmony_ci				 OP_ALG_ALGSEL_MASK;
528962306a36Sopenharmony_ci
529062306a36Sopenharmony_ci		/* Skip DES algorithms if not supported by device */
529162306a36Sopenharmony_ci		if (!priv->sec_attr.des_acc_num &&
529262306a36Sopenharmony_ci		    (c1_alg_sel == OP_ALG_ALGSEL_3DES ||
529362306a36Sopenharmony_ci		     c1_alg_sel == OP_ALG_ALGSEL_DES))
529462306a36Sopenharmony_ci			continue;
529562306a36Sopenharmony_ci
529662306a36Sopenharmony_ci		/* Skip AES algorithms if not supported by device */
529762306a36Sopenharmony_ci		if (!priv->sec_attr.aes_acc_num &&
529862306a36Sopenharmony_ci		    c1_alg_sel == OP_ALG_ALGSEL_AES)
529962306a36Sopenharmony_ci			continue;
530062306a36Sopenharmony_ci
530162306a36Sopenharmony_ci		/* Skip CHACHA20 algorithms if not supported by device */
530262306a36Sopenharmony_ci		if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 &&
530362306a36Sopenharmony_ci		    !priv->sec_attr.ccha_acc_num)
530462306a36Sopenharmony_ci			continue;
530562306a36Sopenharmony_ci
530662306a36Sopenharmony_ci		/* Skip POLY1305 algorithms if not supported by device */
530762306a36Sopenharmony_ci		if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 &&
530862306a36Sopenharmony_ci		    !priv->sec_attr.ptha_acc_num)
530962306a36Sopenharmony_ci			continue;
531062306a36Sopenharmony_ci
531162306a36Sopenharmony_ci		/*
531262306a36Sopenharmony_ci		 * Skip algorithms requiring message digests
531362306a36Sopenharmony_ci		 * if MD not supported by device.
531462306a36Sopenharmony_ci		 */
531562306a36Sopenharmony_ci		if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 &&
531662306a36Sopenharmony_ci		    !priv->sec_attr.md_acc_num)
531762306a36Sopenharmony_ci			continue;
531862306a36Sopenharmony_ci
531962306a36Sopenharmony_ci		t_alg->caam.dev = dev;
532062306a36Sopenharmony_ci		caam_aead_alg_init(t_alg);
532162306a36Sopenharmony_ci
532262306a36Sopenharmony_ci		err = crypto_register_aead(&t_alg->aead);
532362306a36Sopenharmony_ci		if (err) {
532462306a36Sopenharmony_ci			dev_warn(dev, "%s alg registration failed: %d\n",
532562306a36Sopenharmony_ci				 t_alg->aead.base.cra_driver_name, err);
532662306a36Sopenharmony_ci			continue;
532762306a36Sopenharmony_ci		}
532862306a36Sopenharmony_ci
532962306a36Sopenharmony_ci		t_alg->registered = true;
533062306a36Sopenharmony_ci		registered = true;
533162306a36Sopenharmony_ci	}
533262306a36Sopenharmony_ci	if (registered)
533362306a36Sopenharmony_ci		dev_info(dev, "algorithms registered in /proc/crypto\n");
533462306a36Sopenharmony_ci
533562306a36Sopenharmony_ci	/* register hash algorithms the device supports */
533662306a36Sopenharmony_ci	INIT_LIST_HEAD(&hash_list);
533762306a36Sopenharmony_ci
533862306a36Sopenharmony_ci	/*
533962306a36Sopenharmony_ci	 * Skip registration of any hashing algorithms if MD block
534062306a36Sopenharmony_ci	 * is not present.
534162306a36Sopenharmony_ci	 */
534262306a36Sopenharmony_ci	if (!priv->sec_attr.md_acc_num)
534362306a36Sopenharmony_ci		return 0;
534462306a36Sopenharmony_ci
534562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(driver_hash); i++) {
534662306a36Sopenharmony_ci		struct caam_hash_alg *t_alg;
534762306a36Sopenharmony_ci		struct caam_hash_template *alg = driver_hash + i;
534862306a36Sopenharmony_ci
534962306a36Sopenharmony_ci		/* register hmac version */
535062306a36Sopenharmony_ci		t_alg = caam_hash_alloc(dev, alg, true);
535162306a36Sopenharmony_ci		if (IS_ERR(t_alg)) {
535262306a36Sopenharmony_ci			err = PTR_ERR(t_alg);
535362306a36Sopenharmony_ci			dev_warn(dev, "%s hash alg allocation failed: %d\n",
535462306a36Sopenharmony_ci				 alg->hmac_driver_name, err);
535562306a36Sopenharmony_ci			continue;
535662306a36Sopenharmony_ci		}
535762306a36Sopenharmony_ci
535862306a36Sopenharmony_ci		err = crypto_register_ahash(&t_alg->ahash_alg);
535962306a36Sopenharmony_ci		if (err) {
536062306a36Sopenharmony_ci			dev_warn(dev, "%s alg registration failed: %d\n",
536162306a36Sopenharmony_ci				 t_alg->ahash_alg.halg.base.cra_driver_name,
536262306a36Sopenharmony_ci				 err);
536362306a36Sopenharmony_ci			kfree(t_alg);
536462306a36Sopenharmony_ci		} else {
536562306a36Sopenharmony_ci			list_add_tail(&t_alg->entry, &hash_list);
536662306a36Sopenharmony_ci		}
536762306a36Sopenharmony_ci
536862306a36Sopenharmony_ci		/* register unkeyed version */
536962306a36Sopenharmony_ci		t_alg = caam_hash_alloc(dev, alg, false);
537062306a36Sopenharmony_ci		if (IS_ERR(t_alg)) {
537162306a36Sopenharmony_ci			err = PTR_ERR(t_alg);
537262306a36Sopenharmony_ci			dev_warn(dev, "%s alg allocation failed: %d\n",
537362306a36Sopenharmony_ci				 alg->driver_name, err);
537462306a36Sopenharmony_ci			continue;
537562306a36Sopenharmony_ci		}
537662306a36Sopenharmony_ci
537762306a36Sopenharmony_ci		err = crypto_register_ahash(&t_alg->ahash_alg);
537862306a36Sopenharmony_ci		if (err) {
537962306a36Sopenharmony_ci			dev_warn(dev, "%s alg registration failed: %d\n",
538062306a36Sopenharmony_ci				 t_alg->ahash_alg.halg.base.cra_driver_name,
538162306a36Sopenharmony_ci				 err);
538262306a36Sopenharmony_ci			kfree(t_alg);
538362306a36Sopenharmony_ci		} else {
538462306a36Sopenharmony_ci			list_add_tail(&t_alg->entry, &hash_list);
538562306a36Sopenharmony_ci		}
538662306a36Sopenharmony_ci	}
538762306a36Sopenharmony_ci	if (!list_empty(&hash_list))
538862306a36Sopenharmony_ci		dev_info(dev, "hash algorithms registered in /proc/crypto\n");
538962306a36Sopenharmony_ci
539062306a36Sopenharmony_ci	return err;
539162306a36Sopenharmony_ci
539262306a36Sopenharmony_cierr_bind:
539362306a36Sopenharmony_ci	dpaa2_dpseci_dpio_free(priv);
539462306a36Sopenharmony_cierr_dpio_setup:
539562306a36Sopenharmony_ci	dpaa2_dpseci_free(priv);
539662306a36Sopenharmony_cierr_dpseci_setup:
539762306a36Sopenharmony_ci	free_percpu(priv->ppriv);
539862306a36Sopenharmony_cierr_alloc_ppriv:
539962306a36Sopenharmony_ci	fsl_mc_portal_free(priv->mc_io);
540062306a36Sopenharmony_cierr_dma_mask:
540162306a36Sopenharmony_ci	kmem_cache_destroy(qi_cache);
540262306a36Sopenharmony_ci
540362306a36Sopenharmony_ci	return err;
540462306a36Sopenharmony_ci}
540562306a36Sopenharmony_ci
540662306a36Sopenharmony_cistatic void __cold dpaa2_caam_remove(struct fsl_mc_device *ls_dev)
540762306a36Sopenharmony_ci{
540862306a36Sopenharmony_ci	struct device *dev;
540962306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv;
541062306a36Sopenharmony_ci	int i;
541162306a36Sopenharmony_ci
541262306a36Sopenharmony_ci	dev = &ls_dev->dev;
541362306a36Sopenharmony_ci	priv = dev_get_drvdata(dev);
541462306a36Sopenharmony_ci
541562306a36Sopenharmony_ci	dpaa2_dpseci_debugfs_exit(priv);
541662306a36Sopenharmony_ci
541762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
541862306a36Sopenharmony_ci		struct caam_aead_alg *t_alg = driver_aeads + i;
541962306a36Sopenharmony_ci
542062306a36Sopenharmony_ci		if (t_alg->registered)
542162306a36Sopenharmony_ci			crypto_unregister_aead(&t_alg->aead);
542262306a36Sopenharmony_ci	}
542362306a36Sopenharmony_ci
542462306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
542562306a36Sopenharmony_ci		struct caam_skcipher_alg *t_alg = driver_algs + i;
542662306a36Sopenharmony_ci
542762306a36Sopenharmony_ci		if (t_alg->registered)
542862306a36Sopenharmony_ci			crypto_unregister_skcipher(&t_alg->skcipher);
542962306a36Sopenharmony_ci	}
543062306a36Sopenharmony_ci
543162306a36Sopenharmony_ci	if (hash_list.next) {
543262306a36Sopenharmony_ci		struct caam_hash_alg *t_hash_alg, *p;
543362306a36Sopenharmony_ci
543462306a36Sopenharmony_ci		list_for_each_entry_safe(t_hash_alg, p, &hash_list, entry) {
543562306a36Sopenharmony_ci			crypto_unregister_ahash(&t_hash_alg->ahash_alg);
543662306a36Sopenharmony_ci			list_del(&t_hash_alg->entry);
543762306a36Sopenharmony_ci			kfree(t_hash_alg);
543862306a36Sopenharmony_ci		}
543962306a36Sopenharmony_ci	}
544062306a36Sopenharmony_ci
544162306a36Sopenharmony_ci	dpaa2_dpseci_disable(priv);
544262306a36Sopenharmony_ci	dpaa2_dpseci_dpio_free(priv);
544362306a36Sopenharmony_ci	dpaa2_dpseci_free(priv);
544462306a36Sopenharmony_ci	free_percpu(priv->ppriv);
544562306a36Sopenharmony_ci	fsl_mc_portal_free(priv->mc_io);
544662306a36Sopenharmony_ci	kmem_cache_destroy(qi_cache);
544762306a36Sopenharmony_ci}
544862306a36Sopenharmony_ci
544962306a36Sopenharmony_ciint dpaa2_caam_enqueue(struct device *dev, struct caam_request *req)
545062306a36Sopenharmony_ci{
545162306a36Sopenharmony_ci	struct dpaa2_fd fd;
545262306a36Sopenharmony_ci	struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
545362306a36Sopenharmony_ci	struct dpaa2_caam_priv_per_cpu *ppriv;
545462306a36Sopenharmony_ci	int err = 0, i;
545562306a36Sopenharmony_ci
545662306a36Sopenharmony_ci	if (IS_ERR(req))
545762306a36Sopenharmony_ci		return PTR_ERR(req);
545862306a36Sopenharmony_ci
545962306a36Sopenharmony_ci	if (priv->cscn_mem) {
546062306a36Sopenharmony_ci		dma_sync_single_for_cpu(priv->dev, priv->cscn_dma,
546162306a36Sopenharmony_ci					DPAA2_CSCN_SIZE,
546262306a36Sopenharmony_ci					DMA_FROM_DEVICE);
546362306a36Sopenharmony_ci		if (unlikely(dpaa2_cscn_state_congested(priv->cscn_mem))) {
546462306a36Sopenharmony_ci			dev_dbg_ratelimited(dev, "Dropping request\n");
546562306a36Sopenharmony_ci			return -EBUSY;
546662306a36Sopenharmony_ci		}
546762306a36Sopenharmony_ci	}
546862306a36Sopenharmony_ci
546962306a36Sopenharmony_ci	dpaa2_fl_set_flc(&req->fd_flt[1], req->flc_dma);
547062306a36Sopenharmony_ci
547162306a36Sopenharmony_ci	req->fd_flt_dma = dma_map_single(dev, req->fd_flt, sizeof(req->fd_flt),
547262306a36Sopenharmony_ci					 DMA_BIDIRECTIONAL);
547362306a36Sopenharmony_ci	if (dma_mapping_error(dev, req->fd_flt_dma)) {
547462306a36Sopenharmony_ci		dev_err(dev, "DMA mapping error for QI enqueue request\n");
547562306a36Sopenharmony_ci		goto err_out;
547662306a36Sopenharmony_ci	}
547762306a36Sopenharmony_ci
547862306a36Sopenharmony_ci	memset(&fd, 0, sizeof(fd));
547962306a36Sopenharmony_ci	dpaa2_fd_set_format(&fd, dpaa2_fd_list);
548062306a36Sopenharmony_ci	dpaa2_fd_set_addr(&fd, req->fd_flt_dma);
548162306a36Sopenharmony_ci	dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1]));
548262306a36Sopenharmony_ci	dpaa2_fd_set_flc(&fd, req->flc_dma);
548362306a36Sopenharmony_ci
548462306a36Sopenharmony_ci	ppriv = raw_cpu_ptr(priv->ppriv);
548562306a36Sopenharmony_ci	for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) {
548662306a36Sopenharmony_ci		err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid,
548762306a36Sopenharmony_ci						  &fd);
548862306a36Sopenharmony_ci		if (err != -EBUSY)
548962306a36Sopenharmony_ci			break;
549062306a36Sopenharmony_ci
549162306a36Sopenharmony_ci		cpu_relax();
549262306a36Sopenharmony_ci	}
549362306a36Sopenharmony_ci
549462306a36Sopenharmony_ci	if (unlikely(err)) {
549562306a36Sopenharmony_ci		dev_err_ratelimited(dev, "Error enqueuing frame: %d\n", err);
549662306a36Sopenharmony_ci		goto err_out;
549762306a36Sopenharmony_ci	}
549862306a36Sopenharmony_ci
549962306a36Sopenharmony_ci	return -EINPROGRESS;
550062306a36Sopenharmony_ci
550162306a36Sopenharmony_cierr_out:
550262306a36Sopenharmony_ci	dma_unmap_single(dev, req->fd_flt_dma, sizeof(req->fd_flt),
550362306a36Sopenharmony_ci			 DMA_BIDIRECTIONAL);
550462306a36Sopenharmony_ci	return -EIO;
550562306a36Sopenharmony_ci}
550662306a36Sopenharmony_ciEXPORT_SYMBOL(dpaa2_caam_enqueue);
550762306a36Sopenharmony_ci
550862306a36Sopenharmony_cistatic const struct fsl_mc_device_id dpaa2_caam_match_id_table[] = {
550962306a36Sopenharmony_ci	{
551062306a36Sopenharmony_ci		.vendor = FSL_MC_VENDOR_FREESCALE,
551162306a36Sopenharmony_ci		.obj_type = "dpseci",
551262306a36Sopenharmony_ci	},
551362306a36Sopenharmony_ci	{ .vendor = 0x0 }
551462306a36Sopenharmony_ci};
551562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(fslmc, dpaa2_caam_match_id_table);
551662306a36Sopenharmony_ci
551762306a36Sopenharmony_cistatic struct fsl_mc_driver dpaa2_caam_driver = {
551862306a36Sopenharmony_ci	.driver = {
551962306a36Sopenharmony_ci		.name		= KBUILD_MODNAME,
552062306a36Sopenharmony_ci		.owner		= THIS_MODULE,
552162306a36Sopenharmony_ci	},
552262306a36Sopenharmony_ci	.probe		= dpaa2_caam_probe,
552362306a36Sopenharmony_ci	.remove		= dpaa2_caam_remove,
552462306a36Sopenharmony_ci	.match_id_table = dpaa2_caam_match_id_table
552562306a36Sopenharmony_ci};
552662306a36Sopenharmony_ci
552762306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
552862306a36Sopenharmony_ciMODULE_AUTHOR("Freescale Semiconductor, Inc");
552962306a36Sopenharmony_ciMODULE_DESCRIPTION("Freescale DPAA2 CAAM Driver");
553062306a36Sopenharmony_ci
553162306a36Sopenharmony_cimodule_fsl_mc_driver(dpaa2_caam_driver);
5532