1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * sun8i-ss.h - hardware cryptographic offloader for
4  * Allwinner A80/A83T 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 #define SS_ENCRYPTION		0
17 #define SS_DECRYPTION		BIT(6)
18 
19 #define SS_ALG_AES		0
20 #define SS_ALG_DES		(1 << 2)
21 #define SS_ALG_3DES		(2 << 2)
22 
23 #define SS_CTL_REG		0x00
24 #define SS_INT_CTL_REG		0x04
25 #define SS_INT_STA_REG		0x08
26 #define SS_KEY_ADR_REG		0x10
27 #define SS_IV_ADR_REG		0x18
28 #define SS_SRC_ADR_REG		0x20
29 #define SS_DST_ADR_REG		0x28
30 #define SS_LEN_ADR_REG		0x30
31 
32 #define SS_ID_NOTSUPP		0xFF
33 
34 #define SS_ID_CIPHER_AES	0
35 #define SS_ID_CIPHER_DES	1
36 #define SS_ID_CIPHER_DES3	2
37 #define SS_ID_CIPHER_MAX	3
38 
39 #define SS_ID_OP_ECB	0
40 #define SS_ID_OP_CBC	1
41 #define SS_ID_OP_MAX	2
42 
43 #define SS_AES_128BITS 0
44 #define SS_AES_192BITS 1
45 #define SS_AES_256BITS 2
46 
47 #define SS_OP_ECB	0
48 #define SS_OP_CBC	(1 << 13)
49 
50 #define SS_FLOW0	BIT(30)
51 #define SS_FLOW1	BIT(31)
52 
53 #define MAX_SG 8
54 
55 #define MAXFLOW 2
56 
57 #define SS_MAX_CLOCKS 2
58 
59 #define SS_DIE_ID_SHIFT	20
60 #define SS_DIE_ID_MASK	0x07
61 
62 /*
63  * struct ss_clock - Describe clocks used by sun8i-ss
64  * @name:       Name of clock needed by this variant
65  * @freq:       Frequency to set for each clock
66  * @max_freq:   Maximum frequency for each clock
67  */
68 struct ss_clock {
69 	const char *name;
70 	unsigned long freq;
71 	unsigned long max_freq;
72 };
73 
74 /*
75  * struct ss_variant - Describe SS capability for each variant hardware
76  * @alg_cipher:	list of supported ciphers. for each SS_ID_ this will give the
77  *              coresponding SS_ALG_XXX value
78  * @op_mode:	list of supported block modes
79  * @ss_clks!	list of clock needed by this variant
80  */
81 struct ss_variant {
82 	char alg_cipher[SS_ID_CIPHER_MAX];
83 	u32 op_mode[SS_ID_OP_MAX];
84 	struct ss_clock ss_clks[SS_MAX_CLOCKS];
85 };
86 
87 struct sginfo {
88 	u32 addr;
89 	u32 len;
90 };
91 
92 /*
93  * struct sun8i_ss_flow - Information used by each flow
94  * @engine:	ptr to the crypto_engine for this flow
95  * @complete:	completion for the current task on this flow
96  * @status:	set to 1 by interrupt if task is done
97  * @stat_req:	number of request done by this flow
98  */
99 struct sun8i_ss_flow {
100 	struct crypto_engine *engine;
101 	struct completion complete;
102 	int status;
103 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
104 	unsigned long stat_req;
105 #endif
106 };
107 
108 /*
109  * struct sun8i_ss_dev - main container for all this driver information
110  * @base:	base address of SS
111  * @ssclks:	clocks used by SS
112  * @reset:	pointer to reset controller
113  * @dev:	the platform device
114  * @mlock:	Control access to device registers
115  * @flows:	array of all flow
116  * @flow:	flow to use in next request
117  * @variant:	pointer to variant specific data
118  * @dbgfs_dir:	Debugfs dentry for statistic directory
119  * @dbgfs_stats: Debugfs dentry for statistic counters
120  */
121 struct sun8i_ss_dev {
122 	void __iomem *base;
123 	struct clk *ssclks[SS_MAX_CLOCKS];
124 	struct reset_control *reset;
125 	struct device *dev;
126 	struct mutex mlock;
127 	struct sun8i_ss_flow *flows;
128 	atomic_t flow;
129 	const struct ss_variant *variant;
130 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
131 	struct dentry *dbgfs_dir;
132 	struct dentry *dbgfs_stats;
133 #endif
134 };
135 
136 /*
137  * struct sun8i_cipher_req_ctx - context for a skcipher request
138  * @t_src:	list of mapped SGs with their size
139  * @t_dst:	list of mapped SGs with their size
140  * @p_key:	DMA address of the key
141  * @p_iv:	DMA address of the IV
142  * @method:	current algorithm for this request
143  * @op_mode:	op_mode for this request
144  * @op_dir:	direction (encrypt vs decrypt) for this request
145  * @flow:	the flow to use for this request
146  * @ivlen:	size of biv
147  * @keylen:	keylen for this request
148  * @biv:	buffer which contain the IV
149  */
150 struct sun8i_cipher_req_ctx {
151 	struct sginfo t_src[MAX_SG];
152 	struct sginfo t_dst[MAX_SG];
153 	u32 p_key;
154 	u32 p_iv;
155 	u32 method;
156 	u32 op_mode;
157 	u32 op_dir;
158 	int flow;
159 	unsigned int ivlen;
160 	unsigned int keylen;
161 	void *biv;
162 };
163 
164 /*
165  * struct sun8i_cipher_tfm_ctx - context for a skcipher TFM
166  * @enginectx:		crypto_engine used by this TFM
167  * @key:		pointer to key data
168  * @keylen:		len of the key
169  * @ss:			pointer to the private data of driver handling this TFM
170  * @fallback_tfm:	pointer to the fallback TFM
171  */
172 struct sun8i_cipher_tfm_ctx {
173 	struct crypto_engine_ctx enginectx;
174 	u32 *key;
175 	u32 keylen;
176 	struct sun8i_ss_dev *ss;
177 	struct crypto_sync_skcipher *fallback_tfm;
178 };
179 
180 /*
181  * struct sun8i_ss_alg_template - crypto_alg template
182  * @type:		the CRYPTO_ALG_TYPE for this template
183  * @ss_algo_id:		the SS_ID for this template
184  * @ss_blockmode:	the type of block operation SS_ID
185  * @ss:			pointer to the sun8i_ss_dev structure associated with
186  *			this template
187  * @alg:		one of sub struct must be used
188  * @stat_req:		number of request done on this template
189  * @stat_fb:		number of request which has fallbacked
190  */
191 struct sun8i_ss_alg_template {
192 	u32 type;
193 	u32 ss_algo_id;
194 	u32 ss_blockmode;
195 	struct sun8i_ss_dev *ss;
196 	union {
197 		struct skcipher_alg skcipher;
198 	} alg;
199 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
200 	unsigned long stat_req;
201 	unsigned long stat_fb;
202 #endif
203 };
204 
205 int sun8i_ss_enqueue(struct crypto_async_request *areq, u32 type);
206 
207 int sun8i_ss_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
208 			unsigned int keylen);
209 int sun8i_ss_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,
210 			 unsigned int keylen);
211 int sun8i_ss_cipher_init(struct crypto_tfm *tfm);
212 void sun8i_ss_cipher_exit(struct crypto_tfm *tfm);
213 int sun8i_ss_skdecrypt(struct skcipher_request *areq);
214 int sun8i_ss_skencrypt(struct skcipher_request *areq);
215 
216 int sun8i_ss_get_engine_number(struct sun8i_ss_dev *ss);
217 
218 int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx, const char *name);
219