162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2021 Aspeed Technology Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include "aspeed-hace.h"
762306a36Sopenharmony_ci#include <crypto/des.h>
862306a36Sopenharmony_ci#include <crypto/engine.h>
962306a36Sopenharmony_ci#include <crypto/internal/des.h>
1062306a36Sopenharmony_ci#include <crypto/internal/skcipher.h>
1162306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1262306a36Sopenharmony_ci#include <linux/err.h>
1362306a36Sopenharmony_ci#include <linux/io.h>
1462306a36Sopenharmony_ci#include <linux/kernel.h>
1562306a36Sopenharmony_ci#include <linux/module.h>
1662306a36Sopenharmony_ci#include <linux/scatterlist.h>
1762306a36Sopenharmony_ci#include <linux/string.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO_DEBUG
2062306a36Sopenharmony_ci#define CIPHER_DBG(h, fmt, ...)	\
2162306a36Sopenharmony_ci	dev_info((h)->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
2262306a36Sopenharmony_ci#else
2362306a36Sopenharmony_ci#define CIPHER_DBG(h, fmt, ...)	\
2462306a36Sopenharmony_ci	dev_dbg((h)->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
2562306a36Sopenharmony_ci#endif
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic int aspeed_crypto_do_fallback(struct skcipher_request *areq)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx = skcipher_request_ctx(areq);
3062306a36Sopenharmony_ci	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
3162306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
3262306a36Sopenharmony_ci	int err;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
3562306a36Sopenharmony_ci	skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags,
3662306a36Sopenharmony_ci				      areq->base.complete, areq->base.data);
3762306a36Sopenharmony_ci	skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst,
3862306a36Sopenharmony_ci				   areq->cryptlen, areq->iv);
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	if (rctx->enc_cmd & HACE_CMD_ENCRYPT)
4162306a36Sopenharmony_ci		err = crypto_skcipher_encrypt(&rctx->fallback_req);
4262306a36Sopenharmony_ci	else
4362306a36Sopenharmony_ci		err = crypto_skcipher_decrypt(&rctx->fallback_req);
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	return err;
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic bool aspeed_crypto_need_fallback(struct skcipher_request *areq)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx = skcipher_request_ctx(areq);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	if (areq->cryptlen == 0)
5362306a36Sopenharmony_ci		return true;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	if ((rctx->enc_cmd & HACE_CMD_DES_SELECT) &&
5662306a36Sopenharmony_ci	    !IS_ALIGNED(areq->cryptlen, DES_BLOCK_SIZE))
5762306a36Sopenharmony_ci		return true;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	if ((!(rctx->enc_cmd & HACE_CMD_DES_SELECT)) &&
6062306a36Sopenharmony_ci	    !IS_ALIGNED(areq->cryptlen, AES_BLOCK_SIZE))
6162306a36Sopenharmony_ci		return true;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	return false;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic int aspeed_hace_crypto_handle_queue(struct aspeed_hace_dev *hace_dev,
6762306a36Sopenharmony_ci					   struct skcipher_request *req)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	if (hace_dev->version == AST2500_VERSION &&
7062306a36Sopenharmony_ci	    aspeed_crypto_need_fallback(req)) {
7162306a36Sopenharmony_ci		CIPHER_DBG(hace_dev, "SW fallback\n");
7262306a36Sopenharmony_ci		return aspeed_crypto_do_fallback(req);
7362306a36Sopenharmony_ci	}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	return crypto_transfer_skcipher_request_to_engine(
7662306a36Sopenharmony_ci			hace_dev->crypt_engine_crypto, req);
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic int aspeed_crypto_do_request(struct crypto_engine *engine, void *areq)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	struct skcipher_request *req = skcipher_request_cast(areq);
8262306a36Sopenharmony_ci	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
8362306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
8462306a36Sopenharmony_ci	struct aspeed_hace_dev *hace_dev = ctx->hace_dev;
8562306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine;
8662306a36Sopenharmony_ci	int rc;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	crypto_engine = &hace_dev->crypto_engine;
8962306a36Sopenharmony_ci	crypto_engine->req = req;
9062306a36Sopenharmony_ci	crypto_engine->flags |= CRYPTO_FLAGS_BUSY;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	rc = ctx->start(hace_dev);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	if (rc != -EINPROGRESS)
9562306a36Sopenharmony_ci		return -EIO;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	return 0;
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic int aspeed_sk_complete(struct aspeed_hace_dev *hace_dev, int err)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
10362306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx;
10462306a36Sopenharmony_ci	struct skcipher_request *req;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "\n");
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	req = crypto_engine->req;
10962306a36Sopenharmony_ci	rctx = skcipher_request_ctx(req);
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	if (rctx->enc_cmd & HACE_CMD_IV_REQUIRE) {
11262306a36Sopenharmony_ci		if (rctx->enc_cmd & HACE_CMD_DES_SELECT)
11362306a36Sopenharmony_ci			memcpy(req->iv, crypto_engine->cipher_ctx +
11462306a36Sopenharmony_ci			       DES_KEY_SIZE, DES_KEY_SIZE);
11562306a36Sopenharmony_ci		else
11662306a36Sopenharmony_ci			memcpy(req->iv, crypto_engine->cipher_ctx,
11762306a36Sopenharmony_ci			       AES_BLOCK_SIZE);
11862306a36Sopenharmony_ci	}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	crypto_engine->flags &= ~CRYPTO_FLAGS_BUSY;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	crypto_finalize_skcipher_request(hace_dev->crypt_engine_crypto, req,
12362306a36Sopenharmony_ci					 err);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	return err;
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistatic int aspeed_sk_transfer_sg(struct aspeed_hace_dev *hace_dev)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
13162306a36Sopenharmony_ci	struct device *dev = hace_dev->dev;
13262306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx;
13362306a36Sopenharmony_ci	struct skcipher_request *req;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "\n");
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	req = crypto_engine->req;
13862306a36Sopenharmony_ci	rctx = skcipher_request_ctx(req);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	if (req->src == req->dst) {
14162306a36Sopenharmony_ci		dma_unmap_sg(dev, req->src, rctx->src_nents, DMA_BIDIRECTIONAL);
14262306a36Sopenharmony_ci	} else {
14362306a36Sopenharmony_ci		dma_unmap_sg(dev, req->src, rctx->src_nents, DMA_TO_DEVICE);
14462306a36Sopenharmony_ci		dma_unmap_sg(dev, req->dst, rctx->dst_nents, DMA_FROM_DEVICE);
14562306a36Sopenharmony_ci	}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	return aspeed_sk_complete(hace_dev, 0);
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic int aspeed_sk_transfer(struct aspeed_hace_dev *hace_dev)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
15362306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx;
15462306a36Sopenharmony_ci	struct skcipher_request *req;
15562306a36Sopenharmony_ci	struct scatterlist *out_sg;
15662306a36Sopenharmony_ci	int nbytes = 0;
15762306a36Sopenharmony_ci	int rc = 0;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	req = crypto_engine->req;
16062306a36Sopenharmony_ci	rctx = skcipher_request_ctx(req);
16162306a36Sopenharmony_ci	out_sg = req->dst;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	/* Copy output buffer to dst scatter-gather lists */
16462306a36Sopenharmony_ci	nbytes = sg_copy_from_buffer(out_sg, rctx->dst_nents,
16562306a36Sopenharmony_ci				     crypto_engine->cipher_addr, req->cryptlen);
16662306a36Sopenharmony_ci	if (!nbytes) {
16762306a36Sopenharmony_ci		dev_warn(hace_dev->dev, "invalid sg copy, %s:0x%x, %s:0x%x\n",
16862306a36Sopenharmony_ci			 "nbytes", nbytes, "cryptlen", req->cryptlen);
16962306a36Sopenharmony_ci		rc = -EINVAL;
17062306a36Sopenharmony_ci	}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "%s:%d, %s:%d, %s:%d, %s:%p\n",
17362306a36Sopenharmony_ci		   "nbytes", nbytes, "req->cryptlen", req->cryptlen,
17462306a36Sopenharmony_ci		   "nb_out_sg", rctx->dst_nents,
17562306a36Sopenharmony_ci		   "cipher addr", crypto_engine->cipher_addr);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	return aspeed_sk_complete(hace_dev, rc);
17862306a36Sopenharmony_ci}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_cistatic int aspeed_sk_start(struct aspeed_hace_dev *hace_dev)
18162306a36Sopenharmony_ci{
18262306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
18362306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx;
18462306a36Sopenharmony_ci	struct skcipher_request *req;
18562306a36Sopenharmony_ci	struct scatterlist *in_sg;
18662306a36Sopenharmony_ci	int nbytes;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	req = crypto_engine->req;
18962306a36Sopenharmony_ci	rctx = skcipher_request_ctx(req);
19062306a36Sopenharmony_ci	in_sg = req->src;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	nbytes = sg_copy_to_buffer(in_sg, rctx->src_nents,
19362306a36Sopenharmony_ci				   crypto_engine->cipher_addr, req->cryptlen);
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "%s:%d, %s:%d, %s:%d, %s:%p\n",
19662306a36Sopenharmony_ci		   "nbytes", nbytes, "req->cryptlen", req->cryptlen,
19762306a36Sopenharmony_ci		   "nb_in_sg", rctx->src_nents,
19862306a36Sopenharmony_ci		   "cipher addr", crypto_engine->cipher_addr);
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	if (!nbytes) {
20162306a36Sopenharmony_ci		dev_warn(hace_dev->dev, "invalid sg copy, %s:0x%x, %s:0x%x\n",
20262306a36Sopenharmony_ci			 "nbytes", nbytes, "cryptlen", req->cryptlen);
20362306a36Sopenharmony_ci		return -EINVAL;
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	crypto_engine->resume = aspeed_sk_transfer;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	/* Trigger engines */
20962306a36Sopenharmony_ci	ast_hace_write(hace_dev, crypto_engine->cipher_dma_addr,
21062306a36Sopenharmony_ci		       ASPEED_HACE_SRC);
21162306a36Sopenharmony_ci	ast_hace_write(hace_dev, crypto_engine->cipher_dma_addr,
21262306a36Sopenharmony_ci		       ASPEED_HACE_DEST);
21362306a36Sopenharmony_ci	ast_hace_write(hace_dev, req->cryptlen, ASPEED_HACE_DATA_LEN);
21462306a36Sopenharmony_ci	ast_hace_write(hace_dev, rctx->enc_cmd, ASPEED_HACE_CMD);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	return -EINPROGRESS;
21762306a36Sopenharmony_ci}
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistatic int aspeed_sk_start_sg(struct aspeed_hace_dev *hace_dev)
22062306a36Sopenharmony_ci{
22162306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
22262306a36Sopenharmony_ci	struct aspeed_sg_list *src_list, *dst_list;
22362306a36Sopenharmony_ci	dma_addr_t src_dma_addr, dst_dma_addr;
22462306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx;
22562306a36Sopenharmony_ci	struct skcipher_request *req;
22662306a36Sopenharmony_ci	struct scatterlist *s;
22762306a36Sopenharmony_ci	int src_sg_len;
22862306a36Sopenharmony_ci	int dst_sg_len;
22962306a36Sopenharmony_ci	int total, i;
23062306a36Sopenharmony_ci	int rc;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "\n");
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	req = crypto_engine->req;
23562306a36Sopenharmony_ci	rctx = skcipher_request_ctx(req);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	rctx->enc_cmd |= HACE_CMD_DES_SG_CTRL | HACE_CMD_SRC_SG_CTRL |
23862306a36Sopenharmony_ci			 HACE_CMD_AES_KEY_HW_EXP | HACE_CMD_MBUS_REQ_SYNC_EN;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	/* BIDIRECTIONAL */
24162306a36Sopenharmony_ci	if (req->dst == req->src) {
24262306a36Sopenharmony_ci		src_sg_len = dma_map_sg(hace_dev->dev, req->src,
24362306a36Sopenharmony_ci					rctx->src_nents, DMA_BIDIRECTIONAL);
24462306a36Sopenharmony_ci		dst_sg_len = src_sg_len;
24562306a36Sopenharmony_ci		if (!src_sg_len) {
24662306a36Sopenharmony_ci			dev_warn(hace_dev->dev, "dma_map_sg() src error\n");
24762306a36Sopenharmony_ci			return -EINVAL;
24862306a36Sopenharmony_ci		}
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	} else {
25162306a36Sopenharmony_ci		src_sg_len = dma_map_sg(hace_dev->dev, req->src,
25262306a36Sopenharmony_ci					rctx->src_nents, DMA_TO_DEVICE);
25362306a36Sopenharmony_ci		if (!src_sg_len) {
25462306a36Sopenharmony_ci			dev_warn(hace_dev->dev, "dma_map_sg() src error\n");
25562306a36Sopenharmony_ci			return -EINVAL;
25662306a36Sopenharmony_ci		}
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci		dst_sg_len = dma_map_sg(hace_dev->dev, req->dst,
25962306a36Sopenharmony_ci					rctx->dst_nents, DMA_FROM_DEVICE);
26062306a36Sopenharmony_ci		if (!dst_sg_len) {
26162306a36Sopenharmony_ci			dev_warn(hace_dev->dev, "dma_map_sg() dst error\n");
26262306a36Sopenharmony_ci			rc = -EINVAL;
26362306a36Sopenharmony_ci			goto free_req_src;
26462306a36Sopenharmony_ci		}
26562306a36Sopenharmony_ci	}
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	src_list = (struct aspeed_sg_list *)crypto_engine->cipher_addr;
26862306a36Sopenharmony_ci	src_dma_addr = crypto_engine->cipher_dma_addr;
26962306a36Sopenharmony_ci	total = req->cryptlen;
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	for_each_sg(req->src, s, src_sg_len, i) {
27262306a36Sopenharmony_ci		u32 phy_addr = sg_dma_address(s);
27362306a36Sopenharmony_ci		u32 len = sg_dma_len(s);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci		if (total > len)
27662306a36Sopenharmony_ci			total -= len;
27762306a36Sopenharmony_ci		else {
27862306a36Sopenharmony_ci			/* last sg list */
27962306a36Sopenharmony_ci			len = total;
28062306a36Sopenharmony_ci			len |= BIT(31);
28162306a36Sopenharmony_ci			total = 0;
28262306a36Sopenharmony_ci		}
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci		src_list[i].phy_addr = cpu_to_le32(phy_addr);
28562306a36Sopenharmony_ci		src_list[i].len = cpu_to_le32(len);
28662306a36Sopenharmony_ci	}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	if (total != 0) {
28962306a36Sopenharmony_ci		rc = -EINVAL;
29062306a36Sopenharmony_ci		goto free_req;
29162306a36Sopenharmony_ci	}
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	if (req->dst == req->src) {
29462306a36Sopenharmony_ci		dst_list = src_list;
29562306a36Sopenharmony_ci		dst_dma_addr = src_dma_addr;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	} else {
29862306a36Sopenharmony_ci		dst_list = (struct aspeed_sg_list *)crypto_engine->dst_sg_addr;
29962306a36Sopenharmony_ci		dst_dma_addr = crypto_engine->dst_sg_dma_addr;
30062306a36Sopenharmony_ci		total = req->cryptlen;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci		for_each_sg(req->dst, s, dst_sg_len, i) {
30362306a36Sopenharmony_ci			u32 phy_addr = sg_dma_address(s);
30462306a36Sopenharmony_ci			u32 len = sg_dma_len(s);
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci			if (total > len)
30762306a36Sopenharmony_ci				total -= len;
30862306a36Sopenharmony_ci			else {
30962306a36Sopenharmony_ci				/* last sg list */
31062306a36Sopenharmony_ci				len = total;
31162306a36Sopenharmony_ci				len |= BIT(31);
31262306a36Sopenharmony_ci				total = 0;
31362306a36Sopenharmony_ci			}
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci			dst_list[i].phy_addr = cpu_to_le32(phy_addr);
31662306a36Sopenharmony_ci			dst_list[i].len = cpu_to_le32(len);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci		}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci		dst_list[dst_sg_len].phy_addr = 0;
32162306a36Sopenharmony_ci		dst_list[dst_sg_len].len = 0;
32262306a36Sopenharmony_ci	}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	if (total != 0) {
32562306a36Sopenharmony_ci		rc = -EINVAL;
32662306a36Sopenharmony_ci		goto free_req;
32762306a36Sopenharmony_ci	}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	crypto_engine->resume = aspeed_sk_transfer_sg;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	/* Memory barrier to ensure all data setup before engine starts */
33262306a36Sopenharmony_ci	mb();
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	/* Trigger engines */
33562306a36Sopenharmony_ci	ast_hace_write(hace_dev, src_dma_addr, ASPEED_HACE_SRC);
33662306a36Sopenharmony_ci	ast_hace_write(hace_dev, dst_dma_addr, ASPEED_HACE_DEST);
33762306a36Sopenharmony_ci	ast_hace_write(hace_dev, req->cryptlen, ASPEED_HACE_DATA_LEN);
33862306a36Sopenharmony_ci	ast_hace_write(hace_dev, rctx->enc_cmd, ASPEED_HACE_CMD);
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	return -EINPROGRESS;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cifree_req:
34362306a36Sopenharmony_ci	if (req->dst == req->src) {
34462306a36Sopenharmony_ci		dma_unmap_sg(hace_dev->dev, req->src, rctx->src_nents,
34562306a36Sopenharmony_ci			     DMA_BIDIRECTIONAL);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	} else {
34862306a36Sopenharmony_ci		dma_unmap_sg(hace_dev->dev, req->dst, rctx->dst_nents,
34962306a36Sopenharmony_ci			     DMA_TO_DEVICE);
35062306a36Sopenharmony_ci		dma_unmap_sg(hace_dev->dev, req->src, rctx->src_nents,
35162306a36Sopenharmony_ci			     DMA_TO_DEVICE);
35262306a36Sopenharmony_ci	}
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	return rc;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cifree_req_src:
35762306a36Sopenharmony_ci	dma_unmap_sg(hace_dev->dev, req->src, rctx->src_nents, DMA_TO_DEVICE);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	return rc;
36062306a36Sopenharmony_ci}
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_cistatic int aspeed_hace_skcipher_trigger(struct aspeed_hace_dev *hace_dev)
36362306a36Sopenharmony_ci{
36462306a36Sopenharmony_ci	struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
36562306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx;
36662306a36Sopenharmony_ci	struct crypto_skcipher *cipher;
36762306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx;
36862306a36Sopenharmony_ci	struct skcipher_request *req;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "\n");
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	req = crypto_engine->req;
37362306a36Sopenharmony_ci	rctx = skcipher_request_ctx(req);
37462306a36Sopenharmony_ci	cipher = crypto_skcipher_reqtfm(req);
37562306a36Sopenharmony_ci	ctx = crypto_skcipher_ctx(cipher);
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	/* enable interrupt */
37862306a36Sopenharmony_ci	rctx->enc_cmd |= HACE_CMD_ISR_EN;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	rctx->dst_nents = sg_nents(req->dst);
38162306a36Sopenharmony_ci	rctx->src_nents = sg_nents(req->src);
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	ast_hace_write(hace_dev, crypto_engine->cipher_ctx_dma,
38462306a36Sopenharmony_ci		       ASPEED_HACE_CONTEXT);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	if (rctx->enc_cmd & HACE_CMD_IV_REQUIRE) {
38762306a36Sopenharmony_ci		if (rctx->enc_cmd & HACE_CMD_DES_SELECT)
38862306a36Sopenharmony_ci			memcpy(crypto_engine->cipher_ctx + DES_BLOCK_SIZE,
38962306a36Sopenharmony_ci			       req->iv, DES_BLOCK_SIZE);
39062306a36Sopenharmony_ci		else
39162306a36Sopenharmony_ci			memcpy(crypto_engine->cipher_ctx, req->iv,
39262306a36Sopenharmony_ci			       AES_BLOCK_SIZE);
39362306a36Sopenharmony_ci	}
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	if (hace_dev->version == AST2600_VERSION) {
39662306a36Sopenharmony_ci		memcpy(crypto_engine->cipher_ctx + 16, ctx->key, ctx->key_len);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci		return aspeed_sk_start_sg(hace_dev);
39962306a36Sopenharmony_ci	}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	memcpy(crypto_engine->cipher_ctx + 16, ctx->key, AES_MAX_KEYLENGTH);
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	return aspeed_sk_start(hace_dev);
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_cistatic int aspeed_des_crypt(struct skcipher_request *req, u32 cmd)
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx = skcipher_request_ctx(req);
40962306a36Sopenharmony_ci	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
41062306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
41162306a36Sopenharmony_ci	struct aspeed_hace_dev *hace_dev = ctx->hace_dev;
41262306a36Sopenharmony_ci	u32 crypto_alg = cmd & HACE_CMD_OP_MODE_MASK;
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "\n");
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	if (crypto_alg == HACE_CMD_CBC || crypto_alg == HACE_CMD_ECB) {
41762306a36Sopenharmony_ci		if (!IS_ALIGNED(req->cryptlen, DES_BLOCK_SIZE))
41862306a36Sopenharmony_ci			return -EINVAL;
41962306a36Sopenharmony_ci	}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	rctx->enc_cmd = cmd | HACE_CMD_DES_SELECT | HACE_CMD_RI_WO_DATA_ENABLE |
42262306a36Sopenharmony_ci			HACE_CMD_DES | HACE_CMD_CONTEXT_LOAD_ENABLE |
42362306a36Sopenharmony_ci			HACE_CMD_CONTEXT_SAVE_ENABLE;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	return aspeed_hace_crypto_handle_queue(hace_dev, req);
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic int aspeed_des_setkey(struct crypto_skcipher *cipher, const u8 *key,
42962306a36Sopenharmony_ci			     unsigned int keylen)
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
43262306a36Sopenharmony_ci	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
43362306a36Sopenharmony_ci	struct aspeed_hace_dev *hace_dev = ctx->hace_dev;
43462306a36Sopenharmony_ci	int rc;
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "keylen: %d bits\n", keylen);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	if (keylen != DES_KEY_SIZE && keylen != DES3_EDE_KEY_SIZE) {
43962306a36Sopenharmony_ci		dev_warn(hace_dev->dev, "invalid keylen: %d bits\n", keylen);
44062306a36Sopenharmony_ci		return -EINVAL;
44162306a36Sopenharmony_ci	}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	if (keylen == DES_KEY_SIZE) {
44462306a36Sopenharmony_ci		rc = crypto_des_verify_key(tfm, key);
44562306a36Sopenharmony_ci		if (rc)
44662306a36Sopenharmony_ci			return rc;
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	} else if (keylen == DES3_EDE_KEY_SIZE) {
44962306a36Sopenharmony_ci		rc = crypto_des3_ede_verify_key(tfm, key);
45062306a36Sopenharmony_ci		if (rc)
45162306a36Sopenharmony_ci			return rc;
45262306a36Sopenharmony_ci	}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	memcpy(ctx->key, key, keylen);
45562306a36Sopenharmony_ci	ctx->key_len = keylen;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	crypto_skcipher_clear_flags(ctx->fallback_tfm, CRYPTO_TFM_REQ_MASK);
45862306a36Sopenharmony_ci	crypto_skcipher_set_flags(ctx->fallback_tfm, cipher->base.crt_flags &
45962306a36Sopenharmony_ci				  CRYPTO_TFM_REQ_MASK);
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
46262306a36Sopenharmony_ci}
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_cistatic int aspeed_tdes_ctr_decrypt(struct skcipher_request *req)
46562306a36Sopenharmony_ci{
46662306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CTR |
46762306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
46862306a36Sopenharmony_ci}
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_cistatic int aspeed_tdes_ctr_encrypt(struct skcipher_request *req)
47162306a36Sopenharmony_ci{
47262306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CTR |
47362306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic int aspeed_tdes_ofb_decrypt(struct skcipher_request *req)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_OFB |
47962306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
48062306a36Sopenharmony_ci}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_cistatic int aspeed_tdes_ofb_encrypt(struct skcipher_request *req)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_OFB |
48562306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
48662306a36Sopenharmony_ci}
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_cistatic int aspeed_tdes_cfb_decrypt(struct skcipher_request *req)
48962306a36Sopenharmony_ci{
49062306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CFB |
49162306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
49262306a36Sopenharmony_ci}
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_cistatic int aspeed_tdes_cfb_encrypt(struct skcipher_request *req)
49562306a36Sopenharmony_ci{
49662306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CFB |
49762306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
49862306a36Sopenharmony_ci}
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_cistatic int aspeed_tdes_cbc_decrypt(struct skcipher_request *req)
50162306a36Sopenharmony_ci{
50262306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CBC |
50362306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
50462306a36Sopenharmony_ci}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_cistatic int aspeed_tdes_cbc_encrypt(struct skcipher_request *req)
50762306a36Sopenharmony_ci{
50862306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CBC |
50962306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_cistatic int aspeed_tdes_ecb_decrypt(struct skcipher_request *req)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_ECB |
51562306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
51662306a36Sopenharmony_ci}
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_cistatic int aspeed_tdes_ecb_encrypt(struct skcipher_request *req)
51962306a36Sopenharmony_ci{
52062306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_ECB |
52162306a36Sopenharmony_ci				HACE_CMD_TRIPLE_DES);
52262306a36Sopenharmony_ci}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_cistatic int aspeed_des_ctr_decrypt(struct skcipher_request *req)
52562306a36Sopenharmony_ci{
52662306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CTR |
52762306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
52862306a36Sopenharmony_ci}
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_cistatic int aspeed_des_ctr_encrypt(struct skcipher_request *req)
53162306a36Sopenharmony_ci{
53262306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CTR |
53362306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
53462306a36Sopenharmony_ci}
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_cistatic int aspeed_des_ofb_decrypt(struct skcipher_request *req)
53762306a36Sopenharmony_ci{
53862306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_OFB |
53962306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
54062306a36Sopenharmony_ci}
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_cistatic int aspeed_des_ofb_encrypt(struct skcipher_request *req)
54362306a36Sopenharmony_ci{
54462306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_OFB |
54562306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
54662306a36Sopenharmony_ci}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_cistatic int aspeed_des_cfb_decrypt(struct skcipher_request *req)
54962306a36Sopenharmony_ci{
55062306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CFB |
55162306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
55262306a36Sopenharmony_ci}
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_cistatic int aspeed_des_cfb_encrypt(struct skcipher_request *req)
55562306a36Sopenharmony_ci{
55662306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CFB |
55762306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
55862306a36Sopenharmony_ci}
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_cistatic int aspeed_des_cbc_decrypt(struct skcipher_request *req)
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CBC |
56362306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
56462306a36Sopenharmony_ci}
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_cistatic int aspeed_des_cbc_encrypt(struct skcipher_request *req)
56762306a36Sopenharmony_ci{
56862306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CBC |
56962306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
57062306a36Sopenharmony_ci}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_cistatic int aspeed_des_ecb_decrypt(struct skcipher_request *req)
57362306a36Sopenharmony_ci{
57462306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_ECB |
57562306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
57662306a36Sopenharmony_ci}
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_cistatic int aspeed_des_ecb_encrypt(struct skcipher_request *req)
57962306a36Sopenharmony_ci{
58062306a36Sopenharmony_ci	return aspeed_des_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_ECB |
58162306a36Sopenharmony_ci				HACE_CMD_SINGLE_DES);
58262306a36Sopenharmony_ci}
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_cistatic int aspeed_aes_crypt(struct skcipher_request *req, u32 cmd)
58562306a36Sopenharmony_ci{
58662306a36Sopenharmony_ci	struct aspeed_cipher_reqctx *rctx = skcipher_request_ctx(req);
58762306a36Sopenharmony_ci	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
58862306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
58962306a36Sopenharmony_ci	struct aspeed_hace_dev *hace_dev = ctx->hace_dev;
59062306a36Sopenharmony_ci	u32 crypto_alg = cmd & HACE_CMD_OP_MODE_MASK;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	if (crypto_alg == HACE_CMD_CBC || crypto_alg == HACE_CMD_ECB) {
59362306a36Sopenharmony_ci		if (!IS_ALIGNED(req->cryptlen, AES_BLOCK_SIZE))
59462306a36Sopenharmony_ci			return -EINVAL;
59562306a36Sopenharmony_ci	}
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "%s\n",
59862306a36Sopenharmony_ci		   (cmd & HACE_CMD_ENCRYPT) ? "encrypt" : "decrypt");
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci	cmd |= HACE_CMD_AES_SELECT | HACE_CMD_RI_WO_DATA_ENABLE |
60162306a36Sopenharmony_ci	       HACE_CMD_CONTEXT_LOAD_ENABLE | HACE_CMD_CONTEXT_SAVE_ENABLE;
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	switch (ctx->key_len) {
60462306a36Sopenharmony_ci	case AES_KEYSIZE_128:
60562306a36Sopenharmony_ci		cmd |= HACE_CMD_AES128;
60662306a36Sopenharmony_ci		break;
60762306a36Sopenharmony_ci	case AES_KEYSIZE_192:
60862306a36Sopenharmony_ci		cmd |= HACE_CMD_AES192;
60962306a36Sopenharmony_ci		break;
61062306a36Sopenharmony_ci	case AES_KEYSIZE_256:
61162306a36Sopenharmony_ci		cmd |= HACE_CMD_AES256;
61262306a36Sopenharmony_ci		break;
61362306a36Sopenharmony_ci	default:
61462306a36Sopenharmony_ci		return -EINVAL;
61562306a36Sopenharmony_ci	}
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	rctx->enc_cmd = cmd;
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	return aspeed_hace_crypto_handle_queue(hace_dev, req);
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_cistatic int aspeed_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
62362306a36Sopenharmony_ci			     unsigned int keylen)
62462306a36Sopenharmony_ci{
62562306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
62662306a36Sopenharmony_ci	struct aspeed_hace_dev *hace_dev = ctx->hace_dev;
62762306a36Sopenharmony_ci	struct crypto_aes_ctx gen_aes_key;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "keylen: %d bits\n", (keylen * 8));
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
63262306a36Sopenharmony_ci	    keylen != AES_KEYSIZE_256)
63362306a36Sopenharmony_ci		return -EINVAL;
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	if (ctx->hace_dev->version == AST2500_VERSION) {
63662306a36Sopenharmony_ci		aes_expandkey(&gen_aes_key, key, keylen);
63762306a36Sopenharmony_ci		memcpy(ctx->key, gen_aes_key.key_enc, AES_MAX_KEYLENGTH);
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	} else {
64062306a36Sopenharmony_ci		memcpy(ctx->key, key, keylen);
64162306a36Sopenharmony_ci	}
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	ctx->key_len = keylen;
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	crypto_skcipher_clear_flags(ctx->fallback_tfm, CRYPTO_TFM_REQ_MASK);
64662306a36Sopenharmony_ci	crypto_skcipher_set_flags(ctx->fallback_tfm, cipher->base.crt_flags &
64762306a36Sopenharmony_ci				  CRYPTO_TFM_REQ_MASK);
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
65062306a36Sopenharmony_ci}
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistatic int aspeed_aes_ctr_decrypt(struct skcipher_request *req)
65362306a36Sopenharmony_ci{
65462306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CTR);
65562306a36Sopenharmony_ci}
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_cistatic int aspeed_aes_ctr_encrypt(struct skcipher_request *req)
65862306a36Sopenharmony_ci{
65962306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CTR);
66062306a36Sopenharmony_ci}
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_cistatic int aspeed_aes_ofb_decrypt(struct skcipher_request *req)
66362306a36Sopenharmony_ci{
66462306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_OFB);
66562306a36Sopenharmony_ci}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_cistatic int aspeed_aes_ofb_encrypt(struct skcipher_request *req)
66862306a36Sopenharmony_ci{
66962306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_OFB);
67062306a36Sopenharmony_ci}
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_cistatic int aspeed_aes_cfb_decrypt(struct skcipher_request *req)
67362306a36Sopenharmony_ci{
67462306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CFB);
67562306a36Sopenharmony_ci}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_cistatic int aspeed_aes_cfb_encrypt(struct skcipher_request *req)
67862306a36Sopenharmony_ci{
67962306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CFB);
68062306a36Sopenharmony_ci}
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_cistatic int aspeed_aes_cbc_decrypt(struct skcipher_request *req)
68362306a36Sopenharmony_ci{
68462306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_CBC);
68562306a36Sopenharmony_ci}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_cistatic int aspeed_aes_cbc_encrypt(struct skcipher_request *req)
68862306a36Sopenharmony_ci{
68962306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_CBC);
69062306a36Sopenharmony_ci}
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_cistatic int aspeed_aes_ecb_decrypt(struct skcipher_request *req)
69362306a36Sopenharmony_ci{
69462306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_DECRYPT | HACE_CMD_ECB);
69562306a36Sopenharmony_ci}
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_cistatic int aspeed_aes_ecb_encrypt(struct skcipher_request *req)
69862306a36Sopenharmony_ci{
69962306a36Sopenharmony_ci	return aspeed_aes_crypt(req, HACE_CMD_ENCRYPT | HACE_CMD_ECB);
70062306a36Sopenharmony_ci}
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_cistatic int aspeed_crypto_cra_init(struct crypto_skcipher *tfm)
70362306a36Sopenharmony_ci{
70462306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
70562306a36Sopenharmony_ci	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
70662306a36Sopenharmony_ci	const char *name = crypto_tfm_alg_name(&tfm->base);
70762306a36Sopenharmony_ci	struct aspeed_hace_alg *crypto_alg;
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	crypto_alg = container_of(alg, struct aspeed_hace_alg, alg.skcipher.base);
71162306a36Sopenharmony_ci	ctx->hace_dev = crypto_alg->hace_dev;
71262306a36Sopenharmony_ci	ctx->start = aspeed_hace_skcipher_trigger;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	CIPHER_DBG(ctx->hace_dev, "%s\n", name);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_ASYNC |
71762306a36Sopenharmony_ci						  CRYPTO_ALG_NEED_FALLBACK);
71862306a36Sopenharmony_ci	if (IS_ERR(ctx->fallback_tfm)) {
71962306a36Sopenharmony_ci		dev_err(ctx->hace_dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
72062306a36Sopenharmony_ci			name, PTR_ERR(ctx->fallback_tfm));
72162306a36Sopenharmony_ci		return PTR_ERR(ctx->fallback_tfm);
72262306a36Sopenharmony_ci	}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	crypto_skcipher_set_reqsize(tfm, sizeof(struct aspeed_cipher_reqctx) +
72562306a36Sopenharmony_ci			 crypto_skcipher_reqsize(ctx->fallback_tfm));
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci	return 0;
72862306a36Sopenharmony_ci}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_cistatic void aspeed_crypto_cra_exit(struct crypto_skcipher *tfm)
73162306a36Sopenharmony_ci{
73262306a36Sopenharmony_ci	struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
73362306a36Sopenharmony_ci	struct aspeed_hace_dev *hace_dev = ctx->hace_dev;
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "%s\n", crypto_tfm_alg_name(&tfm->base));
73662306a36Sopenharmony_ci	crypto_free_skcipher(ctx->fallback_tfm);
73762306a36Sopenharmony_ci}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_cistatic struct aspeed_hace_alg aspeed_crypto_algs[] = {
74062306a36Sopenharmony_ci	{
74162306a36Sopenharmony_ci		.alg.skcipher.base = {
74262306a36Sopenharmony_ci			.min_keysize	= AES_MIN_KEY_SIZE,
74362306a36Sopenharmony_ci			.max_keysize	= AES_MAX_KEY_SIZE,
74462306a36Sopenharmony_ci			.setkey		= aspeed_aes_setkey,
74562306a36Sopenharmony_ci			.encrypt	= aspeed_aes_ecb_encrypt,
74662306a36Sopenharmony_ci			.decrypt	= aspeed_aes_ecb_decrypt,
74762306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
74862306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
74962306a36Sopenharmony_ci			.base = {
75062306a36Sopenharmony_ci				.cra_name		= "ecb(aes)",
75162306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ecb-aes",
75262306a36Sopenharmony_ci				.cra_priority		= 300,
75362306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
75462306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
75562306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
75662306a36Sopenharmony_ci				.cra_blocksize		= AES_BLOCK_SIZE,
75762306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
75862306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
75962306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
76062306a36Sopenharmony_ci			}
76162306a36Sopenharmony_ci		},
76262306a36Sopenharmony_ci		.alg.skcipher.op = {
76362306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
76462306a36Sopenharmony_ci		},
76562306a36Sopenharmony_ci	},
76662306a36Sopenharmony_ci	{
76762306a36Sopenharmony_ci		.alg.skcipher.base = {
76862306a36Sopenharmony_ci			.ivsize		= AES_BLOCK_SIZE,
76962306a36Sopenharmony_ci			.min_keysize	= AES_MIN_KEY_SIZE,
77062306a36Sopenharmony_ci			.max_keysize	= AES_MAX_KEY_SIZE,
77162306a36Sopenharmony_ci			.setkey		= aspeed_aes_setkey,
77262306a36Sopenharmony_ci			.encrypt	= aspeed_aes_cbc_encrypt,
77362306a36Sopenharmony_ci			.decrypt	= aspeed_aes_cbc_decrypt,
77462306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
77562306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
77662306a36Sopenharmony_ci			.base = {
77762306a36Sopenharmony_ci				.cra_name		= "cbc(aes)",
77862306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-cbc-aes",
77962306a36Sopenharmony_ci				.cra_priority		= 300,
78062306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
78162306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
78262306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
78362306a36Sopenharmony_ci				.cra_blocksize		= AES_BLOCK_SIZE,
78462306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
78562306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
78662306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
78762306a36Sopenharmony_ci			}
78862306a36Sopenharmony_ci		},
78962306a36Sopenharmony_ci		.alg.skcipher.op = {
79062306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
79162306a36Sopenharmony_ci		},
79262306a36Sopenharmony_ci	},
79362306a36Sopenharmony_ci	{
79462306a36Sopenharmony_ci		.alg.skcipher.base = {
79562306a36Sopenharmony_ci			.ivsize		= AES_BLOCK_SIZE,
79662306a36Sopenharmony_ci			.min_keysize	= AES_MIN_KEY_SIZE,
79762306a36Sopenharmony_ci			.max_keysize	= AES_MAX_KEY_SIZE,
79862306a36Sopenharmony_ci			.setkey		= aspeed_aes_setkey,
79962306a36Sopenharmony_ci			.encrypt	= aspeed_aes_cfb_encrypt,
80062306a36Sopenharmony_ci			.decrypt	= aspeed_aes_cfb_decrypt,
80162306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
80262306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
80362306a36Sopenharmony_ci			.base = {
80462306a36Sopenharmony_ci				.cra_name		= "cfb(aes)",
80562306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-cfb-aes",
80662306a36Sopenharmony_ci				.cra_priority		= 300,
80762306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
80862306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
80962306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
81062306a36Sopenharmony_ci				.cra_blocksize		= 1,
81162306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
81262306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
81362306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
81462306a36Sopenharmony_ci			}
81562306a36Sopenharmony_ci		},
81662306a36Sopenharmony_ci		.alg.skcipher.op = {
81762306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
81862306a36Sopenharmony_ci		},
81962306a36Sopenharmony_ci	},
82062306a36Sopenharmony_ci	{
82162306a36Sopenharmony_ci		.alg.skcipher.base = {
82262306a36Sopenharmony_ci			.ivsize		= AES_BLOCK_SIZE,
82362306a36Sopenharmony_ci			.min_keysize	= AES_MIN_KEY_SIZE,
82462306a36Sopenharmony_ci			.max_keysize	= AES_MAX_KEY_SIZE,
82562306a36Sopenharmony_ci			.setkey		= aspeed_aes_setkey,
82662306a36Sopenharmony_ci			.encrypt	= aspeed_aes_ofb_encrypt,
82762306a36Sopenharmony_ci			.decrypt	= aspeed_aes_ofb_decrypt,
82862306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
82962306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
83062306a36Sopenharmony_ci			.base = {
83162306a36Sopenharmony_ci				.cra_name		= "ofb(aes)",
83262306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ofb-aes",
83362306a36Sopenharmony_ci				.cra_priority		= 300,
83462306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
83562306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
83662306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
83762306a36Sopenharmony_ci				.cra_blocksize		= 1,
83862306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
83962306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
84062306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
84162306a36Sopenharmony_ci			}
84262306a36Sopenharmony_ci		},
84362306a36Sopenharmony_ci		.alg.skcipher.op = {
84462306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
84562306a36Sopenharmony_ci		},
84662306a36Sopenharmony_ci	},
84762306a36Sopenharmony_ci	{
84862306a36Sopenharmony_ci		.alg.skcipher.base = {
84962306a36Sopenharmony_ci			.min_keysize	= DES_KEY_SIZE,
85062306a36Sopenharmony_ci			.max_keysize	= DES_KEY_SIZE,
85162306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
85262306a36Sopenharmony_ci			.encrypt	= aspeed_des_ecb_encrypt,
85362306a36Sopenharmony_ci			.decrypt	= aspeed_des_ecb_decrypt,
85462306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
85562306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
85662306a36Sopenharmony_ci			.base = {
85762306a36Sopenharmony_ci				.cra_name		= "ecb(des)",
85862306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ecb-des",
85962306a36Sopenharmony_ci				.cra_priority		= 300,
86062306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
86162306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
86262306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
86362306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
86462306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
86562306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
86662306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
86762306a36Sopenharmony_ci			}
86862306a36Sopenharmony_ci		},
86962306a36Sopenharmony_ci		.alg.skcipher.op = {
87062306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
87162306a36Sopenharmony_ci		},
87262306a36Sopenharmony_ci	},
87362306a36Sopenharmony_ci	{
87462306a36Sopenharmony_ci		.alg.skcipher.base = {
87562306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
87662306a36Sopenharmony_ci			.min_keysize	= DES_KEY_SIZE,
87762306a36Sopenharmony_ci			.max_keysize	= DES_KEY_SIZE,
87862306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
87962306a36Sopenharmony_ci			.encrypt	= aspeed_des_cbc_encrypt,
88062306a36Sopenharmony_ci			.decrypt	= aspeed_des_cbc_decrypt,
88162306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
88262306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
88362306a36Sopenharmony_ci			.base = {
88462306a36Sopenharmony_ci				.cra_name		= "cbc(des)",
88562306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-cbc-des",
88662306a36Sopenharmony_ci				.cra_priority		= 300,
88762306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
88862306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
88962306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
89062306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
89162306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
89262306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
89362306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
89462306a36Sopenharmony_ci			}
89562306a36Sopenharmony_ci		},
89662306a36Sopenharmony_ci		.alg.skcipher.op = {
89762306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
89862306a36Sopenharmony_ci		},
89962306a36Sopenharmony_ci	},
90062306a36Sopenharmony_ci	{
90162306a36Sopenharmony_ci		.alg.skcipher.base = {
90262306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
90362306a36Sopenharmony_ci			.min_keysize	= DES_KEY_SIZE,
90462306a36Sopenharmony_ci			.max_keysize	= DES_KEY_SIZE,
90562306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
90662306a36Sopenharmony_ci			.encrypt	= aspeed_des_cfb_encrypt,
90762306a36Sopenharmony_ci			.decrypt	= aspeed_des_cfb_decrypt,
90862306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
90962306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
91062306a36Sopenharmony_ci			.base = {
91162306a36Sopenharmony_ci				.cra_name		= "cfb(des)",
91262306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-cfb-des",
91362306a36Sopenharmony_ci				.cra_priority		= 300,
91462306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
91562306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
91662306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
91762306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
91862306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
91962306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
92062306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
92162306a36Sopenharmony_ci			}
92262306a36Sopenharmony_ci		},
92362306a36Sopenharmony_ci		.alg.skcipher.op = {
92462306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
92562306a36Sopenharmony_ci		},
92662306a36Sopenharmony_ci	},
92762306a36Sopenharmony_ci	{
92862306a36Sopenharmony_ci		.alg.skcipher.base = {
92962306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
93062306a36Sopenharmony_ci			.min_keysize	= DES_KEY_SIZE,
93162306a36Sopenharmony_ci			.max_keysize	= DES_KEY_SIZE,
93262306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
93362306a36Sopenharmony_ci			.encrypt	= aspeed_des_ofb_encrypt,
93462306a36Sopenharmony_ci			.decrypt	= aspeed_des_ofb_decrypt,
93562306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
93662306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
93762306a36Sopenharmony_ci			.base = {
93862306a36Sopenharmony_ci				.cra_name		= "ofb(des)",
93962306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ofb-des",
94062306a36Sopenharmony_ci				.cra_priority		= 300,
94162306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
94262306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
94362306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
94462306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
94562306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
94662306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
94762306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
94862306a36Sopenharmony_ci			}
94962306a36Sopenharmony_ci		},
95062306a36Sopenharmony_ci		.alg.skcipher.op = {
95162306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
95262306a36Sopenharmony_ci		},
95362306a36Sopenharmony_ci	},
95462306a36Sopenharmony_ci	{
95562306a36Sopenharmony_ci		.alg.skcipher.base = {
95662306a36Sopenharmony_ci			.min_keysize	= DES3_EDE_KEY_SIZE,
95762306a36Sopenharmony_ci			.max_keysize	= DES3_EDE_KEY_SIZE,
95862306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
95962306a36Sopenharmony_ci			.encrypt	= aspeed_tdes_ecb_encrypt,
96062306a36Sopenharmony_ci			.decrypt	= aspeed_tdes_ecb_decrypt,
96162306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
96262306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
96362306a36Sopenharmony_ci			.base = {
96462306a36Sopenharmony_ci				.cra_name		= "ecb(des3_ede)",
96562306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ecb-tdes",
96662306a36Sopenharmony_ci				.cra_priority		= 300,
96762306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
96862306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
96962306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
97062306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
97162306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
97262306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
97362306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
97462306a36Sopenharmony_ci			}
97562306a36Sopenharmony_ci		},
97662306a36Sopenharmony_ci		.alg.skcipher.op = {
97762306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
97862306a36Sopenharmony_ci		},
97962306a36Sopenharmony_ci	},
98062306a36Sopenharmony_ci	{
98162306a36Sopenharmony_ci		.alg.skcipher.base = {
98262306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
98362306a36Sopenharmony_ci			.min_keysize	= DES3_EDE_KEY_SIZE,
98462306a36Sopenharmony_ci			.max_keysize	= DES3_EDE_KEY_SIZE,
98562306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
98662306a36Sopenharmony_ci			.encrypt	= aspeed_tdes_cbc_encrypt,
98762306a36Sopenharmony_ci			.decrypt	= aspeed_tdes_cbc_decrypt,
98862306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
98962306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
99062306a36Sopenharmony_ci			.base = {
99162306a36Sopenharmony_ci				.cra_name		= "cbc(des3_ede)",
99262306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-cbc-tdes",
99362306a36Sopenharmony_ci				.cra_priority		= 300,
99462306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
99562306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
99662306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
99762306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
99862306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
99962306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
100062306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
100162306a36Sopenharmony_ci			}
100262306a36Sopenharmony_ci		},
100362306a36Sopenharmony_ci		.alg.skcipher.op = {
100462306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
100562306a36Sopenharmony_ci		},
100662306a36Sopenharmony_ci	},
100762306a36Sopenharmony_ci	{
100862306a36Sopenharmony_ci		.alg.skcipher.base = {
100962306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
101062306a36Sopenharmony_ci			.min_keysize	= DES3_EDE_KEY_SIZE,
101162306a36Sopenharmony_ci			.max_keysize	= DES3_EDE_KEY_SIZE,
101262306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
101362306a36Sopenharmony_ci			.encrypt	= aspeed_tdes_cfb_encrypt,
101462306a36Sopenharmony_ci			.decrypt	= aspeed_tdes_cfb_decrypt,
101562306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
101662306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
101762306a36Sopenharmony_ci			.base = {
101862306a36Sopenharmony_ci				.cra_name		= "cfb(des3_ede)",
101962306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-cfb-tdes",
102062306a36Sopenharmony_ci				.cra_priority		= 300,
102162306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
102262306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
102362306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
102462306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
102562306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
102662306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
102762306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
102862306a36Sopenharmony_ci			}
102962306a36Sopenharmony_ci		},
103062306a36Sopenharmony_ci		.alg.skcipher.op = {
103162306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
103262306a36Sopenharmony_ci		},
103362306a36Sopenharmony_ci	},
103462306a36Sopenharmony_ci	{
103562306a36Sopenharmony_ci		.alg.skcipher.base = {
103662306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
103762306a36Sopenharmony_ci			.min_keysize	= DES3_EDE_KEY_SIZE,
103862306a36Sopenharmony_ci			.max_keysize	= DES3_EDE_KEY_SIZE,
103962306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
104062306a36Sopenharmony_ci			.encrypt	= aspeed_tdes_ofb_encrypt,
104162306a36Sopenharmony_ci			.decrypt	= aspeed_tdes_ofb_decrypt,
104262306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
104362306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
104462306a36Sopenharmony_ci			.base = {
104562306a36Sopenharmony_ci				.cra_name		= "ofb(des3_ede)",
104662306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ofb-tdes",
104762306a36Sopenharmony_ci				.cra_priority		= 300,
104862306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
104962306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC |
105062306a36Sopenharmony_ci							  CRYPTO_ALG_NEED_FALLBACK,
105162306a36Sopenharmony_ci				.cra_blocksize		= DES_BLOCK_SIZE,
105262306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
105362306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
105462306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
105562306a36Sopenharmony_ci			}
105662306a36Sopenharmony_ci		},
105762306a36Sopenharmony_ci		.alg.skcipher.op = {
105862306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
105962306a36Sopenharmony_ci		},
106062306a36Sopenharmony_ci	},
106162306a36Sopenharmony_ci};
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_cistatic struct aspeed_hace_alg aspeed_crypto_algs_g6[] = {
106462306a36Sopenharmony_ci	{
106562306a36Sopenharmony_ci		.alg.skcipher.base = {
106662306a36Sopenharmony_ci			.ivsize		= AES_BLOCK_SIZE,
106762306a36Sopenharmony_ci			.min_keysize	= AES_MIN_KEY_SIZE,
106862306a36Sopenharmony_ci			.max_keysize	= AES_MAX_KEY_SIZE,
106962306a36Sopenharmony_ci			.setkey		= aspeed_aes_setkey,
107062306a36Sopenharmony_ci			.encrypt	= aspeed_aes_ctr_encrypt,
107162306a36Sopenharmony_ci			.decrypt	= aspeed_aes_ctr_decrypt,
107262306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
107362306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
107462306a36Sopenharmony_ci			.base = {
107562306a36Sopenharmony_ci				.cra_name		= "ctr(aes)",
107662306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ctr-aes",
107762306a36Sopenharmony_ci				.cra_priority		= 300,
107862306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
107962306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC,
108062306a36Sopenharmony_ci				.cra_blocksize		= 1,
108162306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
108262306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
108362306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
108462306a36Sopenharmony_ci			}
108562306a36Sopenharmony_ci		},
108662306a36Sopenharmony_ci		.alg.skcipher.op = {
108762306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
108862306a36Sopenharmony_ci		},
108962306a36Sopenharmony_ci	},
109062306a36Sopenharmony_ci	{
109162306a36Sopenharmony_ci		.alg.skcipher.base = {
109262306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
109362306a36Sopenharmony_ci			.min_keysize	= DES_KEY_SIZE,
109462306a36Sopenharmony_ci			.max_keysize	= DES_KEY_SIZE,
109562306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
109662306a36Sopenharmony_ci			.encrypt	= aspeed_des_ctr_encrypt,
109762306a36Sopenharmony_ci			.decrypt	= aspeed_des_ctr_decrypt,
109862306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
109962306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
110062306a36Sopenharmony_ci			.base = {
110162306a36Sopenharmony_ci				.cra_name		= "ctr(des)",
110262306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ctr-des",
110362306a36Sopenharmony_ci				.cra_priority		= 300,
110462306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
110562306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC,
110662306a36Sopenharmony_ci				.cra_blocksize		= 1,
110762306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
110862306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
110962306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
111062306a36Sopenharmony_ci			}
111162306a36Sopenharmony_ci		},
111262306a36Sopenharmony_ci		.alg.skcipher.op = {
111362306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
111462306a36Sopenharmony_ci		},
111562306a36Sopenharmony_ci	},
111662306a36Sopenharmony_ci	{
111762306a36Sopenharmony_ci		.alg.skcipher.base = {
111862306a36Sopenharmony_ci			.ivsize		= DES_BLOCK_SIZE,
111962306a36Sopenharmony_ci			.min_keysize	= DES3_EDE_KEY_SIZE,
112062306a36Sopenharmony_ci			.max_keysize	= DES3_EDE_KEY_SIZE,
112162306a36Sopenharmony_ci			.setkey		= aspeed_des_setkey,
112262306a36Sopenharmony_ci			.encrypt	= aspeed_tdes_ctr_encrypt,
112362306a36Sopenharmony_ci			.decrypt	= aspeed_tdes_ctr_decrypt,
112462306a36Sopenharmony_ci			.init		= aspeed_crypto_cra_init,
112562306a36Sopenharmony_ci			.exit		= aspeed_crypto_cra_exit,
112662306a36Sopenharmony_ci			.base = {
112762306a36Sopenharmony_ci				.cra_name		= "ctr(des3_ede)",
112862306a36Sopenharmony_ci				.cra_driver_name	= "aspeed-ctr-tdes",
112962306a36Sopenharmony_ci				.cra_priority		= 300,
113062306a36Sopenharmony_ci				.cra_flags		= CRYPTO_ALG_KERN_DRIVER_ONLY |
113162306a36Sopenharmony_ci							  CRYPTO_ALG_ASYNC,
113262306a36Sopenharmony_ci				.cra_blocksize		= 1,
113362306a36Sopenharmony_ci				.cra_ctxsize		= sizeof(struct aspeed_cipher_ctx),
113462306a36Sopenharmony_ci				.cra_alignmask		= 0x0f,
113562306a36Sopenharmony_ci				.cra_module		= THIS_MODULE,
113662306a36Sopenharmony_ci			}
113762306a36Sopenharmony_ci		},
113862306a36Sopenharmony_ci		.alg.skcipher.op = {
113962306a36Sopenharmony_ci			.do_one_request = aspeed_crypto_do_request,
114062306a36Sopenharmony_ci		},
114162306a36Sopenharmony_ci	},
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci};
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_civoid aspeed_unregister_hace_crypto_algs(struct aspeed_hace_dev *hace_dev)
114662306a36Sopenharmony_ci{
114762306a36Sopenharmony_ci	int i;
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(aspeed_crypto_algs); i++)
115062306a36Sopenharmony_ci		crypto_engine_unregister_skcipher(&aspeed_crypto_algs[i].alg.skcipher);
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	if (hace_dev->version != AST2600_VERSION)
115362306a36Sopenharmony_ci		return;
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(aspeed_crypto_algs_g6); i++)
115662306a36Sopenharmony_ci		crypto_engine_unregister_skcipher(&aspeed_crypto_algs_g6[i].alg.skcipher);
115762306a36Sopenharmony_ci}
115862306a36Sopenharmony_ci
115962306a36Sopenharmony_civoid aspeed_register_hace_crypto_algs(struct aspeed_hace_dev *hace_dev)
116062306a36Sopenharmony_ci{
116162306a36Sopenharmony_ci	int rc, i;
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci	CIPHER_DBG(hace_dev, "\n");
116462306a36Sopenharmony_ci
116562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(aspeed_crypto_algs); i++) {
116662306a36Sopenharmony_ci		aspeed_crypto_algs[i].hace_dev = hace_dev;
116762306a36Sopenharmony_ci		rc = crypto_engine_register_skcipher(&aspeed_crypto_algs[i].alg.skcipher);
116862306a36Sopenharmony_ci		if (rc) {
116962306a36Sopenharmony_ci			CIPHER_DBG(hace_dev, "Failed to register %s\n",
117062306a36Sopenharmony_ci				   aspeed_crypto_algs[i].alg.skcipher.base.base.cra_name);
117162306a36Sopenharmony_ci		}
117262306a36Sopenharmony_ci	}
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	if (hace_dev->version != AST2600_VERSION)
117562306a36Sopenharmony_ci		return;
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(aspeed_crypto_algs_g6); i++) {
117862306a36Sopenharmony_ci		aspeed_crypto_algs_g6[i].hace_dev = hace_dev;
117962306a36Sopenharmony_ci		rc = crypto_engine_register_skcipher(&aspeed_crypto_algs_g6[i].alg.skcipher);
118062306a36Sopenharmony_ci		if (rc) {
118162306a36Sopenharmony_ci			CIPHER_DBG(hace_dev, "Failed to register %s\n",
118262306a36Sopenharmony_ci				   aspeed_crypto_algs_g6[i].alg.skcipher.base.base.cra_name);
118362306a36Sopenharmony_ci		}
118462306a36Sopenharmony_ci	}
118562306a36Sopenharmony_ci}
1186