162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __STARFIVE_STR_H__
362306a36Sopenharmony_ci#define __STARFIVE_STR_H__
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <crypto/aes.h>
662306a36Sopenharmony_ci#include <crypto/hash.h>
762306a36Sopenharmony_ci#include <crypto/scatterwalk.h>
862306a36Sopenharmony_ci#include <crypto/sha2.h>
962306a36Sopenharmony_ci#include <crypto/sm3.h>
1062306a36Sopenharmony_ci#include <linux/delay.h>
1162306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1262306a36Sopenharmony_ci#include <linux/dmaengine.h>
1362306a36Sopenharmony_ci#include <linux/interrupt.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define STARFIVE_ALG_CR_OFFSET			0x0
1662306a36Sopenharmony_ci#define STARFIVE_ALG_FIFO_OFFSET		0x4
1762306a36Sopenharmony_ci#define STARFIVE_IE_MASK_OFFSET			0x8
1862306a36Sopenharmony_ci#define STARFIVE_IE_FLAG_OFFSET			0xc
1962306a36Sopenharmony_ci#define STARFIVE_DMA_IN_LEN_OFFSET		0x10
2062306a36Sopenharmony_ci#define STARFIVE_DMA_OUT_LEN_OFFSET		0x14
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define STARFIVE_IE_MASK_AES_DONE		0x1
2362306a36Sopenharmony_ci#define STARFIVE_IE_MASK_HASH_DONE		0x4
2462306a36Sopenharmony_ci#define STARFIVE_IE_MASK_PKA_DONE		0x8
2562306a36Sopenharmony_ci#define STARFIVE_IE_FLAG_AES_DONE		0x1
2662306a36Sopenharmony_ci#define STARFIVE_IE_FLAG_HASH_DONE		0x4
2762306a36Sopenharmony_ci#define STARFIVE_IE_FLAG_PKA_DONE		0x8
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define STARFIVE_MSG_BUFFER_SIZE		SZ_16K
3062306a36Sopenharmony_ci#define MAX_KEY_SIZE				SHA512_BLOCK_SIZE
3162306a36Sopenharmony_ci#define STARFIVE_AES_IV_LEN			AES_BLOCK_SIZE
3262306a36Sopenharmony_ci#define STARFIVE_AES_CTR_LEN			AES_BLOCK_SIZE
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciunion starfive_aes_csr {
3562306a36Sopenharmony_ci	u32 v;
3662306a36Sopenharmony_ci	struct {
3762306a36Sopenharmony_ci		u32 cmode			:1;
3862306a36Sopenharmony_ci#define STARFIVE_AES_KEYMODE_128		0x0
3962306a36Sopenharmony_ci#define STARFIVE_AES_KEYMODE_192		0x1
4062306a36Sopenharmony_ci#define STARFIVE_AES_KEYMODE_256		0x2
4162306a36Sopenharmony_ci		u32 keymode			:2;
4262306a36Sopenharmony_ci#define STARFIVE_AES_BUSY			BIT(3)
4362306a36Sopenharmony_ci		u32 busy			:1;
4462306a36Sopenharmony_ci		u32 done			:1;
4562306a36Sopenharmony_ci#define STARFIVE_AES_KEY_DONE			BIT(5)
4662306a36Sopenharmony_ci		u32 krdy			:1;
4762306a36Sopenharmony_ci		u32 aesrst			:1;
4862306a36Sopenharmony_ci		u32 ie				:1;
4962306a36Sopenharmony_ci#define STARFIVE_AES_CCM_START			BIT(8)
5062306a36Sopenharmony_ci		u32 ccm_start			:1;
5162306a36Sopenharmony_ci#define STARFIVE_AES_MODE_ECB			0x0
5262306a36Sopenharmony_ci#define STARFIVE_AES_MODE_CBC			0x1
5362306a36Sopenharmony_ci#define STARFIVE_AES_MODE_CFB			0x2
5462306a36Sopenharmony_ci#define STARFIVE_AES_MODE_OFB			0x3
5562306a36Sopenharmony_ci#define STARFIVE_AES_MODE_CTR			0x4
5662306a36Sopenharmony_ci#define STARFIVE_AES_MODE_CCM			0x5
5762306a36Sopenharmony_ci#define STARFIVE_AES_MODE_GCM			0x6
5862306a36Sopenharmony_ci		u32 mode			:3;
5962306a36Sopenharmony_ci#define STARFIVE_AES_GCM_START			BIT(12)
6062306a36Sopenharmony_ci		u32 gcm_start			:1;
6162306a36Sopenharmony_ci#define STARFIVE_AES_GCM_DONE			BIT(13)
6262306a36Sopenharmony_ci		u32 gcm_done			:1;
6362306a36Sopenharmony_ci		u32 delay_aes			:1;
6462306a36Sopenharmony_ci		u32 vaes_start			:1;
6562306a36Sopenharmony_ci		u32 rsvd_0			:8;
6662306a36Sopenharmony_ci#define STARFIVE_AES_MODE_XFB_1			0x0
6762306a36Sopenharmony_ci#define STARFIVE_AES_MODE_XFB_128		0x5
6862306a36Sopenharmony_ci		u32 stmode			:3;
6962306a36Sopenharmony_ci		u32 rsvd_1			:5;
7062306a36Sopenharmony_ci	};
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciunion starfive_hash_csr {
7462306a36Sopenharmony_ci	u32 v;
7562306a36Sopenharmony_ci	struct {
7662306a36Sopenharmony_ci		u32 start			:1;
7762306a36Sopenharmony_ci		u32 reset			:1;
7862306a36Sopenharmony_ci		u32 ie				:1;
7962306a36Sopenharmony_ci		u32 firstb			:1;
8062306a36Sopenharmony_ci#define STARFIVE_HASH_SM3			0x0
8162306a36Sopenharmony_ci#define STARFIVE_HASH_SHA224			0x3
8262306a36Sopenharmony_ci#define STARFIVE_HASH_SHA256			0x4
8362306a36Sopenharmony_ci#define STARFIVE_HASH_SHA384			0x5
8462306a36Sopenharmony_ci#define STARFIVE_HASH_SHA512			0x6
8562306a36Sopenharmony_ci#define STARFIVE_HASH_MODE_MASK			0x7
8662306a36Sopenharmony_ci		u32 mode			:3;
8762306a36Sopenharmony_ci		u32 rsvd_1			:1;
8862306a36Sopenharmony_ci		u32 final			:1;
8962306a36Sopenharmony_ci		u32 rsvd_2			:2;
9062306a36Sopenharmony_ci#define STARFIVE_HASH_HMAC_FLAGS		0x800
9162306a36Sopenharmony_ci		u32 hmac			:1;
9262306a36Sopenharmony_ci		u32 rsvd_3			:1;
9362306a36Sopenharmony_ci#define STARFIVE_HASH_KEY_DONE			BIT(13)
9462306a36Sopenharmony_ci		u32 key_done			:1;
9562306a36Sopenharmony_ci		u32 key_flag			:1;
9662306a36Sopenharmony_ci		u32 hmac_done			:1;
9762306a36Sopenharmony_ci#define STARFIVE_HASH_BUSY			BIT(16)
9862306a36Sopenharmony_ci		u32 busy			:1;
9962306a36Sopenharmony_ci		u32 hashdone			:1;
10062306a36Sopenharmony_ci		u32 rsvd_4			:14;
10162306a36Sopenharmony_ci	};
10262306a36Sopenharmony_ci};
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciunion starfive_pka_cacr {
10562306a36Sopenharmony_ci	u32 v;
10662306a36Sopenharmony_ci	struct {
10762306a36Sopenharmony_ci		u32 start			:1;
10862306a36Sopenharmony_ci		u32 reset			:1;
10962306a36Sopenharmony_ci		u32 ie				:1;
11062306a36Sopenharmony_ci		u32 rsvd_0			:1;
11162306a36Sopenharmony_ci		u32 fifo_mode			:1;
11262306a36Sopenharmony_ci		u32 not_r2			:1;
11362306a36Sopenharmony_ci		u32 ecc_sub			:1;
11462306a36Sopenharmony_ci		u32 pre_expf			:1;
11562306a36Sopenharmony_ci		u32 cmd				:4;
11662306a36Sopenharmony_ci		u32 rsvd_1			:1;
11762306a36Sopenharmony_ci		u32 ctrl_dummy			:1;
11862306a36Sopenharmony_ci		u32 ctrl_false			:1;
11962306a36Sopenharmony_ci		u32 cln_done			:1;
12062306a36Sopenharmony_ci		u32 opsize			:6;
12162306a36Sopenharmony_ci		u32 rsvd_2			:2;
12262306a36Sopenharmony_ci		u32 exposize			:6;
12362306a36Sopenharmony_ci		u32 rsvd_3			:1;
12462306a36Sopenharmony_ci		u32 bigendian			:1;
12562306a36Sopenharmony_ci	};
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistruct starfive_rsa_key {
12962306a36Sopenharmony_ci	u8	*n;
13062306a36Sopenharmony_ci	u8	*e;
13162306a36Sopenharmony_ci	u8	*d;
13262306a36Sopenharmony_ci	int	e_bitlen;
13362306a36Sopenharmony_ci	int	d_bitlen;
13462306a36Sopenharmony_ci	int	bitlen;
13562306a36Sopenharmony_ci	size_t	key_sz;
13662306a36Sopenharmony_ci};
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ciunion starfive_alg_cr {
13962306a36Sopenharmony_ci	u32 v;
14062306a36Sopenharmony_ci	struct {
14162306a36Sopenharmony_ci		u32 start			:1;
14262306a36Sopenharmony_ci		u32 aes_dma_en			:1;
14362306a36Sopenharmony_ci		u32 rsvd_0			:1;
14462306a36Sopenharmony_ci		u32 hash_dma_en			:1;
14562306a36Sopenharmony_ci		u32 alg_done			:1;
14662306a36Sopenharmony_ci		u32 rsvd_1			:3;
14762306a36Sopenharmony_ci		u32 clear			:1;
14862306a36Sopenharmony_ci		u32 rsvd_2			:23;
14962306a36Sopenharmony_ci	};
15062306a36Sopenharmony_ci};
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistruct starfive_cryp_ctx {
15362306a36Sopenharmony_ci	struct starfive_cryp_dev		*cryp;
15462306a36Sopenharmony_ci	struct starfive_cryp_request_ctx	*rctx;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	unsigned int				hash_mode;
15762306a36Sopenharmony_ci	u8					key[MAX_KEY_SIZE];
15862306a36Sopenharmony_ci	int					keylen;
15962306a36Sopenharmony_ci	bool					is_hmac;
16062306a36Sopenharmony_ci	struct starfive_rsa_key			rsa_key;
16162306a36Sopenharmony_ci	struct crypto_akcipher			*akcipher_fbk;
16262306a36Sopenharmony_ci	struct crypto_ahash			*ahash_fbk;
16362306a36Sopenharmony_ci	struct crypto_aead			*aead_fbk;
16462306a36Sopenharmony_ci};
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistruct starfive_cryp_dev {
16762306a36Sopenharmony_ci	struct list_head			list;
16862306a36Sopenharmony_ci	struct device				*dev;
16962306a36Sopenharmony_ci	struct clk				*hclk;
17062306a36Sopenharmony_ci	struct clk				*ahb;
17162306a36Sopenharmony_ci	struct reset_control			*rst;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	void __iomem				*base;
17462306a36Sopenharmony_ci	phys_addr_t				phys_base;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	u32					dma_maxburst;
17762306a36Sopenharmony_ci	struct dma_chan				*tx;
17862306a36Sopenharmony_ci	struct dma_chan				*rx;
17962306a36Sopenharmony_ci	struct dma_slave_config			cfg_in;
18062306a36Sopenharmony_ci	struct dma_slave_config			cfg_out;
18162306a36Sopenharmony_ci	struct scatter_walk			in_walk;
18262306a36Sopenharmony_ci	struct scatter_walk			out_walk;
18362306a36Sopenharmony_ci	struct crypto_engine			*engine;
18462306a36Sopenharmony_ci	struct tasklet_struct			aes_done;
18562306a36Sopenharmony_ci	struct tasklet_struct			hash_done;
18662306a36Sopenharmony_ci	struct completion			pka_done;
18762306a36Sopenharmony_ci	size_t					assoclen;
18862306a36Sopenharmony_ci	size_t					total_in;
18962306a36Sopenharmony_ci	size_t					total_out;
19062306a36Sopenharmony_ci	u32					tag_in[4];
19162306a36Sopenharmony_ci	u32					tag_out[4];
19262306a36Sopenharmony_ci	unsigned int				authsize;
19362306a36Sopenharmony_ci	unsigned long				flags;
19462306a36Sopenharmony_ci	int					err;
19562306a36Sopenharmony_ci	bool					side_chan;
19662306a36Sopenharmony_ci	union starfive_alg_cr			alg_cr;
19762306a36Sopenharmony_ci	union {
19862306a36Sopenharmony_ci		struct ahash_request		*hreq;
19962306a36Sopenharmony_ci		struct aead_request		*areq;
20062306a36Sopenharmony_ci		struct skcipher_request		*sreq;
20162306a36Sopenharmony_ci	} req;
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_cistruct starfive_cryp_request_ctx {
20562306a36Sopenharmony_ci	union {
20662306a36Sopenharmony_ci		union starfive_hash_csr		hash;
20762306a36Sopenharmony_ci		union starfive_pka_cacr		pka;
20862306a36Sopenharmony_ci		union starfive_aes_csr		aes;
20962306a36Sopenharmony_ci	} csr;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	struct scatterlist			*in_sg;
21262306a36Sopenharmony_ci	struct scatterlist			*out_sg;
21362306a36Sopenharmony_ci	struct ahash_request			ahash_fbk_req;
21462306a36Sopenharmony_ci	size_t					total;
21562306a36Sopenharmony_ci	size_t					nents;
21662306a36Sopenharmony_ci	unsigned int				blksize;
21762306a36Sopenharmony_ci	unsigned int				digsize;
21862306a36Sopenharmony_ci	unsigned long				in_sg_len;
21962306a36Sopenharmony_ci	unsigned char				*adata;
22062306a36Sopenharmony_ci	u8 rsa_data[] __aligned(sizeof(u32));
22162306a36Sopenharmony_ci};
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cistruct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciint starfive_hash_register_algs(void);
22662306a36Sopenharmony_civoid starfive_hash_unregister_algs(void);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ciint starfive_rsa_register_algs(void);
22962306a36Sopenharmony_civoid starfive_rsa_unregister_algs(void);
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ciint starfive_aes_register_algs(void);
23262306a36Sopenharmony_civoid starfive_aes_unregister_algs(void);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_civoid starfive_hash_done_task(unsigned long param);
23562306a36Sopenharmony_civoid starfive_aes_done_task(unsigned long param);
23662306a36Sopenharmony_ci#endif
237