Commit | Line | Data |
---|---|---|
049359d6 JH |
1 | /** |
2 | * AMCC SoC PPC4xx Crypto Driver | |
3 | * | |
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | |
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * This is the header file for AMCC Crypto offload Linux device driver for | |
18 | * use with Linux CryptoAPI. | |
19 | ||
20 | */ | |
21 | ||
22 | #ifndef __CRYPTO4XX_CORE_H__ | |
23 | #define __CRYPTO4XX_CORE_H__ | |
24 | ||
4dc10c01 | 25 | #include <crypto/internal/hash.h> |
9e0a0b3a CL |
26 | #include "crypto4xx_reg_def.h" |
27 | #include "crypto4xx_sa.h" | |
4dc10c01 | 28 | |
5343e674 CL |
29 | #define MODULE_NAME "crypto4xx" |
30 | ||
049359d6 JH |
31 | #define PPC460SX_SDR0_SRST 0x201 |
32 | #define PPC405EX_SDR0_SRST 0x200 | |
33 | #define PPC460EX_SDR0_SRST 0x201 | |
34 | #define PPC460EX_CE_RESET 0x08000000 | |
35 | #define PPC460SX_CE_RESET 0x20000000 | |
36 | #define PPC405EX_CE_RESET 0x00000008 | |
37 | ||
38 | #define CRYPTO4XX_CRYPTO_PRIORITY 300 | |
778f81d6 CL |
39 | #define PPC4XX_NUM_PD 256 |
40 | #define PPC4XX_LAST_PD (PPC4XX_NUM_PD - 1) | |
049359d6 | 41 | #define PPC4XX_NUM_GD 1024 |
778f81d6 CL |
42 | #define PPC4XX_LAST_GD (PPC4XX_NUM_GD - 1) |
43 | #define PPC4XX_NUM_SD 256 | |
44 | #define PPC4XX_LAST_SD (PPC4XX_NUM_SD - 1) | |
049359d6 JH |
45 | #define PPC4XX_SD_BUFFER_SIZE 2048 |
46 | ||
8ef8d195 CL |
47 | #define PD_ENTRY_BUSY BIT(1) |
48 | #define PD_ENTRY_INUSE BIT(0) | |
049359d6 JH |
49 | #define PD_ENTRY_FREE 0 |
50 | #define ERING_WAS_FULL 0xffffffff | |
51 | ||
52 | struct crypto4xx_device; | |
53 | ||
9e0a0b3a CL |
54 | union shadow_sa_buf { |
55 | struct dynamic_sa_ctl sa; | |
56 | ||
57 | /* alloc 256 bytes which is enough for any kind of dynamic sa */ | |
58 | u8 buf[256]; | |
59 | } __packed; | |
60 | ||
049359d6 JH |
61 | struct pd_uinfo { |
62 | struct crypto4xx_device *dev; | |
63 | u32 state; | |
64 | u32 using_sd; | |
65 | u32 first_gd; /* first gather discriptor | |
66 | used by this packet */ | |
67 | u32 num_gd; /* number of gather discriptor | |
68 | used by this packet */ | |
69 | u32 first_sd; /* first scatter discriptor | |
70 | used by this packet */ | |
71 | u32 num_sd; /* number of scatter discriptors | |
72 | used by this packet */ | |
9e0a0b3a | 73 | struct dynamic_sa_ctl *sa_va; /* shadow sa */ |
9e0a0b3a | 74 | struct sa_state_record *sr_va; /* state record for shadow sa */ |
049359d6 JH |
75 | u32 sr_pa; |
76 | struct scatterlist *dest_va; | |
77 | struct crypto_async_request *async_req; /* base crypto request | |
78 | for this packet */ | |
79 | }; | |
80 | ||
81 | struct crypto4xx_device { | |
82 | struct crypto4xx_core_device *core_dev; | |
83 | char *name; | |
049359d6 | 84 | void __iomem *ce_base; |
5343e674 | 85 | void __iomem *trng_base; |
049359d6 | 86 | |
9e0a0b3a CL |
87 | struct ce_pd *pdr; /* base address of packet descriptor ring */ |
88 | dma_addr_t pdr_pa; /* physical address of pdr_base_register */ | |
89 | struct ce_gd *gdr; /* gather descriptor ring */ | |
90 | dma_addr_t gdr_pa; /* physical address of gdr_base_register */ | |
91 | struct ce_sd *sdr; /* scatter descriptor ring */ | |
92 | dma_addr_t sdr_pa; /* physical address of sdr_base_register */ | |
049359d6 JH |
93 | void *scatter_buffer_va; |
94 | dma_addr_t scatter_buffer_pa; | |
049359d6 | 95 | |
9e0a0b3a | 96 | union shadow_sa_buf *shadow_sa_pool; |
049359d6 | 97 | dma_addr_t shadow_sa_pool_pa; |
9e0a0b3a | 98 | struct sa_state_record *shadow_sr_pool; |
049359d6 JH |
99 | dma_addr_t shadow_sr_pool_pa; |
100 | u32 pdr_tail; | |
101 | u32 pdr_head; | |
102 | u32 gdr_tail; | |
103 | u32 gdr_head; | |
104 | u32 sdr_tail; | |
105 | u32 sdr_head; | |
9e0a0b3a | 106 | struct pd_uinfo *pdr_uinfo; |
049359d6 JH |
107 | struct list_head alg_list; /* List of algorithm supported |
108 | by this device */ | |
109 | }; | |
110 | ||
111 | struct crypto4xx_core_device { | |
112 | struct device *device; | |
2dc11581 | 113 | struct platform_device *ofdev; |
049359d6 | 114 | struct crypto4xx_device *dev; |
5343e674 | 115 | struct hwrng *trng; |
049359d6 JH |
116 | u32 int_status; |
117 | u32 irq; | |
118 | struct tasklet_struct tasklet; | |
119 | spinlock_t lock; | |
120 | }; | |
121 | ||
122 | struct crypto4xx_ctx { | |
123 | struct crypto4xx_device *dev; | |
9e0a0b3a | 124 | struct dynamic_sa_ctl *sa_in; |
9e0a0b3a | 125 | struct dynamic_sa_ctl *sa_out; |
2f77690d | 126 | __le32 iv_nonce; |
049359d6 | 127 | u32 sa_len; |
049359d6 JH |
128 | }; |
129 | ||
4dc10c01 HX |
130 | struct crypto4xx_alg_common { |
131 | u32 type; | |
132 | union { | |
133 | struct crypto_alg cipher; | |
134 | struct ahash_alg hash; | |
135 | } u; | |
136 | }; | |
137 | ||
049359d6 JH |
138 | struct crypto4xx_alg { |
139 | struct list_head entry; | |
4dc10c01 | 140 | struct crypto4xx_alg_common alg; |
049359d6 JH |
141 | struct crypto4xx_device *dev; |
142 | }; | |
143 | ||
4dc10c01 HX |
144 | static inline struct crypto4xx_alg *crypto_alg_to_crypto4xx_alg( |
145 | struct crypto_alg *x) | |
146 | { | |
147 | switch (x->cra_flags & CRYPTO_ALG_TYPE_MASK) { | |
148 | case CRYPTO_ALG_TYPE_AHASH: | |
149 | return container_of(__crypto_ahash_alg(x), | |
150 | struct crypto4xx_alg, alg.u.hash); | |
151 | } | |
152 | ||
153 | return container_of(x, struct crypto4xx_alg, alg.u.cipher); | |
154 | } | |
049359d6 | 155 | |
886c251f CL |
156 | int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size); |
157 | void crypto4xx_free_sa(struct crypto4xx_ctx *ctx); | |
158 | void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx); | |
4865b122 | 159 | int crypto4xx_build_pd(struct crypto_async_request *req, |
886c251f CL |
160 | struct crypto4xx_ctx *ctx, |
161 | struct scatterlist *src, | |
162 | struct scatterlist *dst, | |
cd4dcd6d CL |
163 | const unsigned int datalen, |
164 | const __le32 *iv, const u32 iv_len, | |
165 | const struct dynamic_sa_ctl *sa, | |
166 | const unsigned int sa_len); | |
886c251f CL |
167 | int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher, |
168 | const u8 *key, unsigned int keylen); | |
f2a13e7c CL |
169 | int crypto4xx_setkey_aes_cfb(struct crypto_ablkcipher *cipher, |
170 | const u8 *key, unsigned int keylen); | |
171 | int crypto4xx_setkey_aes_ecb(struct crypto_ablkcipher *cipher, | |
172 | const u8 *key, unsigned int keylen); | |
173 | int crypto4xx_setkey_aes_ofb(struct crypto_ablkcipher *cipher, | |
174 | const u8 *key, unsigned int keylen); | |
175 | int crypto4xx_setkey_rfc3686(struct crypto_ablkcipher *cipher, | |
176 | const u8 *key, unsigned int keylen); | |
886c251f CL |
177 | int crypto4xx_encrypt(struct ablkcipher_request *req); |
178 | int crypto4xx_decrypt(struct ablkcipher_request *req); | |
f2a13e7c CL |
179 | int crypto4xx_rfc3686_encrypt(struct ablkcipher_request *req); |
180 | int crypto4xx_rfc3686_decrypt(struct ablkcipher_request *req); | |
886c251f CL |
181 | int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm); |
182 | int crypto4xx_hash_digest(struct ahash_request *req); | |
183 | int crypto4xx_hash_final(struct ahash_request *req); | |
184 | int crypto4xx_hash_update(struct ahash_request *req); | |
185 | int crypto4xx_hash_init(struct ahash_request *req); | |
4865b122 CL |
186 | |
187 | /** | |
188 | * Note: Only use this function to copy items that is word aligned. | |
189 | */ | |
190 | static inline void crypto4xx_memcpy_swab32(u32 *dst, const void *buf, | |
191 | size_t len) | |
192 | { | |
193 | for (; len >= 4; buf += 4, len -= 4) | |
194 | *dst++ = __swab32p((u32 *) buf); | |
195 | ||
196 | if (len) { | |
197 | const u8 *tmp = (u8 *)buf; | |
198 | ||
199 | switch (len) { | |
200 | case 3: | |
201 | *dst = (tmp[2] << 16) | | |
202 | (tmp[1] << 8) | | |
203 | tmp[0]; | |
204 | break; | |
205 | case 2: | |
206 | *dst = (tmp[1] << 8) | | |
207 | tmp[0]; | |
208 | break; | |
209 | case 1: | |
210 | *dst = tmp[0]; | |
211 | break; | |
212 | default: | |
213 | break; | |
214 | } | |
215 | } | |
216 | } | |
217 | ||
218 | static inline void crypto4xx_memcpy_from_le32(u32 *dst, const void *buf, | |
219 | size_t len) | |
220 | { | |
221 | crypto4xx_memcpy_swab32(dst, buf, len); | |
222 | } | |
223 | ||
224 | static inline void crypto4xx_memcpy_to_le32(__le32 *dst, const void *buf, | |
225 | size_t len) | |
226 | { | |
227 | crypto4xx_memcpy_swab32((u32 *)dst, buf, len); | |
228 | } | |
049359d6 | 229 | #endif |