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 * @complete: completion for the current task on this flow 135 * @status: set to 1 by interrupt if task is done 136 * @t_phy: Physical address of task 137 * @tl: pointer to the current ce_task for this flow 138 * @stat_req: number of request done by this flow 139 */ 140 struct sun8i_ce_flow { 141 struct crypto_engine *engine; 142 void *bounce_iv; 143 unsigned int ivlen; 144 struct completion complete; 145 int status; 146 dma_addr_t t_phy; 147 int timeout; 148 struct ce_task *tl; 149 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG 150 unsigned long stat_req; 151 #endif 152 }; 153 154 /* 155 * struct sun8i_ce_dev - main container for all this driver information 156 * @base: base address of CE 157 * @ceclks: clocks used by CE 158 * @reset: pointer to reset controller 159 * @dev: the platform device 160 * @mlock: Control access to device registers 161 * @chanlist: array of all flow 162 * @flow: flow to use in next request 163 * @variant: pointer to variant specific data 164 * @dbgfs_dir: Debugfs dentry for statistic directory 165 * @dbgfs_stats: Debugfs dentry for statistic counters 166 */ 167 struct sun8i_ce_dev { 168 void __iomem *base; 169 struct clk *ceclks[CE_MAX_CLOCKS]; 170 struct reset_control *reset; 171 struct device *dev; 172 struct mutex mlock; 173 struct sun8i_ce_flow *chanlist; 174 atomic_t flow; 175 const struct ce_variant *variant; 176 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG 177 struct dentry *dbgfs_dir; 178 struct dentry *dbgfs_stats; 179 #endif 180 }; 181 182 /* 183 * struct sun8i_cipher_req_ctx - context for a skcipher request 184 * @op_dir: direction (encrypt vs decrypt) for this request 185 * @flow: the flow to use for this request 186 * @fallback_req: request struct for invoking the fallback skcipher TFM 187 */ 188 struct sun8i_cipher_req_ctx { 189 u32 op_dir; 190 int flow; 191 struct skcipher_request fallback_req; // keep at the end 192 }; 193 194 /* 195 * struct sun8i_cipher_tfm_ctx - context for a skcipher TFM 196 * @enginectx: crypto_engine used by this TFM 197 * @key: pointer to key data 198 * @keylen: len of the key 199 * @ce: pointer to the private data of driver handling this TFM 200 * @fallback_tfm: pointer to the fallback TFM 201 */ 202 struct sun8i_cipher_tfm_ctx { 203 struct crypto_engine_ctx enginectx; 204 u32 *key; 205 u32 keylen; 206 struct sun8i_ce_dev *ce; 207 struct crypto_skcipher *fallback_tfm; 208 }; 209 210 /* 211 * struct sun8i_ce_alg_template - crypto_alg template 212 * @type: the CRYPTO_ALG_TYPE for this template 213 * @ce_algo_id: the CE_ID for this template 214 * @ce_blockmode: the type of block operation CE_ID 215 * @ce: pointer to the sun8i_ce_dev structure associated with 216 * this template 217 * @alg: one of sub struct must be used 218 * @stat_req: number of request done on this template 219 * @stat_fb: number of request which has fallbacked 220 */ 221 struct sun8i_ce_alg_template { 222 u32 type; 223 u32 ce_algo_id; 224 u32 ce_blockmode; 225 struct sun8i_ce_dev *ce; 226 union { 227 struct skcipher_alg skcipher; 228 } alg; 229 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG 230 unsigned long stat_req; 231 unsigned long stat_fb; 232 #endif 233 }; 234 235 int sun8i_ce_enqueue(struct crypto_async_request *areq, u32 type); 236 237 int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, 238 unsigned int keylen); 239 int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, const u8 *key, 240 unsigned int keylen); 241 int sun8i_ce_cipher_init(struct crypto_tfm *tfm); 242 void sun8i_ce_cipher_exit(struct crypto_tfm *tfm); 243 int sun8i_ce_skdecrypt(struct skcipher_request *areq); 244 int sun8i_ce_skencrypt(struct skcipher_request *areq); 245 246 int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce); 247 248 int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name); 249