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