1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * sun8i-ce.h - hardware cryptographic offloader for
4  * Allwinner H3/A64/H5/H2+/H6 SoC
5  *
6  * Copyright (C) 2016-2019 Corentin LABBE <clabbe.montjoie@gmail.com>
7  */
8 #include <crypto/aes.h>
9 #include <crypto/des.h>
10 #include <crypto/engine.h>
11 #include <crypto/skcipher.h>
12 #include <linux/atomic.h>
13 #include <linux/debugfs.h>
14 #include <linux/crypto.h>
15 
16 /* CE Registers */
17 #define CE_TDQ	0x00
18 #define CE_CTR	0x04
19 #define CE_ICR	0x08
20 #define CE_ISR	0x0C
21 #define CE_TLR	0x10
22 #define CE_TSR	0x14
23 #define CE_ESR	0x18
24 #define CE_CSSGR	0x1C
25 #define CE_CDSGR	0x20
26 #define CE_CSAR	0x24
27 #define CE_CDAR	0x28
28 #define CE_TPR	0x2C
29 
30 /* Used in struct ce_task */
31 /* ce_task common */
32 #define CE_ENCRYPTION		0
33 #define CE_DECRYPTION		BIT(8)
34 
35 #define CE_COMM_INT		BIT(31)
36 
37 /* ce_task symmetric */
38 #define CE_AES_128BITS 0
39 #define CE_AES_192BITS 1
40 #define CE_AES_256BITS 2
41 
42 #define CE_OP_ECB	0
43 #define CE_OP_CBC	(1 << 8)
44 
45 #define CE_ALG_AES		0
46 #define CE_ALG_DES		1
47 #define CE_ALG_3DES		2
48 
49 /* Used in ce_variant */
50 #define CE_ID_NOTSUPP		0xFF
51 
52 #define CE_ID_CIPHER_AES	0
53 #define CE_ID_CIPHER_DES	1
54 #define CE_ID_CIPHER_DES3	2
55 #define CE_ID_CIPHER_MAX	3
56 
57 #define CE_ID_OP_ECB	0
58 #define CE_ID_OP_CBC	1
59 #define CE_ID_OP_MAX	2
60 
61 /* Used in CE registers */
62 #define CE_ERR_ALGO_NOTSUP	BIT(0)
63 #define CE_ERR_DATALEN		BIT(1)
64 #define CE_ERR_KEYSRAM		BIT(2)
65 #define CE_ERR_ADDR_INVALID	BIT(5)
66 #define CE_ERR_KEYLADDER	BIT(6)
67 
68 #define CE_DIE_ID_SHIFT	16
69 #define CE_DIE_ID_MASK	0x07
70 
71 #define MAX_SG 8
72 
73 #define CE_MAX_CLOCKS 3
74 
75 #define MAXFLOW 4
76 
77 /*
78  * struct ce_clock - Describe clocks used by sun8i-ce
79  * @name:	Name of clock needed by this variant
80  * @freq:	Frequency to set for each clock
81  * @max_freq:	Maximum frequency for each clock (generally given by datasheet)
82  */
83 struct ce_clock {
84 	const char *name;
85 	unsigned long freq;
86 	unsigned long max_freq;
87 };
88 
89 /*
90  * struct ce_variant - Describe CE capability for each variant hardware
91  * @alg_cipher:	list of supported ciphers. for each CE_ID_ this will give the
92  *              coresponding CE_ALG_XXX value
93  * @op_mode:	list of supported block modes
94  * @has_t_dlen_in_bytes:	Does the request size for cipher is in
95  *				bytes or words
96  * @ce_clks:	list of clocks needed by this variant
97  */
98 struct ce_variant {
99 	char alg_cipher[CE_ID_CIPHER_MAX];
100 	u32 op_mode[CE_ID_OP_MAX];
101 	bool has_t_dlen_in_bytes;
102 	struct ce_clock ce_clks[CE_MAX_CLOCKS];
103 };
104 
105 struct sginfo {
106 	__le32 addr;
107 	__le32 len;
108 } __packed;
109 
110 /*
111  * struct ce_task - CE Task descriptor
112  * The structure of this descriptor could be found in the datasheet
113  */
114 struct ce_task {
115 	__le32 t_id;
116 	__le32 t_common_ctl;
117 	__le32 t_sym_ctl;
118 	__le32 t_asym_ctl;
119 	__le32 t_key;
120 	__le32 t_iv;
121 	__le32 t_ctr;
122 	__le32 t_dlen;
123 	struct sginfo t_src[MAX_SG];
124 	struct sginfo t_dst[MAX_SG];
125 	__le32 next;
126 	__le32 reserved[3];
127 } __packed __aligned(8);
128 
129 /*
130  * struct sun8i_ce_flow - Information used by each flow
131  * @engine:	ptr to the crypto_engine for this flow
132  * @bounce_iv:	buffer which contain the IV
133  * @ivlen:	size of bounce_iv
134  * @keylen:	keylen for this flow operation
135  * @complete:	completion for the current task on this flow
136  * @status:	set to 1 by interrupt if task is done
137  * @method:	current method for flow
138  * @op_dir:	direction (encrypt vs decrypt) of this flow
139  * @op_mode:	op_mode for this flow
140  * @t_phy:	Physical address of task
141  * @tl:		pointer to the current ce_task for this flow
142  * @stat_req:	number of request done by this flow
143  */
144 struct sun8i_ce_flow {
145 	struct crypto_engine *engine;
146 	void *bounce_iv;
147 	unsigned int ivlen;
148 	unsigned int keylen;
149 	struct completion complete;
150 	int status;
151 	u32 method;
152 	u32 op_dir;
153 	u32 op_mode;
154 	dma_addr_t t_phy;
155 	int timeout;
156 	struct ce_task *tl;
157 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
158 	unsigned long stat_req;
159 #endif
160 };
161 
162 /*
163  * struct sun8i_ce_dev - main container for all this driver information
164  * @base:	base address of CE
165  * @ceclks:	clocks used by CE
166  * @reset:	pointer to reset controller
167  * @dev:	the platform device
168  * @mlock:	Control access to device registers
169  * @chanlist:	array of all flow
170  * @flow:	flow to use in next request
171  * @variant:	pointer to variant specific data
172  * @dbgfs_dir:	Debugfs dentry for statistic directory
173  * @dbgfs_stats: Debugfs dentry for statistic counters
174  */
175 struct sun8i_ce_dev {
176 	void __iomem *base;
177 	struct clk *ceclks[CE_MAX_CLOCKS];
178 	struct reset_control *reset;
179 	struct device *dev;
180 	struct mutex mlock;
181 	struct sun8i_ce_flow *chanlist;
182 	atomic_t flow;
183 	const struct ce_variant *variant;
184 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
185 	struct dentry *dbgfs_dir;
186 	struct dentry *dbgfs_stats;
187 #endif
188 };
189 
190 /*
191  * struct sun8i_cipher_req_ctx - context for a skcipher request
192  * @op_dir:	direction (encrypt vs decrypt) for this request
193  * @flow:	the flow to use for this request
194  */
195 struct sun8i_cipher_req_ctx {
196 	u32 op_dir;
197 	int flow;
198 };
199 
200 /*
201  * struct sun8i_cipher_tfm_ctx - context for a skcipher TFM
202  * @enginectx:		crypto_engine used by this TFM
203  * @key:		pointer to key data
204  * @keylen:		len of the key
205  * @ce:			pointer to the private data of driver handling this TFM
206  * @fallback_tfm:	pointer to the fallback TFM
207  */
208 struct sun8i_cipher_tfm_ctx {
209 	struct crypto_engine_ctx enginectx;
210 	u32 *key;
211 	u32 keylen;
212 	struct sun8i_ce_dev *ce;
213 	struct crypto_sync_skcipher *fallback_tfm;
214 };
215 
216 /*
217  * struct sun8i_ce_alg_template - crypto_alg template
218  * @type:		the CRYPTO_ALG_TYPE for this template
219  * @ce_algo_id:		the CE_ID for this template
220  * @ce_blockmode:	the type of block operation CE_ID
221  * @ce:			pointer to the sun8i_ce_dev structure associated with
222  *			this template
223  * @alg:		one of sub struct must be used
224  * @stat_req:		number of request done on this template
225  * @stat_fb:		total of all data len done on this template
226  */
227 struct sun8i_ce_alg_template {
228 	u32 type;
229 	u32 ce_algo_id;
230 	u32 ce_blockmode;
231 	struct sun8i_ce_dev *ce;
232 	union {
233 		struct skcipher_alg skcipher;
234 	} alg;
235 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
236 	unsigned long stat_req;
237 	unsigned long stat_fb;
238 #endif
239 };
240 
241 int sun8i_ce_enqueue(struct crypto_async_request *areq, u32 type);
242 
243 int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
244 			unsigned int keylen);
245 int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,
246 			 unsigned int keylen);
247 int sun8i_ce_cipher_init(struct crypto_tfm *tfm);
248 void sun8i_ce_cipher_exit(struct crypto_tfm *tfm);
249 int sun8i_ce_skdecrypt(struct skcipher_request *areq);
250 int sun8i_ce_skencrypt(struct skcipher_request *areq);
251 
252 int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce);
253 
254 int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name);
255