162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __MARVELL_CESA_H__
362306a36Sopenharmony_ci#define __MARVELL_CESA_H__
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <crypto/internal/hash.h>
662306a36Sopenharmony_ci#include <crypto/internal/skcipher.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/dma-direction.h>
962306a36Sopenharmony_ci#include <linux/dmapool.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define CESA_ENGINE_OFF(i)			(((i) * 0x2000))
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define CESA_TDMA_BYTE_CNT			0x800
1462306a36Sopenharmony_ci#define CESA_TDMA_SRC_ADDR			0x810
1562306a36Sopenharmony_ci#define CESA_TDMA_DST_ADDR			0x820
1662306a36Sopenharmony_ci#define CESA_TDMA_NEXT_ADDR			0x830
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define CESA_TDMA_CONTROL			0x840
1962306a36Sopenharmony_ci#define CESA_TDMA_DST_BURST			GENMASK(2, 0)
2062306a36Sopenharmony_ci#define CESA_TDMA_DST_BURST_32B			3
2162306a36Sopenharmony_ci#define CESA_TDMA_DST_BURST_128B		4
2262306a36Sopenharmony_ci#define CESA_TDMA_OUT_RD_EN			BIT(4)
2362306a36Sopenharmony_ci#define CESA_TDMA_SRC_BURST			GENMASK(8, 6)
2462306a36Sopenharmony_ci#define CESA_TDMA_SRC_BURST_32B			(3 << 6)
2562306a36Sopenharmony_ci#define CESA_TDMA_SRC_BURST_128B		(4 << 6)
2662306a36Sopenharmony_ci#define CESA_TDMA_CHAIN				BIT(9)
2762306a36Sopenharmony_ci#define CESA_TDMA_BYTE_SWAP			BIT(11)
2862306a36Sopenharmony_ci#define CESA_TDMA_NO_BYTE_SWAP			BIT(11)
2962306a36Sopenharmony_ci#define CESA_TDMA_EN				BIT(12)
3062306a36Sopenharmony_ci#define CESA_TDMA_FETCH_ND			BIT(13)
3162306a36Sopenharmony_ci#define CESA_TDMA_ACT				BIT(14)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define CESA_TDMA_CUR				0x870
3462306a36Sopenharmony_ci#define CESA_TDMA_ERROR_CAUSE			0x8c8
3562306a36Sopenharmony_ci#define CESA_TDMA_ERROR_MSK			0x8cc
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define CESA_TDMA_WINDOW_BASE(x)		(((x) * 0x8) + 0xa00)
3862306a36Sopenharmony_ci#define CESA_TDMA_WINDOW_CTRL(x)		(((x) * 0x8) + 0xa04)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#define CESA_IVDIG(x)				(0xdd00 + ((x) * 4) +	\
4162306a36Sopenharmony_ci						 (((x) < 5) ? 0 : 0x14))
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define CESA_SA_CMD				0xde00
4462306a36Sopenharmony_ci#define CESA_SA_CMD_EN_CESA_SA_ACCL0		BIT(0)
4562306a36Sopenharmony_ci#define CESA_SA_CMD_EN_CESA_SA_ACCL1		BIT(1)
4662306a36Sopenharmony_ci#define CESA_SA_CMD_DISABLE_SEC			BIT(2)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define CESA_SA_DESC_P0				0xde04
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define CESA_SA_DESC_P1				0xde14
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define CESA_SA_CFG				0xde08
5362306a36Sopenharmony_ci#define CESA_SA_CFG_STOP_DIG_ERR		GENMASK(1, 0)
5462306a36Sopenharmony_ci#define CESA_SA_CFG_DIG_ERR_CONT		0
5562306a36Sopenharmony_ci#define CESA_SA_CFG_DIG_ERR_SKIP		1
5662306a36Sopenharmony_ci#define CESA_SA_CFG_DIG_ERR_STOP		3
5762306a36Sopenharmony_ci#define CESA_SA_CFG_CH0_W_IDMA			BIT(7)
5862306a36Sopenharmony_ci#define CESA_SA_CFG_CH1_W_IDMA			BIT(8)
5962306a36Sopenharmony_ci#define CESA_SA_CFG_ACT_CH0_IDMA		BIT(9)
6062306a36Sopenharmony_ci#define CESA_SA_CFG_ACT_CH1_IDMA		BIT(10)
6162306a36Sopenharmony_ci#define CESA_SA_CFG_MULTI_PKT			BIT(11)
6262306a36Sopenharmony_ci#define CESA_SA_CFG_PARA_DIS			BIT(13)
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#define CESA_SA_ACCEL_STATUS			0xde0c
6562306a36Sopenharmony_ci#define CESA_SA_ST_ACT_0			BIT(0)
6662306a36Sopenharmony_ci#define CESA_SA_ST_ACT_1			BIT(1)
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/*
6962306a36Sopenharmony_ci * CESA_SA_FPGA_INT_STATUS looks like an FPGA leftover and is documented only
7062306a36Sopenharmony_ci * in Errata 4.12. It looks like that it was part of an IRQ-controller in FPGA
7162306a36Sopenharmony_ci * and someone forgot to remove  it while switching to the core and moving to
7262306a36Sopenharmony_ci * CESA_SA_INT_STATUS.
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_ci#define CESA_SA_FPGA_INT_STATUS			0xdd68
7562306a36Sopenharmony_ci#define CESA_SA_INT_STATUS			0xde20
7662306a36Sopenharmony_ci#define CESA_SA_INT_AUTH_DONE			BIT(0)
7762306a36Sopenharmony_ci#define CESA_SA_INT_DES_E_DONE			BIT(1)
7862306a36Sopenharmony_ci#define CESA_SA_INT_AES_E_DONE			BIT(2)
7962306a36Sopenharmony_ci#define CESA_SA_INT_AES_D_DONE			BIT(3)
8062306a36Sopenharmony_ci#define CESA_SA_INT_ENC_DONE			BIT(4)
8162306a36Sopenharmony_ci#define CESA_SA_INT_ACCEL0_DONE			BIT(5)
8262306a36Sopenharmony_ci#define CESA_SA_INT_ACCEL1_DONE			BIT(6)
8362306a36Sopenharmony_ci#define CESA_SA_INT_ACC0_IDMA_DONE		BIT(7)
8462306a36Sopenharmony_ci#define CESA_SA_INT_ACC1_IDMA_DONE		BIT(8)
8562306a36Sopenharmony_ci#define CESA_SA_INT_IDMA_DONE			BIT(9)
8662306a36Sopenharmony_ci#define CESA_SA_INT_IDMA_OWN_ERR		BIT(10)
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define CESA_SA_INT_MSK				0xde24
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_OP_MAC_ONLY		0
9162306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_OP_CRYPT_ONLY		1
9262306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_OP_MAC_CRYPT		2
9362306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_OP_CRYPT_MAC		3
9462306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_OP_MSK			GENMASK(1, 0)
9562306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_SHA256		(1 << 4)
9662306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_HMAC_SHA256	(3 << 4)
9762306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_MD5		(4 << 4)
9862306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_SHA1		(5 << 4)
9962306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_HMAC_MD5		(6 << 4)
10062306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_HMAC_SHA1		(7 << 4)
10162306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MACM_MSK		GENMASK(6, 4)
10262306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTM_DES		(1 << 8)
10362306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTM_3DES		(2 << 8)
10462306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTM_AES		(3 << 8)
10562306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTM_MSK		GENMASK(9, 8)
10662306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_DIR_ENC		(0 << 12)
10762306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_DIR_DEC		(1 << 12)
10862306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTCM_ECB		(0 << 16)
10962306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTCM_CBC		(1 << 16)
11062306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_CRYPTCM_MSK		BIT(16)
11162306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_3DES_EEE		(0 << 20)
11262306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_3DES_EDE		(1 << 20)
11362306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_AES_LEN_128		(0 << 24)
11462306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_AES_LEN_192		(1 << 24)
11562306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_AES_LEN_256		(2 << 24)
11662306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_AES_LEN_MSK		GENMASK(25, 24)
11762306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_NOT_FRAG		(0 << 30)
11862306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_FIRST_FRAG		(1 << 30)
11962306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_LAST_FRAG		(2 << 30)
12062306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_MID_FRAG		(3 << 30)
12162306a36Sopenharmony_ci#define CESA_SA_DESC_CFG_FRAG_MSK		GENMASK(31, 30)
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/*
12462306a36Sopenharmony_ci * /-----------\ 0
12562306a36Sopenharmony_ci * | ACCEL CFG |	4 * 8
12662306a36Sopenharmony_ci * |-----------| 0x20
12762306a36Sopenharmony_ci * | CRYPT KEY |	8 * 4
12862306a36Sopenharmony_ci * |-----------| 0x40
12962306a36Sopenharmony_ci * |  IV   IN  |	4 * 4
13062306a36Sopenharmony_ci * |-----------| 0x40 (inplace)
13162306a36Sopenharmony_ci * |  IV BUF   |	4 * 4
13262306a36Sopenharmony_ci * |-----------| 0x80
13362306a36Sopenharmony_ci * |  DATA IN  |	16 * x (max ->max_req_size)
13462306a36Sopenharmony_ci * |-----------| 0x80 (inplace operation)
13562306a36Sopenharmony_ci * |  DATA OUT |	16 * x (max ->max_req_size)
13662306a36Sopenharmony_ci * \-----------/ SRAM size
13762306a36Sopenharmony_ci */
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/*
14062306a36Sopenharmony_ci * Hashing memory map:
14162306a36Sopenharmony_ci * /-----------\ 0
14262306a36Sopenharmony_ci * | ACCEL CFG |        4 * 8
14362306a36Sopenharmony_ci * |-----------| 0x20
14462306a36Sopenharmony_ci * | Inner IV  |        8 * 4
14562306a36Sopenharmony_ci * |-----------| 0x40
14662306a36Sopenharmony_ci * | Outer IV  |        8 * 4
14762306a36Sopenharmony_ci * |-----------| 0x60
14862306a36Sopenharmony_ci * | Output BUF|        8 * 4
14962306a36Sopenharmony_ci * |-----------| 0x80
15062306a36Sopenharmony_ci * |  DATA IN  |        64 * x (max ->max_req_size)
15162306a36Sopenharmony_ci * \-----------/ SRAM size
15262306a36Sopenharmony_ci */
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci#define CESA_SA_CFG_SRAM_OFFSET			0x00
15562306a36Sopenharmony_ci#define CESA_SA_DATA_SRAM_OFFSET		0x80
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci#define CESA_SA_CRYPT_KEY_SRAM_OFFSET		0x20
15862306a36Sopenharmony_ci#define CESA_SA_CRYPT_IV_SRAM_OFFSET		0x40
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#define CESA_SA_MAC_IIV_SRAM_OFFSET		0x20
16162306a36Sopenharmony_ci#define CESA_SA_MAC_OIV_SRAM_OFFSET		0x40
16262306a36Sopenharmony_ci#define CESA_SA_MAC_DIG_SRAM_OFFSET		0x60
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#define CESA_SA_DESC_CRYPT_DATA(offset)					\
16562306a36Sopenharmony_ci	cpu_to_le32((CESA_SA_DATA_SRAM_OFFSET + (offset)) |		\
16662306a36Sopenharmony_ci		    ((CESA_SA_DATA_SRAM_OFFSET + (offset)) << 16))
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci#define CESA_SA_DESC_CRYPT_IV(offset)					\
16962306a36Sopenharmony_ci	cpu_to_le32((CESA_SA_CRYPT_IV_SRAM_OFFSET + (offset)) |	\
17062306a36Sopenharmony_ci		    ((CESA_SA_CRYPT_IV_SRAM_OFFSET + (offset)) << 16))
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci#define CESA_SA_DESC_CRYPT_KEY(offset)					\
17362306a36Sopenharmony_ci	cpu_to_le32(CESA_SA_CRYPT_KEY_SRAM_OFFSET + (offset))
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_DATA(offset)					\
17662306a36Sopenharmony_ci	cpu_to_le32(CESA_SA_DATA_SRAM_OFFSET + (offset))
17762306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_DATA_MSK		cpu_to_le32(GENMASK(15, 0))
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_TOTAL_LEN(total_len)	cpu_to_le32((total_len) << 16)
18062306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_TOTAL_LEN_MSK		cpu_to_le32(GENMASK(31, 16))
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_SRC_TOTAL_LEN_MAX	0xffff
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_DIGEST(offset)					\
18562306a36Sopenharmony_ci	cpu_to_le32(CESA_SA_MAC_DIG_SRAM_OFFSET + (offset))
18662306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_DIGEST_MSK		cpu_to_le32(GENMASK(15, 0))
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_FRAG_LEN(frag_len)	cpu_to_le32((frag_len) << 16)
18962306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_FRAG_LEN_MSK		cpu_to_le32(GENMASK(31, 16))
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci#define CESA_SA_DESC_MAC_IV(offset)					\
19262306a36Sopenharmony_ci	cpu_to_le32((CESA_SA_MAC_IIV_SRAM_OFFSET + (offset)) |		\
19362306a36Sopenharmony_ci		    ((CESA_SA_MAC_OIV_SRAM_OFFSET + (offset)) << 16))
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#define CESA_SA_SRAM_SIZE			2048
19662306a36Sopenharmony_ci#define CESA_SA_SRAM_PAYLOAD_SIZE		(cesa_dev->sram_size - \
19762306a36Sopenharmony_ci						 CESA_SA_DATA_SRAM_OFFSET)
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci#define CESA_SA_DEFAULT_SRAM_SIZE		2048
20062306a36Sopenharmony_ci#define CESA_SA_MIN_SRAM_SIZE			1024
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci#define CESA_SA_SRAM_MSK			(2048 - 1)
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci#define CESA_MAX_HASH_BLOCK_SIZE		64
20562306a36Sopenharmony_ci#define CESA_HASH_BLOCK_SIZE_MSK		(CESA_MAX_HASH_BLOCK_SIZE - 1)
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci/**
20862306a36Sopenharmony_ci * struct mv_cesa_sec_accel_desc - security accelerator descriptor
20962306a36Sopenharmony_ci * @config:	engine config
21062306a36Sopenharmony_ci * @enc_p:	input and output data pointers for a cipher operation
21162306a36Sopenharmony_ci * @enc_len:	cipher operation length
21262306a36Sopenharmony_ci * @enc_key_p:	cipher key pointer
21362306a36Sopenharmony_ci * @enc_iv:	cipher IV pointers
21462306a36Sopenharmony_ci * @mac_src_p:	input pointer and total hash length
21562306a36Sopenharmony_ci * @mac_digest:	digest pointer and hash operation length
21662306a36Sopenharmony_ci * @mac_iv:	hmac IV pointers
21762306a36Sopenharmony_ci *
21862306a36Sopenharmony_ci * Structure passed to the CESA engine to describe the crypto operation
21962306a36Sopenharmony_ci * to be executed.
22062306a36Sopenharmony_ci */
22162306a36Sopenharmony_cistruct mv_cesa_sec_accel_desc {
22262306a36Sopenharmony_ci	__le32 config;
22362306a36Sopenharmony_ci	__le32 enc_p;
22462306a36Sopenharmony_ci	__le32 enc_len;
22562306a36Sopenharmony_ci	__le32 enc_key_p;
22662306a36Sopenharmony_ci	__le32 enc_iv;
22762306a36Sopenharmony_ci	__le32 mac_src_p;
22862306a36Sopenharmony_ci	__le32 mac_digest;
22962306a36Sopenharmony_ci	__le32 mac_iv;
23062306a36Sopenharmony_ci};
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci/**
23362306a36Sopenharmony_ci * struct mv_cesa_skcipher_op_ctx - cipher operation context
23462306a36Sopenharmony_ci * @key:	cipher key
23562306a36Sopenharmony_ci * @iv:		cipher IV
23662306a36Sopenharmony_ci *
23762306a36Sopenharmony_ci * Context associated to a cipher operation.
23862306a36Sopenharmony_ci */
23962306a36Sopenharmony_cistruct mv_cesa_skcipher_op_ctx {
24062306a36Sopenharmony_ci	__le32 key[8];
24162306a36Sopenharmony_ci	u32 iv[4];
24262306a36Sopenharmony_ci};
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci/**
24562306a36Sopenharmony_ci * struct mv_cesa_hash_op_ctx - hash or hmac operation context
24662306a36Sopenharmony_ci * @key:	cipher key
24762306a36Sopenharmony_ci * @iv:		cipher IV
24862306a36Sopenharmony_ci *
24962306a36Sopenharmony_ci * Context associated to an hash or hmac operation.
25062306a36Sopenharmony_ci */
25162306a36Sopenharmony_cistruct mv_cesa_hash_op_ctx {
25262306a36Sopenharmony_ci	u32 iv[16];
25362306a36Sopenharmony_ci	__le32 hash[8];
25462306a36Sopenharmony_ci};
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci/**
25762306a36Sopenharmony_ci * struct mv_cesa_op_ctx - crypto operation context
25862306a36Sopenharmony_ci * @desc:	CESA descriptor
25962306a36Sopenharmony_ci * @ctx:	context associated to the crypto operation
26062306a36Sopenharmony_ci *
26162306a36Sopenharmony_ci * Context associated to a crypto operation.
26262306a36Sopenharmony_ci */
26362306a36Sopenharmony_cistruct mv_cesa_op_ctx {
26462306a36Sopenharmony_ci	struct mv_cesa_sec_accel_desc desc;
26562306a36Sopenharmony_ci	union {
26662306a36Sopenharmony_ci		struct mv_cesa_skcipher_op_ctx skcipher;
26762306a36Sopenharmony_ci		struct mv_cesa_hash_op_ctx hash;
26862306a36Sopenharmony_ci	} ctx;
26962306a36Sopenharmony_ci};
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci/* TDMA descriptor flags */
27262306a36Sopenharmony_ci#define CESA_TDMA_DST_IN_SRAM			BIT(31)
27362306a36Sopenharmony_ci#define CESA_TDMA_SRC_IN_SRAM			BIT(30)
27462306a36Sopenharmony_ci#define CESA_TDMA_END_OF_REQ			BIT(29)
27562306a36Sopenharmony_ci#define CESA_TDMA_BREAK_CHAIN			BIT(28)
27662306a36Sopenharmony_ci#define CESA_TDMA_SET_STATE			BIT(27)
27762306a36Sopenharmony_ci#define CESA_TDMA_TYPE_MSK			GENMASK(26, 0)
27862306a36Sopenharmony_ci#define CESA_TDMA_DUMMY				0
27962306a36Sopenharmony_ci#define CESA_TDMA_DATA				1
28062306a36Sopenharmony_ci#define CESA_TDMA_OP				2
28162306a36Sopenharmony_ci#define CESA_TDMA_RESULT			3
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci/**
28462306a36Sopenharmony_ci * struct mv_cesa_tdma_desc - TDMA descriptor
28562306a36Sopenharmony_ci * @byte_cnt:	number of bytes to transfer
28662306a36Sopenharmony_ci * @src:	DMA address of the source
28762306a36Sopenharmony_ci * @dst:	DMA address of the destination
28862306a36Sopenharmony_ci * @next_dma:	DMA address of the next TDMA descriptor
28962306a36Sopenharmony_ci * @cur_dma:	DMA address of this TDMA descriptor
29062306a36Sopenharmony_ci * @next:	pointer to the next TDMA descriptor
29162306a36Sopenharmony_ci * @op:		CESA operation attached to this TDMA descriptor
29262306a36Sopenharmony_ci * @data:	raw data attached to this TDMA descriptor
29362306a36Sopenharmony_ci * @flags:	flags describing the TDMA transfer. See the
29462306a36Sopenharmony_ci *		"TDMA descriptor flags" section above
29562306a36Sopenharmony_ci *
29662306a36Sopenharmony_ci * TDMA descriptor used to create a transfer chain describing a crypto
29762306a36Sopenharmony_ci * operation.
29862306a36Sopenharmony_ci */
29962306a36Sopenharmony_cistruct mv_cesa_tdma_desc {
30062306a36Sopenharmony_ci	__le32 byte_cnt;
30162306a36Sopenharmony_ci	union {
30262306a36Sopenharmony_ci		__le32 src;
30362306a36Sopenharmony_ci		u32 src_dma;
30462306a36Sopenharmony_ci	};
30562306a36Sopenharmony_ci	union {
30662306a36Sopenharmony_ci		__le32 dst;
30762306a36Sopenharmony_ci		u32 dst_dma;
30862306a36Sopenharmony_ci	};
30962306a36Sopenharmony_ci	__le32 next_dma;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	/* Software state */
31262306a36Sopenharmony_ci	dma_addr_t cur_dma;
31362306a36Sopenharmony_ci	struct mv_cesa_tdma_desc *next;
31462306a36Sopenharmony_ci	union {
31562306a36Sopenharmony_ci		struct mv_cesa_op_ctx *op;
31662306a36Sopenharmony_ci		void *data;
31762306a36Sopenharmony_ci	};
31862306a36Sopenharmony_ci	u32 flags;
31962306a36Sopenharmony_ci};
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/**
32262306a36Sopenharmony_ci * struct mv_cesa_sg_dma_iter - scatter-gather iterator
32362306a36Sopenharmony_ci * @dir:	transfer direction
32462306a36Sopenharmony_ci * @sg:		scatter list
32562306a36Sopenharmony_ci * @offset:	current position in the scatter list
32662306a36Sopenharmony_ci * @op_offset:	current position in the crypto operation
32762306a36Sopenharmony_ci *
32862306a36Sopenharmony_ci * Iterator used to iterate over a scatterlist while creating a TDMA chain for
32962306a36Sopenharmony_ci * a crypto operation.
33062306a36Sopenharmony_ci */
33162306a36Sopenharmony_cistruct mv_cesa_sg_dma_iter {
33262306a36Sopenharmony_ci	enum dma_data_direction dir;
33362306a36Sopenharmony_ci	struct scatterlist *sg;
33462306a36Sopenharmony_ci	unsigned int offset;
33562306a36Sopenharmony_ci	unsigned int op_offset;
33662306a36Sopenharmony_ci};
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci/**
33962306a36Sopenharmony_ci * struct mv_cesa_dma_iter - crypto operation iterator
34062306a36Sopenharmony_ci * @len:	the crypto operation length
34162306a36Sopenharmony_ci * @offset:	current position in the crypto operation
34262306a36Sopenharmony_ci * @op_len:	sub-operation length (the crypto engine can only act on 2kb
34362306a36Sopenharmony_ci *		chunks)
34462306a36Sopenharmony_ci *
34562306a36Sopenharmony_ci * Iterator used to create a TDMA chain for a given crypto operation.
34662306a36Sopenharmony_ci */
34762306a36Sopenharmony_cistruct mv_cesa_dma_iter {
34862306a36Sopenharmony_ci	unsigned int len;
34962306a36Sopenharmony_ci	unsigned int offset;
35062306a36Sopenharmony_ci	unsigned int op_len;
35162306a36Sopenharmony_ci};
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci/**
35462306a36Sopenharmony_ci * struct mv_cesa_tdma_chain - TDMA chain
35562306a36Sopenharmony_ci * @first:	first entry in the TDMA chain
35662306a36Sopenharmony_ci * @last:	last entry in the TDMA chain
35762306a36Sopenharmony_ci *
35862306a36Sopenharmony_ci * Stores a TDMA chain for a specific crypto operation.
35962306a36Sopenharmony_ci */
36062306a36Sopenharmony_cistruct mv_cesa_tdma_chain {
36162306a36Sopenharmony_ci	struct mv_cesa_tdma_desc *first;
36262306a36Sopenharmony_ci	struct mv_cesa_tdma_desc *last;
36362306a36Sopenharmony_ci};
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_cistruct mv_cesa_engine;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci/**
36862306a36Sopenharmony_ci * struct mv_cesa_caps - CESA device capabilities
36962306a36Sopenharmony_ci * @engines:		number of engines
37062306a36Sopenharmony_ci * @has_tdma:		whether this device has a TDMA block
37162306a36Sopenharmony_ci * @cipher_algs:	supported cipher algorithms
37262306a36Sopenharmony_ci * @ncipher_algs:	number of supported cipher algorithms
37362306a36Sopenharmony_ci * @ahash_algs:		supported hash algorithms
37462306a36Sopenharmony_ci * @nahash_algs:	number of supported hash algorithms
37562306a36Sopenharmony_ci *
37662306a36Sopenharmony_ci * Structure used to describe CESA device capabilities.
37762306a36Sopenharmony_ci */
37862306a36Sopenharmony_cistruct mv_cesa_caps {
37962306a36Sopenharmony_ci	int nengines;
38062306a36Sopenharmony_ci	bool has_tdma;
38162306a36Sopenharmony_ci	struct skcipher_alg **cipher_algs;
38262306a36Sopenharmony_ci	int ncipher_algs;
38362306a36Sopenharmony_ci	struct ahash_alg **ahash_algs;
38462306a36Sopenharmony_ci	int nahash_algs;
38562306a36Sopenharmony_ci};
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci/**
38862306a36Sopenharmony_ci * struct mv_cesa_dev_dma - DMA pools
38962306a36Sopenharmony_ci * @tdma_desc_pool:	TDMA desc pool
39062306a36Sopenharmony_ci * @op_pool:		crypto operation pool
39162306a36Sopenharmony_ci * @cache_pool:		data cache pool (used by hash implementation when the
39262306a36Sopenharmony_ci *			hash request is smaller than the hash block size)
39362306a36Sopenharmony_ci * @padding_pool:	padding pool (used by hash implementation when hardware
39462306a36Sopenharmony_ci *			padding cannot be used)
39562306a36Sopenharmony_ci *
39662306a36Sopenharmony_ci * Structure containing the different DMA pools used by this driver.
39762306a36Sopenharmony_ci */
39862306a36Sopenharmony_cistruct mv_cesa_dev_dma {
39962306a36Sopenharmony_ci	struct dma_pool *tdma_desc_pool;
40062306a36Sopenharmony_ci	struct dma_pool *op_pool;
40162306a36Sopenharmony_ci	struct dma_pool *cache_pool;
40262306a36Sopenharmony_ci	struct dma_pool *padding_pool;
40362306a36Sopenharmony_ci};
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci/**
40662306a36Sopenharmony_ci * struct mv_cesa_dev - CESA device
40762306a36Sopenharmony_ci * @caps:	device capabilities
40862306a36Sopenharmony_ci * @regs:	device registers
40962306a36Sopenharmony_ci * @sram_size:	usable SRAM size
41062306a36Sopenharmony_ci * @lock:	device lock
41162306a36Sopenharmony_ci * @engines:	array of engines
41262306a36Sopenharmony_ci * @dma:	dma pools
41362306a36Sopenharmony_ci *
41462306a36Sopenharmony_ci * Structure storing CESA device information.
41562306a36Sopenharmony_ci */
41662306a36Sopenharmony_cistruct mv_cesa_dev {
41762306a36Sopenharmony_ci	const struct mv_cesa_caps *caps;
41862306a36Sopenharmony_ci	void __iomem *regs;
41962306a36Sopenharmony_ci	struct device *dev;
42062306a36Sopenharmony_ci	unsigned int sram_size;
42162306a36Sopenharmony_ci	spinlock_t lock;
42262306a36Sopenharmony_ci	struct mv_cesa_engine *engines;
42362306a36Sopenharmony_ci	struct mv_cesa_dev_dma *dma;
42462306a36Sopenharmony_ci};
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci/**
42762306a36Sopenharmony_ci * struct mv_cesa_engine - CESA engine
42862306a36Sopenharmony_ci * @id:			engine id
42962306a36Sopenharmony_ci * @regs:		engine registers
43062306a36Sopenharmony_ci * @sram:		SRAM memory region
43162306a36Sopenharmony_ci * @sram_pool:		SRAM memory region from pool
43262306a36Sopenharmony_ci * @sram_dma:		DMA address of the SRAM memory region
43362306a36Sopenharmony_ci * @lock:		engine lock
43462306a36Sopenharmony_ci * @req:		current crypto request
43562306a36Sopenharmony_ci * @clk:		engine clk
43662306a36Sopenharmony_ci * @zclk:		engine zclk
43762306a36Sopenharmony_ci * @max_req_len:	maximum chunk length (useful to create the TDMA chain)
43862306a36Sopenharmony_ci * @int_mask:		interrupt mask cache
43962306a36Sopenharmony_ci * @pool:		memory pool pointing to the memory region reserved in
44062306a36Sopenharmony_ci *			SRAM
44162306a36Sopenharmony_ci * @queue:		fifo of the pending crypto requests
44262306a36Sopenharmony_ci * @load:		engine load counter, useful for load balancing
44362306a36Sopenharmony_ci * @chain:		list of the current tdma descriptors being processed
44462306a36Sopenharmony_ci *			by this engine.
44562306a36Sopenharmony_ci * @complete_queue:	fifo of the processed requests by the engine
44662306a36Sopenharmony_ci *
44762306a36Sopenharmony_ci * Structure storing CESA engine information.
44862306a36Sopenharmony_ci */
44962306a36Sopenharmony_cistruct mv_cesa_engine {
45062306a36Sopenharmony_ci	int id;
45162306a36Sopenharmony_ci	void __iomem *regs;
45262306a36Sopenharmony_ci	union {
45362306a36Sopenharmony_ci		void __iomem *sram;
45462306a36Sopenharmony_ci		void *sram_pool;
45562306a36Sopenharmony_ci	};
45662306a36Sopenharmony_ci	dma_addr_t sram_dma;
45762306a36Sopenharmony_ci	spinlock_t lock;
45862306a36Sopenharmony_ci	struct crypto_async_request *req;
45962306a36Sopenharmony_ci	struct clk *clk;
46062306a36Sopenharmony_ci	struct clk *zclk;
46162306a36Sopenharmony_ci	size_t max_req_len;
46262306a36Sopenharmony_ci	u32 int_mask;
46362306a36Sopenharmony_ci	struct gen_pool *pool;
46462306a36Sopenharmony_ci	struct crypto_queue queue;
46562306a36Sopenharmony_ci	atomic_t load;
46662306a36Sopenharmony_ci	struct mv_cesa_tdma_chain chain;
46762306a36Sopenharmony_ci	struct list_head complete_queue;
46862306a36Sopenharmony_ci	int irq;
46962306a36Sopenharmony_ci};
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci/**
47262306a36Sopenharmony_ci * struct mv_cesa_req_ops - CESA request operations
47362306a36Sopenharmony_ci * @process:	process a request chunk result (should return 0 if the
47462306a36Sopenharmony_ci *		operation, -EINPROGRESS if it needs more steps or an error
47562306a36Sopenharmony_ci *		code)
47662306a36Sopenharmony_ci * @step:	launch the crypto operation on the next chunk
47762306a36Sopenharmony_ci * @cleanup:	cleanup the crypto request (release associated data)
47862306a36Sopenharmony_ci * @complete:	complete the request, i.e copy result or context from sram when
47962306a36Sopenharmony_ci *		needed.
48062306a36Sopenharmony_ci */
48162306a36Sopenharmony_cistruct mv_cesa_req_ops {
48262306a36Sopenharmony_ci	int (*process)(struct crypto_async_request *req, u32 status);
48362306a36Sopenharmony_ci	void (*step)(struct crypto_async_request *req);
48462306a36Sopenharmony_ci	void (*cleanup)(struct crypto_async_request *req);
48562306a36Sopenharmony_ci	void (*complete)(struct crypto_async_request *req);
48662306a36Sopenharmony_ci};
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci/**
48962306a36Sopenharmony_ci * struct mv_cesa_ctx - CESA operation context
49062306a36Sopenharmony_ci * @ops:	crypto operations
49162306a36Sopenharmony_ci *
49262306a36Sopenharmony_ci * Base context structure inherited by operation specific ones.
49362306a36Sopenharmony_ci */
49462306a36Sopenharmony_cistruct mv_cesa_ctx {
49562306a36Sopenharmony_ci	const struct mv_cesa_req_ops *ops;
49662306a36Sopenharmony_ci};
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci/**
49962306a36Sopenharmony_ci * struct mv_cesa_hash_ctx - CESA hash operation context
50062306a36Sopenharmony_ci * @base:	base context structure
50162306a36Sopenharmony_ci *
50262306a36Sopenharmony_ci * Hash context structure.
50362306a36Sopenharmony_ci */
50462306a36Sopenharmony_cistruct mv_cesa_hash_ctx {
50562306a36Sopenharmony_ci	struct mv_cesa_ctx base;
50662306a36Sopenharmony_ci};
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci/**
50962306a36Sopenharmony_ci * struct mv_cesa_hash_ctx - CESA hmac operation context
51062306a36Sopenharmony_ci * @base:	base context structure
51162306a36Sopenharmony_ci * @iv:		initialization vectors
51262306a36Sopenharmony_ci *
51362306a36Sopenharmony_ci * HMAC context structure.
51462306a36Sopenharmony_ci */
51562306a36Sopenharmony_cistruct mv_cesa_hmac_ctx {
51662306a36Sopenharmony_ci	struct mv_cesa_ctx base;
51762306a36Sopenharmony_ci	__be32 iv[16];
51862306a36Sopenharmony_ci};
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci/**
52162306a36Sopenharmony_ci * enum mv_cesa_req_type - request type definitions
52262306a36Sopenharmony_ci * @CESA_STD_REQ:	standard request
52362306a36Sopenharmony_ci * @CESA_DMA_REQ:	DMA request
52462306a36Sopenharmony_ci */
52562306a36Sopenharmony_cienum mv_cesa_req_type {
52662306a36Sopenharmony_ci	CESA_STD_REQ,
52762306a36Sopenharmony_ci	CESA_DMA_REQ,
52862306a36Sopenharmony_ci};
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci/**
53162306a36Sopenharmony_ci * struct mv_cesa_req - CESA request
53262306a36Sopenharmony_ci * @engine:	engine associated with this request
53362306a36Sopenharmony_ci * @chain:	list of tdma descriptors associated  with this request
53462306a36Sopenharmony_ci */
53562306a36Sopenharmony_cistruct mv_cesa_req {
53662306a36Sopenharmony_ci	struct mv_cesa_engine *engine;
53762306a36Sopenharmony_ci	struct mv_cesa_tdma_chain chain;
53862306a36Sopenharmony_ci};
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci/**
54162306a36Sopenharmony_ci * struct mv_cesa_sg_std_iter - CESA scatter-gather iterator for standard
54262306a36Sopenharmony_ci *				requests
54362306a36Sopenharmony_ci * @iter:	sg mapping iterator
54462306a36Sopenharmony_ci * @offset:	current offset in the SG entry mapped in memory
54562306a36Sopenharmony_ci */
54662306a36Sopenharmony_cistruct mv_cesa_sg_std_iter {
54762306a36Sopenharmony_ci	struct sg_mapping_iter iter;
54862306a36Sopenharmony_ci	unsigned int offset;
54962306a36Sopenharmony_ci};
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci/**
55262306a36Sopenharmony_ci * struct mv_cesa_skcipher_std_req - cipher standard request
55362306a36Sopenharmony_ci * @op:		operation context
55462306a36Sopenharmony_ci * @offset:	current operation offset
55562306a36Sopenharmony_ci * @size:	size of the crypto operation
55662306a36Sopenharmony_ci */
55762306a36Sopenharmony_cistruct mv_cesa_skcipher_std_req {
55862306a36Sopenharmony_ci	struct mv_cesa_op_ctx op;
55962306a36Sopenharmony_ci	unsigned int offset;
56062306a36Sopenharmony_ci	unsigned int size;
56162306a36Sopenharmony_ci	bool skip_ctx;
56262306a36Sopenharmony_ci};
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci/**
56562306a36Sopenharmony_ci * struct mv_cesa_skcipher_req - cipher request
56662306a36Sopenharmony_ci * @req:	type specific request information
56762306a36Sopenharmony_ci * @src_nents:	number of entries in the src sg list
56862306a36Sopenharmony_ci * @dst_nents:	number of entries in the dest sg list
56962306a36Sopenharmony_ci */
57062306a36Sopenharmony_cistruct mv_cesa_skcipher_req {
57162306a36Sopenharmony_ci	struct mv_cesa_req base;
57262306a36Sopenharmony_ci	struct mv_cesa_skcipher_std_req std;
57362306a36Sopenharmony_ci	int src_nents;
57462306a36Sopenharmony_ci	int dst_nents;
57562306a36Sopenharmony_ci};
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci/**
57862306a36Sopenharmony_ci * struct mv_cesa_ahash_std_req - standard hash request
57962306a36Sopenharmony_ci * @offset:	current operation offset
58062306a36Sopenharmony_ci */
58162306a36Sopenharmony_cistruct mv_cesa_ahash_std_req {
58262306a36Sopenharmony_ci	unsigned int offset;
58362306a36Sopenharmony_ci};
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci/**
58662306a36Sopenharmony_ci * struct mv_cesa_ahash_dma_req - DMA hash request
58762306a36Sopenharmony_ci * @padding:		padding buffer
58862306a36Sopenharmony_ci * @padding_dma:	DMA address of the padding buffer
58962306a36Sopenharmony_ci * @cache_dma:		DMA address of the cache buffer
59062306a36Sopenharmony_ci */
59162306a36Sopenharmony_cistruct mv_cesa_ahash_dma_req {
59262306a36Sopenharmony_ci	u8 *padding;
59362306a36Sopenharmony_ci	dma_addr_t padding_dma;
59462306a36Sopenharmony_ci	u8 *cache;
59562306a36Sopenharmony_ci	dma_addr_t cache_dma;
59662306a36Sopenharmony_ci};
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci/**
59962306a36Sopenharmony_ci * struct mv_cesa_ahash_req - hash request
60062306a36Sopenharmony_ci * @req:		type specific request information
60162306a36Sopenharmony_ci * @cache:		cache buffer
60262306a36Sopenharmony_ci * @cache_ptr:		write pointer in the cache buffer
60362306a36Sopenharmony_ci * @len:		hash total length
60462306a36Sopenharmony_ci * @src_nents:		number of entries in the scatterlist
60562306a36Sopenharmony_ci * @last_req:		define whether the current operation is the last one
60662306a36Sopenharmony_ci *			or not
60762306a36Sopenharmony_ci * @state:		hash state
60862306a36Sopenharmony_ci */
60962306a36Sopenharmony_cistruct mv_cesa_ahash_req {
61062306a36Sopenharmony_ci	struct mv_cesa_req base;
61162306a36Sopenharmony_ci	union {
61262306a36Sopenharmony_ci		struct mv_cesa_ahash_dma_req dma;
61362306a36Sopenharmony_ci		struct mv_cesa_ahash_std_req std;
61462306a36Sopenharmony_ci	} req;
61562306a36Sopenharmony_ci	struct mv_cesa_op_ctx op_tmpl;
61662306a36Sopenharmony_ci	u8 cache[CESA_MAX_HASH_BLOCK_SIZE];
61762306a36Sopenharmony_ci	unsigned int cache_ptr;
61862306a36Sopenharmony_ci	u64 len;
61962306a36Sopenharmony_ci	int src_nents;
62062306a36Sopenharmony_ci	bool last_req;
62162306a36Sopenharmony_ci	bool algo_le;
62262306a36Sopenharmony_ci	u32 state[8];
62362306a36Sopenharmony_ci};
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci/* CESA functions */
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ciextern struct mv_cesa_dev *cesa_dev;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_cistatic inline void
63162306a36Sopenharmony_cimv_cesa_engine_enqueue_complete_request(struct mv_cesa_engine *engine,
63262306a36Sopenharmony_ci					struct crypto_async_request *req)
63362306a36Sopenharmony_ci{
63462306a36Sopenharmony_ci	list_add_tail(&req->list, &engine->complete_queue);
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic inline struct crypto_async_request *
63862306a36Sopenharmony_cimv_cesa_engine_dequeue_complete_request(struct mv_cesa_engine *engine)
63962306a36Sopenharmony_ci{
64062306a36Sopenharmony_ci	struct crypto_async_request *req;
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	req = list_first_entry_or_null(&engine->complete_queue,
64362306a36Sopenharmony_ci				       struct crypto_async_request,
64462306a36Sopenharmony_ci				       list);
64562306a36Sopenharmony_ci	if (req)
64662306a36Sopenharmony_ci		list_del(&req->list);
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	return req;
64962306a36Sopenharmony_ci}
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistatic inline enum mv_cesa_req_type
65362306a36Sopenharmony_cimv_cesa_req_get_type(struct mv_cesa_req *req)
65462306a36Sopenharmony_ci{
65562306a36Sopenharmony_ci	return req->chain.first ? CESA_DMA_REQ : CESA_STD_REQ;
65662306a36Sopenharmony_ci}
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_cistatic inline void mv_cesa_update_op_cfg(struct mv_cesa_op_ctx *op,
65962306a36Sopenharmony_ci					 u32 cfg, u32 mask)
66062306a36Sopenharmony_ci{
66162306a36Sopenharmony_ci	op->desc.config &= cpu_to_le32(~mask);
66262306a36Sopenharmony_ci	op->desc.config |= cpu_to_le32(cfg);
66362306a36Sopenharmony_ci}
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_cistatic inline u32 mv_cesa_get_op_cfg(const struct mv_cesa_op_ctx *op)
66662306a36Sopenharmony_ci{
66762306a36Sopenharmony_ci	return le32_to_cpu(op->desc.config);
66862306a36Sopenharmony_ci}
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_cistatic inline void mv_cesa_set_op_cfg(struct mv_cesa_op_ctx *op, u32 cfg)
67162306a36Sopenharmony_ci{
67262306a36Sopenharmony_ci	op->desc.config = cpu_to_le32(cfg);
67362306a36Sopenharmony_ci}
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_cistatic inline void mv_cesa_adjust_op(struct mv_cesa_engine *engine,
67662306a36Sopenharmony_ci				     struct mv_cesa_op_ctx *op)
67762306a36Sopenharmony_ci{
67862306a36Sopenharmony_ci	u32 offset = engine->sram_dma & CESA_SA_SRAM_MSK;
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	op->desc.enc_p = CESA_SA_DESC_CRYPT_DATA(offset);
68162306a36Sopenharmony_ci	op->desc.enc_key_p = CESA_SA_DESC_CRYPT_KEY(offset);
68262306a36Sopenharmony_ci	op->desc.enc_iv = CESA_SA_DESC_CRYPT_IV(offset);
68362306a36Sopenharmony_ci	op->desc.mac_src_p &= ~CESA_SA_DESC_MAC_DATA_MSK;
68462306a36Sopenharmony_ci	op->desc.mac_src_p |= CESA_SA_DESC_MAC_DATA(offset);
68562306a36Sopenharmony_ci	op->desc.mac_digest &= ~CESA_SA_DESC_MAC_DIGEST_MSK;
68662306a36Sopenharmony_ci	op->desc.mac_digest |= CESA_SA_DESC_MAC_DIGEST(offset);
68762306a36Sopenharmony_ci	op->desc.mac_iv = CESA_SA_DESC_MAC_IV(offset);
68862306a36Sopenharmony_ci}
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_cistatic inline void mv_cesa_set_crypt_op_len(struct mv_cesa_op_ctx *op, int len)
69162306a36Sopenharmony_ci{
69262306a36Sopenharmony_ci	op->desc.enc_len = cpu_to_le32(len);
69362306a36Sopenharmony_ci}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_cistatic inline void mv_cesa_set_mac_op_total_len(struct mv_cesa_op_ctx *op,
69662306a36Sopenharmony_ci						int len)
69762306a36Sopenharmony_ci{
69862306a36Sopenharmony_ci	op->desc.mac_src_p &= ~CESA_SA_DESC_MAC_TOTAL_LEN_MSK;
69962306a36Sopenharmony_ci	op->desc.mac_src_p |= CESA_SA_DESC_MAC_TOTAL_LEN(len);
70062306a36Sopenharmony_ci}
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_cistatic inline void mv_cesa_set_mac_op_frag_len(struct mv_cesa_op_ctx *op,
70362306a36Sopenharmony_ci					       int len)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	op->desc.mac_digest &= ~CESA_SA_DESC_MAC_FRAG_LEN_MSK;
70662306a36Sopenharmony_ci	op->desc.mac_digest |= CESA_SA_DESC_MAC_FRAG_LEN(len);
70762306a36Sopenharmony_ci}
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_cistatic inline void mv_cesa_set_int_mask(struct mv_cesa_engine *engine,
71062306a36Sopenharmony_ci					u32 int_mask)
71162306a36Sopenharmony_ci{
71262306a36Sopenharmony_ci	if (int_mask == engine->int_mask)
71362306a36Sopenharmony_ci		return;
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	writel_relaxed(int_mask, engine->regs + CESA_SA_INT_MSK);
71662306a36Sopenharmony_ci	engine->int_mask = int_mask;
71762306a36Sopenharmony_ci}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic inline u32 mv_cesa_get_int_mask(struct mv_cesa_engine *engine)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	return engine->int_mask;
72262306a36Sopenharmony_ci}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic inline bool mv_cesa_mac_op_is_first_frag(const struct mv_cesa_op_ctx *op)
72562306a36Sopenharmony_ci{
72662306a36Sopenharmony_ci	return (mv_cesa_get_op_cfg(op) & CESA_SA_DESC_CFG_FRAG_MSK) ==
72762306a36Sopenharmony_ci		CESA_SA_DESC_CFG_FIRST_FRAG;
72862306a36Sopenharmony_ci}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ciint mv_cesa_queue_req(struct crypto_async_request *req,
73162306a36Sopenharmony_ci		      struct mv_cesa_req *creq);
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_cistruct crypto_async_request *
73462306a36Sopenharmony_cimv_cesa_dequeue_req_locked(struct mv_cesa_engine *engine,
73562306a36Sopenharmony_ci			   struct crypto_async_request **backlog);
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_cistatic inline struct mv_cesa_engine *mv_cesa_select_engine(int weight)
73862306a36Sopenharmony_ci{
73962306a36Sopenharmony_ci	int i;
74062306a36Sopenharmony_ci	u32 min_load = U32_MAX;
74162306a36Sopenharmony_ci	struct mv_cesa_engine *selected = NULL;
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci	for (i = 0; i < cesa_dev->caps->nengines; i++) {
74462306a36Sopenharmony_ci		struct mv_cesa_engine *engine = cesa_dev->engines + i;
74562306a36Sopenharmony_ci		u32 load = atomic_read(&engine->load);
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci		if (load < min_load) {
74862306a36Sopenharmony_ci			min_load = load;
74962306a36Sopenharmony_ci			selected = engine;
75062306a36Sopenharmony_ci		}
75162306a36Sopenharmony_ci	}
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci	atomic_add(weight, &selected->load);
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci	return selected;
75662306a36Sopenharmony_ci}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci/*
75962306a36Sopenharmony_ci * Helper function that indicates whether a crypto request needs to be
76062306a36Sopenharmony_ci * cleaned up or not after being enqueued using mv_cesa_queue_req().
76162306a36Sopenharmony_ci */
76262306a36Sopenharmony_cistatic inline int mv_cesa_req_needs_cleanup(struct crypto_async_request *req,
76362306a36Sopenharmony_ci					    int ret)
76462306a36Sopenharmony_ci{
76562306a36Sopenharmony_ci	/*
76662306a36Sopenharmony_ci	 * The queue still had some space, the request was queued
76762306a36Sopenharmony_ci	 * normally, so there's no need to clean it up.
76862306a36Sopenharmony_ci	 */
76962306a36Sopenharmony_ci	if (ret == -EINPROGRESS)
77062306a36Sopenharmony_ci		return false;
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci	/*
77362306a36Sopenharmony_ci	 * The queue had not space left, but since the request is
77462306a36Sopenharmony_ci	 * flagged with CRYPTO_TFM_REQ_MAY_BACKLOG, it was added to
77562306a36Sopenharmony_ci	 * the backlog and will be processed later. There's no need to
77662306a36Sopenharmony_ci	 * clean it up.
77762306a36Sopenharmony_ci	 */
77862306a36Sopenharmony_ci	if (ret == -EBUSY)
77962306a36Sopenharmony_ci		return false;
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	/* Request wasn't queued, we need to clean it up */
78262306a36Sopenharmony_ci	return true;
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci/* TDMA functions */
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_cistatic inline void mv_cesa_req_dma_iter_init(struct mv_cesa_dma_iter *iter,
78862306a36Sopenharmony_ci					     unsigned int len)
78962306a36Sopenharmony_ci{
79062306a36Sopenharmony_ci	iter->len = len;
79162306a36Sopenharmony_ci	iter->op_len = min(len, CESA_SA_SRAM_PAYLOAD_SIZE);
79262306a36Sopenharmony_ci	iter->offset = 0;
79362306a36Sopenharmony_ci}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_cistatic inline void mv_cesa_sg_dma_iter_init(struct mv_cesa_sg_dma_iter *iter,
79662306a36Sopenharmony_ci					    struct scatterlist *sg,
79762306a36Sopenharmony_ci					    enum dma_data_direction dir)
79862306a36Sopenharmony_ci{
79962306a36Sopenharmony_ci	iter->op_offset = 0;
80062306a36Sopenharmony_ci	iter->offset = 0;
80162306a36Sopenharmony_ci	iter->sg = sg;
80262306a36Sopenharmony_ci	iter->dir = dir;
80362306a36Sopenharmony_ci}
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_cistatic inline unsigned int
80662306a36Sopenharmony_cimv_cesa_req_dma_iter_transfer_len(struct mv_cesa_dma_iter *iter,
80762306a36Sopenharmony_ci				  struct mv_cesa_sg_dma_iter *sgiter)
80862306a36Sopenharmony_ci{
80962306a36Sopenharmony_ci	return min(iter->op_len - sgiter->op_offset,
81062306a36Sopenharmony_ci		   sg_dma_len(sgiter->sg) - sgiter->offset);
81162306a36Sopenharmony_ci}
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_cibool mv_cesa_req_dma_iter_next_transfer(struct mv_cesa_dma_iter *chain,
81462306a36Sopenharmony_ci					struct mv_cesa_sg_dma_iter *sgiter,
81562306a36Sopenharmony_ci					unsigned int len);
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_cistatic inline bool mv_cesa_req_dma_iter_next_op(struct mv_cesa_dma_iter *iter)
81862306a36Sopenharmony_ci{
81962306a36Sopenharmony_ci	iter->offset += iter->op_len;
82062306a36Sopenharmony_ci	iter->op_len = min(iter->len - iter->offset,
82162306a36Sopenharmony_ci			   CESA_SA_SRAM_PAYLOAD_SIZE);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci	return iter->op_len;
82462306a36Sopenharmony_ci}
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_civoid mv_cesa_dma_step(struct mv_cesa_req *dreq);
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_cistatic inline int mv_cesa_dma_process(struct mv_cesa_req *dreq,
82962306a36Sopenharmony_ci				      u32 status)
83062306a36Sopenharmony_ci{
83162306a36Sopenharmony_ci	if (!(status & CESA_SA_INT_ACC0_IDMA_DONE))
83262306a36Sopenharmony_ci		return -EINPROGRESS;
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	if (status & CESA_SA_INT_IDMA_OWN_ERR)
83562306a36Sopenharmony_ci		return -EINVAL;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	return 0;
83862306a36Sopenharmony_ci}
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_civoid mv_cesa_dma_prepare(struct mv_cesa_req *dreq,
84162306a36Sopenharmony_ci			 struct mv_cesa_engine *engine);
84262306a36Sopenharmony_civoid mv_cesa_dma_cleanup(struct mv_cesa_req *dreq);
84362306a36Sopenharmony_civoid mv_cesa_tdma_chain(struct mv_cesa_engine *engine,
84462306a36Sopenharmony_ci			struct mv_cesa_req *dreq);
84562306a36Sopenharmony_ciint mv_cesa_tdma_process(struct mv_cesa_engine *engine, u32 status);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_cistatic inline void
84962306a36Sopenharmony_cimv_cesa_tdma_desc_iter_init(struct mv_cesa_tdma_chain *chain)
85062306a36Sopenharmony_ci{
85162306a36Sopenharmony_ci	memset(chain, 0, sizeof(*chain));
85262306a36Sopenharmony_ci}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ciint mv_cesa_dma_add_result_op(struct mv_cesa_tdma_chain *chain, dma_addr_t src,
85562306a36Sopenharmony_ci			  u32 size, u32 flags, gfp_t gfp_flags);
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_cistruct mv_cesa_op_ctx *mv_cesa_dma_add_op(struct mv_cesa_tdma_chain *chain,
85862306a36Sopenharmony_ci					const struct mv_cesa_op_ctx *op_templ,
85962306a36Sopenharmony_ci					bool skip_ctx,
86062306a36Sopenharmony_ci					gfp_t flags);
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ciint mv_cesa_dma_add_data_transfer(struct mv_cesa_tdma_chain *chain,
86362306a36Sopenharmony_ci				  dma_addr_t dst, dma_addr_t src, u32 size,
86462306a36Sopenharmony_ci				  u32 flags, gfp_t gfp_flags);
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ciint mv_cesa_dma_add_dummy_launch(struct mv_cesa_tdma_chain *chain, gfp_t flags);
86762306a36Sopenharmony_ciint mv_cesa_dma_add_dummy_end(struct mv_cesa_tdma_chain *chain, gfp_t flags);
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ciint mv_cesa_dma_add_op_transfers(struct mv_cesa_tdma_chain *chain,
87062306a36Sopenharmony_ci				 struct mv_cesa_dma_iter *dma_iter,
87162306a36Sopenharmony_ci				 struct mv_cesa_sg_dma_iter *sgiter,
87262306a36Sopenharmony_ci				 gfp_t gfp_flags);
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_cisize_t mv_cesa_sg_copy(struct mv_cesa_engine *engine,
87562306a36Sopenharmony_ci		       struct scatterlist *sgl, unsigned int nents,
87662306a36Sopenharmony_ci		       unsigned int sram_off, size_t buflen, off_t skip,
87762306a36Sopenharmony_ci		       bool to_sram);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_cistatic inline size_t mv_cesa_sg_copy_to_sram(struct mv_cesa_engine *engine,
88062306a36Sopenharmony_ci					     struct scatterlist *sgl,
88162306a36Sopenharmony_ci					     unsigned int nents,
88262306a36Sopenharmony_ci					     unsigned int sram_off,
88362306a36Sopenharmony_ci					     size_t buflen, off_t skip)
88462306a36Sopenharmony_ci{
88562306a36Sopenharmony_ci	return mv_cesa_sg_copy(engine, sgl, nents, sram_off, buflen, skip,
88662306a36Sopenharmony_ci			       true);
88762306a36Sopenharmony_ci}
88862306a36Sopenharmony_ci
88962306a36Sopenharmony_cistatic inline size_t mv_cesa_sg_copy_from_sram(struct mv_cesa_engine *engine,
89062306a36Sopenharmony_ci					       struct scatterlist *sgl,
89162306a36Sopenharmony_ci					       unsigned int nents,
89262306a36Sopenharmony_ci					       unsigned int sram_off,
89362306a36Sopenharmony_ci					       size_t buflen, off_t skip)
89462306a36Sopenharmony_ci{
89562306a36Sopenharmony_ci	return mv_cesa_sg_copy(engine, sgl, nents, sram_off, buflen, skip,
89662306a36Sopenharmony_ci			       false);
89762306a36Sopenharmony_ci}
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci/* Algorithm definitions */
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ciextern struct ahash_alg mv_md5_alg;
90262306a36Sopenharmony_ciextern struct ahash_alg mv_sha1_alg;
90362306a36Sopenharmony_ciextern struct ahash_alg mv_sha256_alg;
90462306a36Sopenharmony_ciextern struct ahash_alg mv_ahmac_md5_alg;
90562306a36Sopenharmony_ciextern struct ahash_alg mv_ahmac_sha1_alg;
90662306a36Sopenharmony_ciextern struct ahash_alg mv_ahmac_sha256_alg;
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ciextern struct skcipher_alg mv_cesa_ecb_des_alg;
90962306a36Sopenharmony_ciextern struct skcipher_alg mv_cesa_cbc_des_alg;
91062306a36Sopenharmony_ciextern struct skcipher_alg mv_cesa_ecb_des3_ede_alg;
91162306a36Sopenharmony_ciextern struct skcipher_alg mv_cesa_cbc_des3_ede_alg;
91262306a36Sopenharmony_ciextern struct skcipher_alg mv_cesa_ecb_aes_alg;
91362306a36Sopenharmony_ciextern struct skcipher_alg mv_cesa_cbc_aes_alg;
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci#endif /* __MARVELL_CESA_H__ */
916