aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Iles <jamie@jamieiles.com>2011-02-21 00:43:21 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2011-02-21 06:42:40 -0500
commitce92136843cb6e14aba5fd7bc4e88dbe71e70c5a (patch)
tree5ff99cc504181f37279f388bd502e624d101aa73
parentbd1f2996b44a1c8bde76a6fecd10f36b6eb948d7 (diff)
crypto: picoxcell - add support for the picoxcell crypto engines
Picochip picoXcell devices have two crypto engines, one targeted at IPSEC offload and the other at WCDMA layer 2 ciphering. Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/Kconfig17
-rw-r--r--drivers/crypto/Makefile2
-rw-r--r--drivers/crypto/picoxcell_crypto.c1867
-rw-r--r--drivers/crypto/picoxcell_crypto_regs.h128
4 files changed, 2013 insertions, 1 deletions
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index eab2cf7a0269..e54185223c8c 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -252,4 +252,21 @@ config CRYPTO_DEV_OMAP_AES
252 OMAP processors have AES module accelerator. Select this if you 252 OMAP processors have AES module accelerator. Select this if you
253 want to use the OMAP module for AES algorithms. 253 want to use the OMAP module for AES algorithms.
254 254
255config CRYPTO_DEV_PICOXCELL
256 tristate "Support for picoXcell IPSEC and Layer2 crypto engines"
257 depends on ARCH_PICOXCELL
258 select CRYPTO_AES
259 select CRYPTO_AUTHENC
260 select CRYPTO_ALGAPI
261 select CRYPTO_DES
262 select CRYPTO_CBC
263 select CRYPTO_ECB
264 select CRYPTO_SEQIV
265 help
266 This option enables support for the hardware offload engines in the
267 Picochip picoXcell SoC devices. Select this for IPSEC ESP offload
268 and for 3gpp Layer 2 ciphering support.
269
270 Saying m here will build a module named pipcoxcell_crypto.
271
255endif # CRYPTO_HW 272endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 256697330a41..5203e34248d7 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
10obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ 10obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
11obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o 11obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
12obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o 12obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
13 13obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c
new file mode 100644
index 000000000000..b092d0a65837
--- /dev/null
+++ b/drivers/crypto/picoxcell_crypto.c
@@ -0,0 +1,1867 @@
1/*
2 * Copyright (c) 2010-2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#include <crypto/aead.h>
19#include <crypto/aes.h>
20#include <crypto/algapi.h>
21#include <crypto/authenc.h>
22#include <crypto/des.h>
23#include <crypto/md5.h>
24#include <crypto/sha.h>
25#include <crypto/internal/skcipher.h>
26#include <linux/clk.h>
27#include <linux/crypto.h>
28#include <linux/delay.h>
29#include <linux/dma-mapping.h>
30#include <linux/dmapool.h>
31#include <linux/err.h>
32#include <linux/init.h>
33#include <linux/interrupt.h>
34#include <linux/io.h>
35#include <linux/list.h>
36#include <linux/module.h>
37#include <linux/platform_device.h>
38#include <linux/pm.h>
39#include <linux/rtnetlink.h>
40#include <linux/scatterlist.h>
41#include <linux/sched.h>
42#include <linux/slab.h>
43#include <linux/timer.h>
44
45#include "picoxcell_crypto_regs.h"
46
47/*
48 * The threshold for the number of entries in the CMD FIFO available before
49 * the CMD0_CNT interrupt is raised. Increasing this value will reduce the
50 * number of interrupts raised to the CPU.
51 */
52#define CMD0_IRQ_THRESHOLD 1
53
54/*
55 * The timeout period (in jiffies) for a PDU. When the the number of PDUs in
56 * flight is greater than the STAT_IRQ_THRESHOLD or 0 the timer is disabled.
57 * When there are packets in flight but lower than the threshold, we enable
58 * the timer and at expiry, attempt to remove any processed packets from the
59 * queue and if there are still packets left, schedule the timer again.
60 */
61#define PACKET_TIMEOUT 1
62
63/* The priority to register each algorithm with. */
64#define SPACC_CRYPTO_ALG_PRIORITY 10000
65
66#define SPACC_CRYPTO_KASUMI_F8_KEY_LEN 16
67#define SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ 64
68#define SPACC_CRYPTO_IPSEC_HASH_PG_SZ 64
69#define SPACC_CRYPTO_IPSEC_MAX_CTXS 32
70#define SPACC_CRYPTO_IPSEC_FIFO_SZ 32
71#define SPACC_CRYPTO_L2_CIPHER_PG_SZ 64
72#define SPACC_CRYPTO_L2_HASH_PG_SZ 64
73#define SPACC_CRYPTO_L2_MAX_CTXS 128
74#define SPACC_CRYPTO_L2_FIFO_SZ 128
75
76#define MAX_DDT_LEN 16
77
78/* DDT format. This must match the hardware DDT format exactly. */
79struct spacc_ddt {
80 dma_addr_t p;
81 u32 len;
82};
83
84/*
85 * Asynchronous crypto request structure.
86 *
87 * This structure defines a request that is either queued for processing or
88 * being processed.
89 */
90struct spacc_req {
91 struct list_head list;
92 struct spacc_engine *engine;
93 struct crypto_async_request *req;
94 int result;
95 bool is_encrypt;
96 unsigned ctx_id;
97 dma_addr_t src_addr, dst_addr;
98 struct spacc_ddt *src_ddt, *dst_ddt;
99 void (*complete)(struct spacc_req *req);
100
101 /* AEAD specific bits. */
102 u8 *giv;
103 size_t giv_len;
104 dma_addr_t giv_pa;
105};
106
107struct spacc_engine {
108 void __iomem *regs;
109 struct list_head pending;
110 int next_ctx;
111 spinlock_t hw_lock;
112 int in_flight;
113 struct list_head completed;
114 struct list_head in_progress;
115 struct tasklet_struct complete;
116 unsigned long fifo_sz;
117 void __iomem *cipher_ctx_base;
118 void __iomem *hash_key_base;
119 struct spacc_alg *algs;
120 unsigned num_algs;
121 struct list_head registered_algs;
122 size_t cipher_pg_sz;
123 size_t hash_pg_sz;
124 const char *name;
125 struct clk *clk;
126 struct device *dev;
127 unsigned max_ctxs;
128 struct timer_list packet_timeout;
129 unsigned stat_irq_thresh;
130 struct dma_pool *req_pool;
131};
132
133/* Algorithm type mask. */
134#define SPACC_CRYPTO_ALG_MASK 0x7
135
136/* SPACC definition of a crypto algorithm. */
137struct spacc_alg {
138 unsigned long ctrl_default;
139 unsigned long type;
140 struct crypto_alg alg;
141 struct spacc_engine *engine;
142 struct list_head entry;
143 int key_offs;
144 int iv_offs;
145};
146
147/* Generic context structure for any algorithm type. */
148struct spacc_generic_ctx {
149 struct spacc_engine *engine;
150 int flags;
151 int key_offs;
152 int iv_offs;
153};
154
155/* Block cipher context. */
156struct spacc_ablk_ctx {
157 struct spacc_generic_ctx generic;
158 u8 key[AES_MAX_KEY_SIZE];
159 u8 key_len;
160 /*
161 * The fallback cipher. If the operation can't be done in hardware,
162 * fallback to a software version.
163 */
164 struct crypto_ablkcipher *sw_cipher;
165};
166
167/* AEAD cipher context. */
168struct spacc_aead_ctx {
169 struct spacc_generic_ctx generic;
170 u8 cipher_key[AES_MAX_KEY_SIZE];
171 u8 hash_ctx[SPACC_CRYPTO_IPSEC_HASH_PG_SZ];
172 u8 cipher_key_len;
173 u8 hash_key_len;
174 struct crypto_aead *sw_cipher;
175 size_t auth_size;
176 u8 salt[AES_BLOCK_SIZE];
177};
178
179static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg)
180{
181 return alg ? container_of(alg, struct spacc_alg, alg) : NULL;
182}
183
184static inline int spacc_fifo_cmd_full(struct spacc_engine *engine)
185{
186 u32 fifo_stat = readl(engine->regs + SPA_FIFO_STAT_REG_OFFSET);
187
188 return fifo_stat & SPA_FIFO_CMD_FULL;
189}
190
191/*
192 * Given a cipher context, and a context number, get the base address of the
193 * context page.
194 *
195 * Returns the address of the context page where the key/context may
196 * be written.
197 */
198static inline void __iomem *spacc_ctx_page_addr(struct spacc_generic_ctx *ctx,
199 unsigned indx,
200 bool is_cipher_ctx)
201{
202 return is_cipher_ctx ? ctx->engine->cipher_ctx_base +
203 (indx * ctx->engine->cipher_pg_sz) :
204 ctx->engine->hash_key_base + (indx * ctx->engine->hash_pg_sz);
205}
206
207/* The context pages can only be written with 32-bit accesses. */
208static inline void memcpy_toio32(u32 __iomem *dst, const void *src,
209 unsigned count)
210{
211 const u32 *src32 = (const u32 *) src;
212
213 while (count--)
214 writel(*src32++, dst++);
215}
216
217static void spacc_cipher_write_ctx(struct spacc_generic_ctx *ctx,
218 void __iomem *page_addr, const u8 *key,
219 size_t key_len, const u8 *iv, size_t iv_len)
220{
221 void __iomem *key_ptr = page_addr + ctx->key_offs;
222 void __iomem *iv_ptr = page_addr + ctx->iv_offs;
223
224 memcpy_toio32(key_ptr, key, key_len / 4);
225 memcpy_toio32(iv_ptr, iv, iv_len / 4);
226}
227
228/*
229 * Load a context into the engines context memory.
230 *
231 * Returns the index of the context page where the context was loaded.
232 */
233static unsigned spacc_load_ctx(struct spacc_generic_ctx *ctx,
234 const u8 *ciph_key, size_t ciph_len,
235 const u8 *iv, size_t ivlen, const u8 *hash_key,
236 size_t hash_len)
237{
238 unsigned indx = ctx->engine->next_ctx++;
239 void __iomem *ciph_page_addr, *hash_page_addr;
240
241 ciph_page_addr = spacc_ctx_page_addr(ctx, indx, 1);
242 hash_page_addr = spacc_ctx_page_addr(ctx, indx, 0);
243
244 ctx->engine->next_ctx &= ctx->engine->fifo_sz - 1;
245 spacc_cipher_write_ctx(ctx, ciph_page_addr, ciph_key, ciph_len, iv,
246 ivlen);
247 writel(ciph_len | (indx << SPA_KEY_SZ_CTX_INDEX_OFFSET) |
248 (1 << SPA_KEY_SZ_CIPHER_OFFSET),
249 ctx->engine->regs + SPA_KEY_SZ_REG_OFFSET);
250
251 if (hash_key) {
252 memcpy_toio32(hash_page_addr, hash_key, hash_len / 4);
253 writel(hash_len | (indx << SPA_KEY_SZ_CTX_INDEX_OFFSET),
254 ctx->engine->regs + SPA_KEY_SZ_REG_OFFSET);
255 }
256
257 return indx;
258}
259
260/* Count the number of scatterlist entries in a scatterlist. */
261static int sg_count(struct scatterlist *sg_list, int nbytes)
262{
263 struct scatterlist *sg = sg_list;
264 int sg_nents = 0;
265
266 while (nbytes > 0) {
267 ++sg_nents;
268 nbytes -= sg->length;
269 sg = sg_next(sg);
270 }
271
272 return sg_nents;
273}
274
275static inline void ddt_set(struct spacc_ddt *ddt, dma_addr_t phys, size_t len)
276{
277 ddt->p = phys;
278 ddt->len = len;
279}
280
281/*
282 * Take a crypto request and scatterlists for the data and turn them into DDTs
283 * for passing to the crypto engines. This also DMA maps the data so that the
284 * crypto engines can DMA to/from them.
285 */
286static struct spacc_ddt *spacc_sg_to_ddt(struct spacc_engine *engine,
287 struct scatterlist *payload,
288 unsigned nbytes,
289 enum dma_data_direction dir,
290 dma_addr_t *ddt_phys)
291{
292 unsigned nents, mapped_ents;
293 struct scatterlist *cur;
294 struct spacc_ddt *ddt;
295 int i;
296
297 nents = sg_count(payload, nbytes);
298 mapped_ents = dma_map_sg(engine->dev, payload, nents, dir);
299
300 if (mapped_ents + 1 > MAX_DDT_LEN)
301 goto out;
302
303 ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, ddt_phys);
304 if (!ddt)
305 goto out;
306
307 for_each_sg(payload, cur, mapped_ents, i)
308 ddt_set(&ddt[i], sg_dma_address(cur), sg_dma_len(cur));
309 ddt_set(&ddt[mapped_ents], 0, 0);
310
311 return ddt;
312
313out:
314 dma_unmap_sg(engine->dev, payload, nents, dir);
315 return NULL;
316}
317
318static int spacc_aead_make_ddts(struct spacc_req *req, u8 *giv)
319{
320 struct aead_request *areq = container_of(req->req, struct aead_request,
321 base);
322 struct spacc_engine *engine = req->engine;
323 struct spacc_ddt *src_ddt, *dst_ddt;
324 unsigned ivsize = crypto_aead_ivsize(crypto_aead_reqtfm(areq));
325 unsigned nents = sg_count(areq->src, areq->cryptlen);
326 dma_addr_t iv_addr;
327 struct scatterlist *cur;
328 int i, dst_ents, src_ents, assoc_ents;
329 u8 *iv = giv ? giv : areq->iv;
330
331 src_ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, &req->src_addr);
332 if (!src_ddt)
333 return -ENOMEM;
334
335 dst_ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, &req->dst_addr);
336 if (!dst_ddt) {
337 dma_pool_free(engine->req_pool, src_ddt, req->src_addr);
338 return -ENOMEM;
339 }
340
341 req->src_ddt = src_ddt;
342 req->dst_ddt = dst_ddt;
343
344 assoc_ents = dma_map_sg(engine->dev, areq->assoc,
345 sg_count(areq->assoc, areq->assoclen), DMA_TO_DEVICE);
346 if (areq->src != areq->dst) {
347 src_ents = dma_map_sg(engine->dev, areq->src, nents,
348 DMA_TO_DEVICE);
349 dst_ents = dma_map_sg(engine->dev, areq->dst, nents,
350 DMA_FROM_DEVICE);
351 } else {
352 src_ents = dma_map_sg(engine->dev, areq->src, nents,
353 DMA_BIDIRECTIONAL);
354 dst_ents = 0;
355 }
356
357 /*
358 * Map the IV/GIV. For the GIV it needs to be bidirectional as it is
359 * formed by the crypto block and sent as the ESP IV for IPSEC.
360 */
361 iv_addr = dma_map_single(engine->dev, iv, ivsize,
362 giv ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE);
363 req->giv_pa = iv_addr;
364
365 /*
366 * Map the associated data. For decryption we don't copy the
367 * associated data.
368 */
369 for_each_sg(areq->assoc, cur, assoc_ents, i) {
370 ddt_set(src_ddt++, sg_dma_address(cur), sg_dma_len(cur));
371 if (req->is_encrypt)
372 ddt_set(dst_ddt++, sg_dma_address(cur),
373 sg_dma_len(cur));
374 }
375 ddt_set(src_ddt++, iv_addr, ivsize);
376
377 if (giv || req->is_encrypt)
378 ddt_set(dst_ddt++, iv_addr, ivsize);
379
380 /*
381 * Now map in the payload for the source and destination and terminate
382 * with the NULL pointers.
383 */
384 for_each_sg(areq->src, cur, src_ents, i) {
385 ddt_set(src_ddt++, sg_dma_address(cur), sg_dma_len(cur));
386 if (areq->src == areq->dst)
387 ddt_set(dst_ddt++, sg_dma_address(cur),
388 sg_dma_len(cur));
389 }
390
391 for_each_sg(areq->dst, cur, dst_ents, i)
392 ddt_set(dst_ddt++, sg_dma_address(cur),
393 sg_dma_len(cur));
394
395 ddt_set(src_ddt, 0, 0);
396 ddt_set(dst_ddt, 0, 0);
397
398 return 0;
399}
400
401static void spacc_aead_free_ddts(struct spacc_req *req)
402{
403 struct aead_request *areq = container_of(req->req, struct aead_request,
404 base);
405 struct spacc_alg *alg = to_spacc_alg(req->req->tfm->__crt_alg);
406 struct spacc_ablk_ctx *aead_ctx = crypto_tfm_ctx(req->req->tfm);
407 struct spacc_engine *engine = aead_ctx->generic.engine;
408 unsigned ivsize = alg->alg.cra_aead.ivsize;
409 unsigned nents = sg_count(areq->src, areq->cryptlen);
410
411 if (areq->src != areq->dst) {
412 dma_unmap_sg(engine->dev, areq->src, nents, DMA_TO_DEVICE);
413 dma_unmap_sg(engine->dev, areq->dst,
414 sg_count(areq->dst, areq->cryptlen),
415 DMA_FROM_DEVICE);
416 } else
417 dma_unmap_sg(engine->dev, areq->src, nents, DMA_BIDIRECTIONAL);
418
419 dma_unmap_sg(engine->dev, areq->assoc,
420 sg_count(areq->assoc, areq->assoclen), DMA_TO_DEVICE);
421
422 dma_unmap_single(engine->dev, req->giv_pa, ivsize, DMA_BIDIRECTIONAL);
423
424 dma_pool_free(engine->req_pool, req->src_ddt, req->src_addr);
425 dma_pool_free(engine->req_pool, req->dst_ddt, req->dst_addr);
426}
427
428static void spacc_free_ddt(struct spacc_req *req, struct spacc_ddt *ddt,
429 dma_addr_t ddt_addr, struct scatterlist *payload,
430 unsigned nbytes, enum dma_data_direction dir)
431{
432 unsigned nents = sg_count(payload, nbytes);
433
434 dma_unmap_sg(req->engine->dev, payload, nents, dir);
435 dma_pool_free(req->engine->req_pool, ddt, ddt_addr);
436}
437
438/*
439 * Set key for a DES operation in an AEAD cipher. This also performs weak key
440 * checking if required.
441 */
442static int spacc_aead_des_setkey(struct crypto_aead *aead, const u8 *key,
443 unsigned int len)
444{
445 struct crypto_tfm *tfm = crypto_aead_tfm(aead);
446 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
447 u32 tmp[DES_EXPKEY_WORDS];
448
449 if (unlikely(!des_ekey(tmp, key)) &&
450 (crypto_aead_get_flags(aead)) & CRYPTO_TFM_REQ_WEAK_KEY) {
451 tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
452 return -EINVAL;
453 }
454
455 memcpy(ctx->cipher_key, key, len);
456 ctx->cipher_key_len = len;
457
458 return 0;
459}
460
461/* Set the key for the AES block cipher component of the AEAD transform. */
462static int spacc_aead_aes_setkey(struct crypto_aead *aead, const u8 *key,
463 unsigned int len)
464{
465 struct crypto_tfm *tfm = crypto_aead_tfm(aead);
466 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
467
468 /*
469 * IPSec engine only supports 128 and 256 bit AES keys. If we get a
470 * request for any other size (192 bits) then we need to do a software
471 * fallback.
472 */
473 if (len != AES_KEYSIZE_128 && len != AES_KEYSIZE_256) {
474 /*
475 * Set the fallback transform to use the same request flags as
476 * the hardware transform.
477 */
478 ctx->sw_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
479 ctx->sw_cipher->base.crt_flags |=
480 tfm->crt_flags & CRYPTO_TFM_REQ_MASK;
481 return crypto_aead_setkey(ctx->sw_cipher, key, len);
482 }
483
484 memcpy(ctx->cipher_key, key, len);
485 ctx->cipher_key_len = len;
486
487 return 0;
488}
489
490static int spacc_aead_setkey(struct crypto_aead *tfm, const u8 *key,
491 unsigned int keylen)
492{
493 struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm);
494 struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg);
495 struct rtattr *rta = (void *)key;
496 struct crypto_authenc_key_param *param;
497 unsigned int authkeylen, enckeylen;
498 int err = -EINVAL;
499
500 if (!RTA_OK(rta, keylen))
501 goto badkey;
502
503 if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
504 goto badkey;
505
506 if (RTA_PAYLOAD(rta) < sizeof(*param))
507 goto badkey;
508
509 param = RTA_DATA(rta);
510 enckeylen = be32_to_cpu(param->enckeylen);
511
512 key += RTA_ALIGN(rta->rta_len);
513 keylen -= RTA_ALIGN(rta->rta_len);
514
515 if (keylen < enckeylen)
516 goto badkey;
517
518 authkeylen = keylen - enckeylen;
519
520 if (enckeylen > AES_MAX_KEY_SIZE)
521 goto badkey;
522
523 if ((alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
524 SPA_CTRL_CIPH_ALG_AES)
525 err = spacc_aead_aes_setkey(tfm, key + authkeylen, enckeylen);
526 else
527 err = spacc_aead_des_setkey(tfm, key + authkeylen, enckeylen);
528
529 if (err)
530 goto badkey;
531
532 memcpy(ctx->hash_ctx, key, authkeylen);
533 ctx->hash_key_len = authkeylen;
534
535 return 0;
536
537badkey:
538 crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
539 return -EINVAL;
540}
541
542static int spacc_aead_setauthsize(struct crypto_aead *tfm,
543 unsigned int authsize)
544{
545 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(crypto_aead_tfm(tfm));
546
547 ctx->auth_size = authsize;
548
549 return 0;
550}
551
552/*
553 * Check if an AEAD request requires a fallback operation. Some requests can't
554 * be completed in hardware because the hardware may not support certain key
555 * sizes. In these cases we need to complete the request in software.
556 */
557static int spacc_aead_need_fallback(struct spacc_req *req)
558{
559 struct aead_request *aead_req;
560 struct crypto_tfm *tfm = req->req->tfm;
561 struct crypto_alg *alg = req->req->tfm->__crt_alg;
562 struct spacc_alg *spacc_alg = to_spacc_alg(alg);
563 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
564
565 aead_req = container_of(req->req, struct aead_request, base);
566 /*
567 * If we have a non-supported key-length, then we need to do a
568 * software fallback.
569 */
570 if ((spacc_alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
571 SPA_CTRL_CIPH_ALG_AES &&
572 ctx->cipher_key_len != AES_KEYSIZE_128 &&
573 ctx->cipher_key_len != AES_KEYSIZE_256)
574 return 1;
575
576 return 0;
577}
578
579static int spacc_aead_do_fallback(struct aead_request *req, unsigned alg_type,
580 bool is_encrypt)
581{
582 struct crypto_tfm *old_tfm = crypto_aead_tfm(crypto_aead_reqtfm(req));
583 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(old_tfm);
584 int err;
585
586 if (ctx->sw_cipher) {
587 /*
588 * Change the request to use the software fallback transform,
589 * and once the ciphering has completed, put the old transform
590 * back into the request.
591 */
592 aead_request_set_tfm(req, ctx->sw_cipher);
593 err = is_encrypt ? crypto_aead_encrypt(req) :
594 crypto_aead_decrypt(req);
595 aead_request_set_tfm(req, __crypto_aead_cast(old_tfm));
596 } else
597 err = -EINVAL;
598
599 return err;
600}
601
602static void spacc_aead_complete(struct spacc_req *req)
603{
604 spacc_aead_free_ddts(req);
605 req->req->complete(req->req, req->result);
606}
607
608static int spacc_aead_submit(struct spacc_req *req)
609{
610 struct crypto_tfm *tfm = req->req->tfm;
611 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
612 struct crypto_alg *alg = req->req->tfm->__crt_alg;
613 struct spacc_alg *spacc_alg = to_spacc_alg(alg);
614 struct spacc_engine *engine = ctx->generic.engine;
615 u32 ctrl, proc_len, assoc_len;
616 struct aead_request *aead_req =
617 container_of(req->req, struct aead_request, base);
618
619 req->result = -EINPROGRESS;
620 req->ctx_id = spacc_load_ctx(&ctx->generic, ctx->cipher_key,
621 ctx->cipher_key_len, aead_req->iv, alg->cra_aead.ivsize,
622 ctx->hash_ctx, ctx->hash_key_len);
623
624 /* Set the source and destination DDT pointers. */
625 writel(req->src_addr, engine->regs + SPA_SRC_PTR_REG_OFFSET);
626 writel(req->dst_addr, engine->regs + SPA_DST_PTR_REG_OFFSET);
627 writel(0, engine->regs + SPA_OFFSET_REG_OFFSET);
628
629 assoc_len = aead_req->assoclen;
630 proc_len = aead_req->cryptlen + assoc_len;
631
632 /*
633 * If we aren't generating an IV, then we need to include the IV in the
634 * associated data so that it is included in the hash.
635 */
636 if (!req->giv) {
637 assoc_len += crypto_aead_ivsize(crypto_aead_reqtfm(aead_req));
638 proc_len += crypto_aead_ivsize(crypto_aead_reqtfm(aead_req));
639 } else
640 proc_len += req->giv_len;
641
642 /*
643 * If we are decrypting, we need to take the length of the ICV out of
644 * the processing length.
645 */
646 if (!req->is_encrypt)
647 proc_len -= ctx->auth_size;
648
649 writel(proc_len, engine->regs + SPA_PROC_LEN_REG_OFFSET);
650 writel(assoc_len, engine->regs + SPA_AAD_LEN_REG_OFFSET);
651 writel(ctx->auth_size, engine->regs + SPA_ICV_LEN_REG_OFFSET);
652 writel(0, engine->regs + SPA_ICV_OFFSET_REG_OFFSET);
653 writel(0, engine->regs + SPA_AUX_INFO_REG_OFFSET);
654
655 ctrl = spacc_alg->ctrl_default | (req->ctx_id << SPA_CTRL_CTX_IDX) |
656 (1 << SPA_CTRL_ICV_APPEND);
657 if (req->is_encrypt)
658 ctrl |= (1 << SPA_CTRL_ENCRYPT_IDX) | (1 << SPA_CTRL_AAD_COPY);
659 else
660 ctrl |= (1 << SPA_CTRL_KEY_EXP);
661
662 mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
663
664 writel(ctrl, engine->regs + SPA_CTRL_REG_OFFSET);
665
666 return -EINPROGRESS;
667}
668
669/*
670 * Setup an AEAD request for processing. This will configure the engine, load
671 * the context and then start the packet processing.
672 *
673 * @giv Pointer to destination address for a generated IV. If the
674 * request does not need to generate an IV then this should be set to NULL.
675 */
676static int spacc_aead_setup(struct aead_request *req, u8 *giv,
677 unsigned alg_type, bool is_encrypt)
678{
679 struct crypto_alg *alg = req->base.tfm->__crt_alg;
680 struct spacc_engine *engine = to_spacc_alg(alg)->engine;
681 struct spacc_req *dev_req = aead_request_ctx(req);
682 int err = -EINPROGRESS;
683 unsigned long flags;
684 unsigned ivsize = crypto_aead_ivsize(crypto_aead_reqtfm(req));
685
686 dev_req->giv = giv;
687 dev_req->giv_len = ivsize;
688 dev_req->req = &req->base;
689 dev_req->is_encrypt = is_encrypt;
690 dev_req->result = -EBUSY;
691 dev_req->engine = engine;
692 dev_req->complete = spacc_aead_complete;
693
694 if (unlikely(spacc_aead_need_fallback(dev_req)))
695 return spacc_aead_do_fallback(req, alg_type, is_encrypt);
696
697 spacc_aead_make_ddts(dev_req, dev_req->giv);
698
699 err = -EINPROGRESS;
700 spin_lock_irqsave(&engine->hw_lock, flags);
701 if (unlikely(spacc_fifo_cmd_full(engine))) {
702 if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
703 err = -EBUSY;
704 spin_unlock_irqrestore(&engine->hw_lock, flags);
705 goto out_free_ddts;
706 }
707 list_add_tail(&dev_req->list, &engine->pending);
708 } else {
709 ++engine->in_flight;
710 list_add_tail(&dev_req->list, &engine->in_progress);
711 spacc_aead_submit(dev_req);
712 }
713 spin_unlock_irqrestore(&engine->hw_lock, flags);
714
715 goto out;
716
717out_free_ddts:
718 spacc_aead_free_ddts(dev_req);
719out:
720 return err;
721}
722
723static int spacc_aead_encrypt(struct aead_request *req)
724{
725 struct crypto_aead *aead = crypto_aead_reqtfm(req);
726 struct crypto_tfm *tfm = crypto_aead_tfm(aead);
727 struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg);
728
729 return spacc_aead_setup(req, NULL, alg->type, 1);
730}
731
732static int spacc_aead_givencrypt(struct aead_givcrypt_request *req)
733{
734 struct crypto_aead *tfm = aead_givcrypt_reqtfm(req);
735 struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm);
736 size_t ivsize = crypto_aead_ivsize(tfm);
737 struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg);
738 unsigned len;
739 __be64 seq;
740
741 memcpy(req->areq.iv, ctx->salt, ivsize);
742 len = ivsize;
743 if (ivsize > sizeof(u64)) {
744 memset(req->giv, 0, ivsize - sizeof(u64));
745 len = sizeof(u64);
746 }
747 seq = cpu_to_be64(req->seq);
748 memcpy(req->giv + ivsize - len, &seq, len);
749
750 return spacc_aead_setup(&req->areq, req->giv, alg->type, 1);
751}
752
753static int spacc_aead_decrypt(struct aead_request *req)
754{
755 struct crypto_aead *aead = crypto_aead_reqtfm(req);
756 struct crypto_tfm *tfm = crypto_aead_tfm(aead);
757 struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg);
758
759 return spacc_aead_setup(req, NULL, alg->type, 0);
760}
761
762/*
763 * Initialise a new AEAD context. This is responsible for allocating the
764 * fallback cipher and initialising the context.
765 */
766static int spacc_aead_cra_init(struct crypto_tfm *tfm)
767{
768 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
769 struct crypto_alg *alg = tfm->__crt_alg;
770 struct spacc_alg *spacc_alg = to_spacc_alg(alg);
771 struct spacc_engine *engine = spacc_alg->engine;
772
773 ctx->generic.flags = spacc_alg->type;
774 ctx->generic.engine = engine;
775 ctx->sw_cipher = crypto_alloc_aead(alg->cra_name, 0,
776 CRYPTO_ALG_ASYNC |
777 CRYPTO_ALG_NEED_FALLBACK);
778 if (IS_ERR(ctx->sw_cipher)) {
779 dev_warn(engine->dev, "failed to allocate fallback for %s\n",
780 alg->cra_name);
781 ctx->sw_cipher = NULL;
782 }
783 ctx->generic.key_offs = spacc_alg->key_offs;
784 ctx->generic.iv_offs = spacc_alg->iv_offs;
785
786 get_random_bytes(ctx->salt, sizeof(ctx->salt));
787
788 tfm->crt_aead.reqsize = sizeof(struct spacc_req);
789
790 return 0;
791}
792
793/*
794 * Destructor for an AEAD context. This is called when the transform is freed
795 * and must free the fallback cipher.
796 */
797static void spacc_aead_cra_exit(struct crypto_tfm *tfm)
798{
799 struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm);
800
801 if (ctx->sw_cipher)
802 crypto_free_aead(ctx->sw_cipher);
803 ctx->sw_cipher = NULL;
804}
805
806/*
807 * Set the DES key for a block cipher transform. This also performs weak key
808 * checking if the transform has requested it.
809 */
810static int spacc_des_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
811 unsigned int len)
812{
813 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
814 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
815 u32 tmp[DES_EXPKEY_WORDS];
816
817 if (len > DES3_EDE_KEY_SIZE) {
818 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
819 return -EINVAL;
820 }
821
822 if (unlikely(!des_ekey(tmp, key)) &&
823 (crypto_ablkcipher_get_flags(cipher) & CRYPTO_TFM_REQ_WEAK_KEY)) {
824 tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
825 return -EINVAL;
826 }
827
828 memcpy(ctx->key, key, len);
829 ctx->key_len = len;
830
831 return 0;
832}
833
834/*
835 * Set the key for an AES block cipher. Some key lengths are not supported in
836 * hardware so this must also check whether a fallback is needed.
837 */
838static int spacc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
839 unsigned int len)
840{
841 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
842 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
843 int err = 0;
844
845 if (len > AES_MAX_KEY_SIZE) {
846 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
847 return -EINVAL;
848 }
849
850 /*
851 * IPSec engine only supports 128 and 256 bit AES keys. If we get a
852 * request for any other size (192 bits) then we need to do a software
853 * fallback.
854 */
855 if ((len != AES_KEYSIZE_128 || len != AES_KEYSIZE_256) &&
856 ctx->sw_cipher) {
857 /*
858 * Set the fallback transform to use the same request flags as
859 * the hardware transform.
860 */
861 ctx->sw_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
862 ctx->sw_cipher->base.crt_flags |=
863 cipher->base.crt_flags & CRYPTO_TFM_REQ_MASK;
864
865 err = crypto_ablkcipher_setkey(ctx->sw_cipher, key, len);
866 if (err)
867 goto sw_setkey_failed;
868 } else if ((len != AES_KEYSIZE_128 || len != AES_KEYSIZE_256) &&
869 !ctx->sw_cipher)
870 err = -EINVAL;
871
872 memcpy(ctx->key, key, len);
873 ctx->key_len = len;
874
875sw_setkey_failed:
876 if (err && ctx->sw_cipher) {
877 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
878 tfm->crt_flags |=
879 ctx->sw_cipher->base.crt_flags & CRYPTO_TFM_RES_MASK;
880 }
881
882 return err;
883}
884
885static int spacc_kasumi_f8_setkey(struct crypto_ablkcipher *cipher,
886 const u8 *key, unsigned int len)
887{
888 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
889 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
890 int err = 0;
891
892 if (len > AES_MAX_KEY_SIZE) {
893 crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
894 err = -EINVAL;
895 goto out;
896 }
897
898 memcpy(ctx->key, key, len);
899 ctx->key_len = len;
900
901out:
902 return err;
903}
904
905static int spacc_ablk_need_fallback(struct spacc_req *req)
906{
907 struct spacc_ablk_ctx *ctx;
908 struct crypto_tfm *tfm = req->req->tfm;
909 struct crypto_alg *alg = req->req->tfm->__crt_alg;
910 struct spacc_alg *spacc_alg = to_spacc_alg(alg);
911
912 ctx = crypto_tfm_ctx(tfm);
913
914 return (spacc_alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) ==
915 SPA_CTRL_CIPH_ALG_AES &&
916 ctx->key_len != AES_KEYSIZE_128 &&
917 ctx->key_len != AES_KEYSIZE_256;
918}
919
920static void spacc_ablk_complete(struct spacc_req *req)
921{
922 struct ablkcipher_request *ablk_req =
923 container_of(req->req, struct ablkcipher_request, base);
924
925 if (ablk_req->src != ablk_req->dst) {
926 spacc_free_ddt(req, req->src_ddt, req->src_addr, ablk_req->src,
927 ablk_req->nbytes, DMA_TO_DEVICE);
928 spacc_free_ddt(req, req->dst_ddt, req->dst_addr, ablk_req->dst,
929 ablk_req->nbytes, DMA_FROM_DEVICE);
930 } else
931 spacc_free_ddt(req, req->dst_ddt, req->dst_addr, ablk_req->dst,
932 ablk_req->nbytes, DMA_BIDIRECTIONAL);
933
934 req->req->complete(req->req, req->result);
935}
936
937static int spacc_ablk_submit(struct spacc_req *req)
938{
939 struct crypto_tfm *tfm = req->req->tfm;
940 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
941 struct ablkcipher_request *ablk_req = ablkcipher_request_cast(req->req);
942 struct crypto_alg *alg = req->req->tfm->__crt_alg;
943 struct spacc_alg *spacc_alg = to_spacc_alg(alg);
944 struct spacc_engine *engine = ctx->generic.engine;
945 u32 ctrl;
946
947 req->ctx_id = spacc_load_ctx(&ctx->generic, ctx->key,
948 ctx->key_len, ablk_req->info, alg->cra_ablkcipher.ivsize,
949 NULL, 0);
950
951 writel(req->src_addr, engine->regs + SPA_SRC_PTR_REG_OFFSET);
952 writel(req->dst_addr, engine->regs + SPA_DST_PTR_REG_OFFSET);
953 writel(0, engine->regs + SPA_OFFSET_REG_OFFSET);
954
955 writel(ablk_req->nbytes, engine->regs + SPA_PROC_LEN_REG_OFFSET);
956 writel(0, engine->regs + SPA_ICV_OFFSET_REG_OFFSET);
957 writel(0, engine->regs + SPA_AUX_INFO_REG_OFFSET);
958 writel(0, engine->regs + SPA_AAD_LEN_REG_OFFSET);
959
960 ctrl = spacc_alg->ctrl_default | (req->ctx_id << SPA_CTRL_CTX_IDX) |
961 (req->is_encrypt ? (1 << SPA_CTRL_ENCRYPT_IDX) :
962 (1 << SPA_CTRL_KEY_EXP));
963
964 mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
965
966 writel(ctrl, engine->regs + SPA_CTRL_REG_OFFSET);
967
968 return -EINPROGRESS;
969}
970
971static int spacc_ablk_do_fallback(struct ablkcipher_request *req,
972 unsigned alg_type, bool is_encrypt)
973{
974 struct crypto_tfm *old_tfm =
975 crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
976 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(old_tfm);
977 int err;
978
979 if (!ctx->sw_cipher)
980 return -EINVAL;
981
982 /*
983 * Change the request to use the software fallback transform, and once
984 * the ciphering has completed, put the old transform back into the
985 * request.
986 */
987 ablkcipher_request_set_tfm(req, ctx->sw_cipher);
988 err = is_encrypt ? crypto_ablkcipher_encrypt(req) :
989 crypto_ablkcipher_decrypt(req);
990 ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(old_tfm));
991
992 return err;
993}
994
995static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type,
996 bool is_encrypt)
997{
998 struct crypto_alg *alg = req->base.tfm->__crt_alg;
999 struct spacc_engine *engine = to_spacc_alg(alg)->engine;
1000 struct spacc_req *dev_req = ablkcipher_request_ctx(req);
1001 unsigned long flags;
1002 int err = -ENOMEM;
1003
1004 dev_req->req = &req->base;
1005 dev_req->is_encrypt = is_encrypt;
1006 dev_req->engine = engine;
1007 dev_req->complete = spacc_ablk_complete;
1008 dev_req->result = -EINPROGRESS;
1009
1010 if (unlikely(spacc_ablk_need_fallback(dev_req)))
1011 return spacc_ablk_do_fallback(req, alg_type, is_encrypt);
1012
1013 /*
1014 * Create the DDT's for the engine. If we share the same source and
1015 * destination then we can optimize by reusing the DDT's.
1016 */
1017 if (req->src != req->dst) {
1018 dev_req->src_ddt = spacc_sg_to_ddt(engine, req->src,
1019 req->nbytes, DMA_TO_DEVICE, &dev_req->src_addr);
1020 if (!dev_req->src_ddt)
1021 goto out;
1022
1023 dev_req->dst_ddt = spacc_sg_to_ddt(engine, req->dst,
1024 req->nbytes, DMA_FROM_DEVICE, &dev_req->dst_addr);
1025 if (!dev_req->dst_ddt)
1026 goto out_free_src;
1027 } else {
1028 dev_req->dst_ddt = spacc_sg_to_ddt(engine, req->dst,
1029 req->nbytes, DMA_BIDIRECTIONAL, &dev_req->dst_addr);
1030 if (!dev_req->dst_ddt)
1031 goto out;
1032
1033 dev_req->src_ddt = NULL;
1034 dev_req->src_addr = dev_req->dst_addr;
1035 }
1036
1037 err = -EINPROGRESS;
1038 spin_lock_irqsave(&engine->hw_lock, flags);
1039 /*
1040 * Check if the engine will accept the operation now. If it won't then
1041 * we either stick it on the end of a pending list if we can backlog,
1042 * or bailout with an error if not.
1043 */
1044 if (unlikely(spacc_fifo_cmd_full(engine))) {
1045 if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
1046 err = -EBUSY;
1047 spin_unlock_irqrestore(&engine->hw_lock, flags);
1048 goto out_free_ddts;
1049 }
1050 list_add_tail(&dev_req->list, &engine->pending);
1051 } else {
1052 ++engine->in_flight;
1053 list_add_tail(&dev_req->list, &engine->in_progress);
1054 spacc_ablk_submit(dev_req);
1055 }
1056 spin_unlock_irqrestore(&engine->hw_lock, flags);
1057
1058 goto out;
1059
1060out_free_ddts:
1061 spacc_free_ddt(dev_req, dev_req->dst_ddt, dev_req->dst_addr, req->dst,
1062 req->nbytes, req->src == req->dst ?
1063 DMA_BIDIRECTIONAL : DMA_FROM_DEVICE);
1064out_free_src:
1065 if (req->src != req->dst)
1066 spacc_free_ddt(dev_req, dev_req->src_ddt, dev_req->src_addr,
1067 req->src, req->nbytes, DMA_TO_DEVICE);
1068out:
1069 return err;
1070}
1071
1072static int spacc_ablk_cra_init(struct crypto_tfm *tfm)
1073{
1074 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
1075 struct crypto_alg *alg = tfm->__crt_alg;
1076 struct spacc_alg *spacc_alg = to_spacc_alg(alg);
1077 struct spacc_engine *engine = spacc_alg->engine;
1078
1079 ctx->generic.flags = spacc_alg->type;
1080 ctx->generic.engine = engine;
1081 if (alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) {
1082 ctx->sw_cipher = crypto_alloc_ablkcipher(alg->cra_name, 0,
1083 CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
1084 if (IS_ERR(ctx->sw_cipher)) {
1085 dev_warn(engine->dev, "failed to allocate fallback for %s\n",
1086 alg->cra_name);
1087 ctx->sw_cipher = NULL;
1088 }
1089 }
1090 ctx->generic.key_offs = spacc_alg->key_offs;
1091 ctx->generic.iv_offs = spacc_alg->iv_offs;
1092
1093 tfm->crt_ablkcipher.reqsize = sizeof(struct spacc_req);
1094
1095 return 0;
1096}
1097
1098static void spacc_ablk_cra_exit(struct crypto_tfm *tfm)
1099{
1100 struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm);
1101
1102 if (ctx->sw_cipher)
1103 crypto_free_ablkcipher(ctx->sw_cipher);
1104 ctx->sw_cipher = NULL;
1105}
1106
1107static int spacc_ablk_encrypt(struct ablkcipher_request *req)
1108{
1109 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req);
1110 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
1111 struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg);
1112
1113 return spacc_ablk_setup(req, alg->type, 1);
1114}
1115
1116static int spacc_ablk_decrypt(struct ablkcipher_request *req)
1117{
1118 struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req);
1119 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
1120 struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg);
1121
1122 return spacc_ablk_setup(req, alg->type, 0);
1123}
1124
1125static inline int spacc_fifo_stat_empty(struct spacc_engine *engine)
1126{
1127 return readl(engine->regs + SPA_FIFO_STAT_REG_OFFSET) &
1128 SPA_FIFO_STAT_EMPTY;
1129}
1130
1131static void spacc_process_done(struct spacc_engine *engine)
1132{
1133 struct spacc_req *req;
1134 unsigned long flags;
1135
1136 spin_lock_irqsave(&engine->hw_lock, flags);
1137
1138 while (!spacc_fifo_stat_empty(engine)) {
1139 req = list_first_entry(&engine->in_progress, struct spacc_req,
1140 list);
1141 list_move_tail(&req->list, &engine->completed);
1142
1143 /* POP the status register. */
1144 writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET);
1145 req->result = (readl(engine->regs + SPA_STATUS_REG_OFFSET) &
1146 SPA_STATUS_RES_CODE_MASK) >> SPA_STATUS_RES_CODE_OFFSET;
1147
1148 /*
1149 * Convert the SPAcc error status into the standard POSIX error
1150 * codes.
1151 */
1152 if (unlikely(req->result)) {
1153 switch (req->result) {
1154 case SPA_STATUS_ICV_FAIL:
1155 req->result = -EBADMSG;
1156 break;
1157
1158 case SPA_STATUS_MEMORY_ERROR:
1159 dev_warn(engine->dev,
1160 "memory error triggered\n");
1161 req->result = -EFAULT;
1162 break;
1163
1164 case SPA_STATUS_BLOCK_ERROR:
1165 dev_warn(engine->dev,
1166 "block error triggered\n");
1167 req->result = -EIO;
1168 break;
1169 }
1170 }
1171 }
1172
1173 tasklet_schedule(&engine->complete);
1174
1175 spin_unlock_irqrestore(&engine->hw_lock, flags);
1176}
1177
1178static irqreturn_t spacc_spacc_irq(int irq, void *dev)
1179{
1180 struct spacc_engine *engine = (struct spacc_engine *)dev;
1181 u32 spacc_irq_stat = readl(engine->regs + SPA_IRQ_STAT_REG_OFFSET);
1182
1183 writel(spacc_irq_stat, engine->regs + SPA_IRQ_STAT_REG_OFFSET);
1184 spacc_process_done(engine);
1185
1186 return IRQ_HANDLED;
1187}
1188
1189static void spacc_packet_timeout(unsigned long data)
1190{
1191 struct spacc_engine *engine = (struct spacc_engine *)data;
1192
1193 spacc_process_done(engine);
1194}
1195
1196static int spacc_req_submit(struct spacc_req *req)
1197{
1198 struct crypto_alg *alg = req->req->tfm->__crt_alg;
1199
1200 if (CRYPTO_ALG_TYPE_AEAD == (CRYPTO_ALG_TYPE_MASK & alg->cra_flags))
1201 return spacc_aead_submit(req);
1202 else
1203 return spacc_ablk_submit(req);
1204}
1205
1206static void spacc_spacc_complete(unsigned long data)
1207{
1208 struct spacc_engine *engine = (struct spacc_engine *)data;
1209 struct spacc_req *req, *tmp;
1210 unsigned long flags;
1211 int num_removed = 0;
1212 LIST_HEAD(completed);
1213
1214 spin_lock_irqsave(&engine->hw_lock, flags);
1215 list_splice_init(&engine->completed, &completed);
1216 spin_unlock_irqrestore(&engine->hw_lock, flags);
1217
1218 list_for_each_entry_safe(req, tmp, &completed, list) {
1219 ++num_removed;
1220 req->complete(req);
1221 }
1222
1223 /* Try and fill the engine back up again. */
1224 spin_lock_irqsave(&engine->hw_lock, flags);
1225
1226 engine->in_flight -= num_removed;
1227
1228 list_for_each_entry_safe(req, tmp, &engine->pending, list) {
1229 if (spacc_fifo_cmd_full(engine))
1230 break;
1231
1232 list_move_tail(&req->list, &engine->in_progress);
1233 ++engine->in_flight;
1234 req->result = spacc_req_submit(req);
1235 }
1236
1237 if (engine->in_flight)
1238 mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
1239
1240 spin_unlock_irqrestore(&engine->hw_lock, flags);
1241}
1242
1243#ifdef CONFIG_PM
1244static int spacc_suspend(struct device *dev)
1245{
1246 struct platform_device *pdev = to_platform_device(dev);
1247 struct spacc_engine *engine = platform_get_drvdata(pdev);
1248
1249 /*
1250 * We only support standby mode. All we have to do is gate the clock to
1251 * the spacc. The hardware will preserve state until we turn it back
1252 * on again.
1253 */
1254 clk_disable(engine->clk);
1255
1256 return 0;
1257}
1258
1259static int spacc_resume(struct device *dev)
1260{
1261 struct platform_device *pdev = to_platform_device(dev);
1262 struct spacc_engine *engine = platform_get_drvdata(pdev);
1263
1264 return clk_enable(engine->clk);
1265}
1266
1267static const struct dev_pm_ops spacc_pm_ops = {
1268 .suspend = spacc_suspend,
1269 .resume = spacc_resume,
1270};
1271#endif /* CONFIG_PM */
1272
1273static inline struct spacc_engine *spacc_dev_to_engine(struct device *dev)
1274{
1275 return dev ? platform_get_drvdata(to_platform_device(dev)) : NULL;
1276}
1277
1278static ssize_t spacc_stat_irq_thresh_show(struct device *dev,
1279 struct device_attribute *attr,
1280 char *buf)
1281{
1282 struct spacc_engine *engine = spacc_dev_to_engine(dev);
1283
1284 return snprintf(buf, PAGE_SIZE, "%u\n", engine->stat_irq_thresh);
1285}
1286
1287static ssize_t spacc_stat_irq_thresh_store(struct device *dev,
1288 struct device_attribute *attr,
1289 const char *buf, size_t len)
1290{
1291 struct spacc_engine *engine = spacc_dev_to_engine(dev);
1292 unsigned long thresh;
1293
1294 if (strict_strtoul(buf, 0, &thresh))
1295 return -EINVAL;
1296
1297 thresh = clamp(thresh, 1UL, engine->fifo_sz - 1);
1298
1299 engine->stat_irq_thresh = thresh;
1300 writel(engine->stat_irq_thresh << SPA_IRQ_CTRL_STAT_CNT_OFFSET,
1301 engine->regs + SPA_IRQ_CTRL_REG_OFFSET);
1302
1303 return len;
1304}
1305static DEVICE_ATTR(stat_irq_thresh, 0644, spacc_stat_irq_thresh_show,
1306 spacc_stat_irq_thresh_store);
1307
1308static struct spacc_alg ipsec_engine_algs[] = {
1309 {
1310 .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC,
1311 .key_offs = 0,
1312 .iv_offs = AES_MAX_KEY_SIZE,
1313 .alg = {
1314 .cra_name = "cbc(aes)",
1315 .cra_driver_name = "cbc-aes-picoxcell",
1316 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1317 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
1318 CRYPTO_ALG_ASYNC |
1319 CRYPTO_ALG_NEED_FALLBACK,
1320 .cra_blocksize = AES_BLOCK_SIZE,
1321 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1322 .cra_type = &crypto_ablkcipher_type,
1323 .cra_module = THIS_MODULE,
1324 .cra_ablkcipher = {
1325 .setkey = spacc_aes_setkey,
1326 .encrypt = spacc_ablk_encrypt,
1327 .decrypt = spacc_ablk_decrypt,
1328 .min_keysize = AES_MIN_KEY_SIZE,
1329 .max_keysize = AES_MAX_KEY_SIZE,
1330 .ivsize = AES_BLOCK_SIZE,
1331 },
1332 .cra_init = spacc_ablk_cra_init,
1333 .cra_exit = spacc_ablk_cra_exit,
1334 },
1335 },
1336 {
1337 .key_offs = 0,
1338 .iv_offs = AES_MAX_KEY_SIZE,
1339 .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_ECB,
1340 .alg = {
1341 .cra_name = "ecb(aes)",
1342 .cra_driver_name = "ecb-aes-picoxcell",
1343 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1344 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
1345 CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
1346 .cra_blocksize = AES_BLOCK_SIZE,
1347 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1348 .cra_type = &crypto_ablkcipher_type,
1349 .cra_module = THIS_MODULE,
1350 .cra_ablkcipher = {
1351 .setkey = spacc_aes_setkey,
1352 .encrypt = spacc_ablk_encrypt,
1353 .decrypt = spacc_ablk_decrypt,
1354 .min_keysize = AES_MIN_KEY_SIZE,
1355 .max_keysize = AES_MAX_KEY_SIZE,
1356 },
1357 .cra_init = spacc_ablk_cra_init,
1358 .cra_exit = spacc_ablk_cra_exit,
1359 },
1360 },
1361 {
1362 .key_offs = DES_BLOCK_SIZE,
1363 .iv_offs = 0,
1364 .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC,
1365 .alg = {
1366 .cra_name = "cbc(des)",
1367 .cra_driver_name = "cbc-des-picoxcell",
1368 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1369 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
1370 .cra_blocksize = DES_BLOCK_SIZE,
1371 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1372 .cra_type = &crypto_ablkcipher_type,
1373 .cra_module = THIS_MODULE,
1374 .cra_ablkcipher = {
1375 .setkey = spacc_des_setkey,
1376 .encrypt = spacc_ablk_encrypt,
1377 .decrypt = spacc_ablk_decrypt,
1378 .min_keysize = DES_KEY_SIZE,
1379 .max_keysize = DES_KEY_SIZE,
1380 .ivsize = DES_BLOCK_SIZE,
1381 },
1382 .cra_init = spacc_ablk_cra_init,
1383 .cra_exit = spacc_ablk_cra_exit,
1384 },
1385 },
1386 {
1387 .key_offs = DES_BLOCK_SIZE,
1388 .iv_offs = 0,
1389 .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_ECB,
1390 .alg = {
1391 .cra_name = "ecb(des)",
1392 .cra_driver_name = "ecb-des-picoxcell",
1393 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1394 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
1395 .cra_blocksize = DES_BLOCK_SIZE,
1396 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1397 .cra_type = &crypto_ablkcipher_type,
1398 .cra_module = THIS_MODULE,
1399 .cra_ablkcipher = {
1400 .setkey = spacc_des_setkey,
1401 .encrypt = spacc_ablk_encrypt,
1402 .decrypt = spacc_ablk_decrypt,
1403 .min_keysize = DES_KEY_SIZE,
1404 .max_keysize = DES_KEY_SIZE,
1405 },
1406 .cra_init = spacc_ablk_cra_init,
1407 .cra_exit = spacc_ablk_cra_exit,
1408 },
1409 },
1410 {
1411 .key_offs = DES_BLOCK_SIZE,
1412 .iv_offs = 0,
1413 .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC,
1414 .alg = {
1415 .cra_name = "cbc(des3_ede)",
1416 .cra_driver_name = "cbc-des3-ede-picoxcell",
1417 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1418 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
1419 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1420 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1421 .cra_type = &crypto_ablkcipher_type,
1422 .cra_module = THIS_MODULE,
1423 .cra_ablkcipher = {
1424 .setkey = spacc_des_setkey,
1425 .encrypt = spacc_ablk_encrypt,
1426 .decrypt = spacc_ablk_decrypt,
1427 .min_keysize = DES3_EDE_KEY_SIZE,
1428 .max_keysize = DES3_EDE_KEY_SIZE,
1429 .ivsize = DES3_EDE_BLOCK_SIZE,
1430 },
1431 .cra_init = spacc_ablk_cra_init,
1432 .cra_exit = spacc_ablk_cra_exit,
1433 },
1434 },
1435 {
1436 .key_offs = DES_BLOCK_SIZE,
1437 .iv_offs = 0,
1438 .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_ECB,
1439 .alg = {
1440 .cra_name = "ecb(des3_ede)",
1441 .cra_driver_name = "ecb-des3-ede-picoxcell",
1442 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1443 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
1444 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1445 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1446 .cra_type = &crypto_ablkcipher_type,
1447 .cra_module = THIS_MODULE,
1448 .cra_ablkcipher = {
1449 .setkey = spacc_des_setkey,
1450 .encrypt = spacc_ablk_encrypt,
1451 .decrypt = spacc_ablk_decrypt,
1452 .min_keysize = DES3_EDE_KEY_SIZE,
1453 .max_keysize = DES3_EDE_KEY_SIZE,
1454 },
1455 .cra_init = spacc_ablk_cra_init,
1456 .cra_exit = spacc_ablk_cra_exit,
1457 },
1458 },
1459 {
1460 .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC |
1461 SPA_CTRL_HASH_ALG_SHA | SPA_CTRL_HASH_MODE_HMAC,
1462 .key_offs = 0,
1463 .iv_offs = AES_MAX_KEY_SIZE,
1464 .alg = {
1465 .cra_name = "authenc(hmac(sha1),cbc(aes))",
1466 .cra_driver_name = "authenc-hmac-sha1-cbc-aes-picoxcell",
1467 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1468 .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
1469 .cra_blocksize = AES_BLOCK_SIZE,
1470 .cra_ctxsize = sizeof(struct spacc_aead_ctx),
1471 .cra_type = &crypto_aead_type,
1472 .cra_module = THIS_MODULE,
1473 .cra_aead = {
1474 .setkey = spacc_aead_setkey,
1475 .setauthsize = spacc_aead_setauthsize,
1476 .encrypt = spacc_aead_encrypt,
1477 .decrypt = spacc_aead_decrypt,
1478 .givencrypt = spacc_aead_givencrypt,
1479 .ivsize = AES_BLOCK_SIZE,
1480 .maxauthsize = SHA1_DIGEST_SIZE,
1481 },
1482 .cra_init = spacc_aead_cra_init,
1483 .cra_exit = spacc_aead_cra_exit,
1484 },
1485 },
1486 {
1487 .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC |
1488 SPA_CTRL_HASH_ALG_SHA256 |
1489 SPA_CTRL_HASH_MODE_HMAC,
1490 .key_offs = 0,
1491 .iv_offs = AES_MAX_KEY_SIZE,
1492 .alg = {
1493 .cra_name = "authenc(hmac(sha256),cbc(aes))",
1494 .cra_driver_name = "authenc-hmac-sha256-cbc-aes-picoxcell",
1495 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1496 .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
1497 .cra_blocksize = AES_BLOCK_SIZE,
1498 .cra_ctxsize = sizeof(struct spacc_aead_ctx),
1499 .cra_type = &crypto_aead_type,
1500 .cra_module = THIS_MODULE,
1501 .cra_aead = {
1502 .setkey = spacc_aead_setkey,
1503 .setauthsize = spacc_aead_setauthsize,
1504 .encrypt = spacc_aead_encrypt,
1505 .decrypt = spacc_aead_decrypt,
1506 .givencrypt = spacc_aead_givencrypt,
1507 .ivsize = AES_BLOCK_SIZE,
1508 .maxauthsize = SHA256_DIGEST_SIZE,
1509 },
1510 .cra_init = spacc_aead_cra_init,
1511 .cra_exit = spacc_aead_cra_exit,
1512 },
1513 },
1514 {
1515 .key_offs = 0,
1516 .iv_offs = AES_MAX_KEY_SIZE,
1517 .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC |
1518 SPA_CTRL_HASH_ALG_MD5 | SPA_CTRL_HASH_MODE_HMAC,
1519 .alg = {
1520 .cra_name = "authenc(hmac(md5),cbc(aes))",
1521 .cra_driver_name = "authenc-hmac-md5-cbc-aes-picoxcell",
1522 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1523 .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
1524 .cra_blocksize = AES_BLOCK_SIZE,
1525 .cra_ctxsize = sizeof(struct spacc_aead_ctx),
1526 .cra_type = &crypto_aead_type,
1527 .cra_module = THIS_MODULE,
1528 .cra_aead = {
1529 .setkey = spacc_aead_setkey,
1530 .setauthsize = spacc_aead_setauthsize,
1531 .encrypt = spacc_aead_encrypt,
1532 .decrypt = spacc_aead_decrypt,
1533 .givencrypt = spacc_aead_givencrypt,
1534 .ivsize = AES_BLOCK_SIZE,
1535 .maxauthsize = MD5_DIGEST_SIZE,
1536 },
1537 .cra_init = spacc_aead_cra_init,
1538 .cra_exit = spacc_aead_cra_exit,
1539 },
1540 },
1541 {
1542 .key_offs = DES_BLOCK_SIZE,
1543 .iv_offs = 0,
1544 .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC |
1545 SPA_CTRL_HASH_ALG_SHA | SPA_CTRL_HASH_MODE_HMAC,
1546 .alg = {
1547 .cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
1548 .cra_driver_name = "authenc-hmac-sha1-cbc-3des-picoxcell",
1549 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1550 .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
1551 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1552 .cra_ctxsize = sizeof(struct spacc_aead_ctx),
1553 .cra_type = &crypto_aead_type,
1554 .cra_module = THIS_MODULE,
1555 .cra_aead = {
1556 .setkey = spacc_aead_setkey,
1557 .setauthsize = spacc_aead_setauthsize,
1558 .encrypt = spacc_aead_encrypt,
1559 .decrypt = spacc_aead_decrypt,
1560 .givencrypt = spacc_aead_givencrypt,
1561 .ivsize = DES3_EDE_BLOCK_SIZE,
1562 .maxauthsize = SHA1_DIGEST_SIZE,
1563 },
1564 .cra_init = spacc_aead_cra_init,
1565 .cra_exit = spacc_aead_cra_exit,
1566 },
1567 },
1568 {
1569 .key_offs = DES_BLOCK_SIZE,
1570 .iv_offs = 0,
1571 .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC |
1572 SPA_CTRL_HASH_ALG_SHA256 |
1573 SPA_CTRL_HASH_MODE_HMAC,
1574 .alg = {
1575 .cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
1576 .cra_driver_name = "authenc-hmac-sha256-cbc-3des-picoxcell",
1577 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1578 .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
1579 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1580 .cra_ctxsize = sizeof(struct spacc_aead_ctx),
1581 .cra_type = &crypto_aead_type,
1582 .cra_module = THIS_MODULE,
1583 .cra_aead = {
1584 .setkey = spacc_aead_setkey,
1585 .setauthsize = spacc_aead_setauthsize,
1586 .encrypt = spacc_aead_encrypt,
1587 .decrypt = spacc_aead_decrypt,
1588 .givencrypt = spacc_aead_givencrypt,
1589 .ivsize = DES3_EDE_BLOCK_SIZE,
1590 .maxauthsize = SHA256_DIGEST_SIZE,
1591 },
1592 .cra_init = spacc_aead_cra_init,
1593 .cra_exit = spacc_aead_cra_exit,
1594 },
1595 },
1596 {
1597 .key_offs = DES_BLOCK_SIZE,
1598 .iv_offs = 0,
1599 .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC |
1600 SPA_CTRL_HASH_ALG_MD5 | SPA_CTRL_HASH_MODE_HMAC,
1601 .alg = {
1602 .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
1603 .cra_driver_name = "authenc-hmac-md5-cbc-3des-picoxcell",
1604 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1605 .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
1606 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
1607 .cra_ctxsize = sizeof(struct spacc_aead_ctx),
1608 .cra_type = &crypto_aead_type,
1609 .cra_module = THIS_MODULE,
1610 .cra_aead = {
1611 .setkey = spacc_aead_setkey,
1612 .setauthsize = spacc_aead_setauthsize,
1613 .encrypt = spacc_aead_encrypt,
1614 .decrypt = spacc_aead_decrypt,
1615 .givencrypt = spacc_aead_givencrypt,
1616 .ivsize = DES3_EDE_BLOCK_SIZE,
1617 .maxauthsize = MD5_DIGEST_SIZE,
1618 },
1619 .cra_init = spacc_aead_cra_init,
1620 .cra_exit = spacc_aead_cra_exit,
1621 },
1622 },
1623};
1624
1625static struct spacc_alg l2_engine_algs[] = {
1626 {
1627 .key_offs = 0,
1628 .iv_offs = SPACC_CRYPTO_KASUMI_F8_KEY_LEN,
1629 .ctrl_default = SPA_CTRL_CIPH_ALG_KASUMI |
1630 SPA_CTRL_CIPH_MODE_F8,
1631 .alg = {
1632 .cra_name = "f8(kasumi)",
1633 .cra_driver_name = "f8-kasumi-picoxcell",
1634 .cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
1635 .cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_ASYNC,
1636 .cra_blocksize = 8,
1637 .cra_ctxsize = sizeof(struct spacc_ablk_ctx),
1638 .cra_type = &crypto_ablkcipher_type,
1639 .cra_module = THIS_MODULE,
1640 .cra_ablkcipher = {
1641 .setkey = spacc_kasumi_f8_setkey,
1642 .encrypt = spacc_ablk_encrypt,
1643 .decrypt = spacc_ablk_decrypt,
1644 .min_keysize = 16,
1645 .max_keysize = 16,
1646 .ivsize = 8,
1647 },
1648 .cra_init = spacc_ablk_cra_init,
1649 .cra_exit = spacc_ablk_cra_exit,
1650 },
1651 },
1652};
1653
1654static int __devinit spacc_probe(struct platform_device *pdev,
1655 unsigned max_ctxs, size_t cipher_pg_sz,
1656 size_t hash_pg_sz, size_t fifo_sz,
1657 struct spacc_alg *algs, size_t num_algs)
1658{
1659 int i, err, ret = -EINVAL;
1660 struct resource *mem, *irq;
1661 struct spacc_engine *engine = devm_kzalloc(&pdev->dev, sizeof(*engine),
1662 GFP_KERNEL);
1663 if (!engine)
1664 return -ENOMEM;
1665
1666 engine->max_ctxs = max_ctxs;
1667 engine->cipher_pg_sz = cipher_pg_sz;
1668 engine->hash_pg_sz = hash_pg_sz;
1669 engine->fifo_sz = fifo_sz;
1670 engine->algs = algs;
1671 engine->num_algs = num_algs;
1672 engine->name = dev_name(&pdev->dev);
1673
1674 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1675 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1676 if (!mem || !irq) {
1677 dev_err(&pdev->dev, "no memory/irq resource for engine\n");
1678 return -ENXIO;
1679 }
1680
1681 if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
1682 engine->name))
1683 return -ENOMEM;
1684
1685 engine->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
1686 if (!engine->regs) {
1687 dev_err(&pdev->dev, "memory map failed\n");
1688 return -ENOMEM;
1689 }
1690
1691 if (devm_request_irq(&pdev->dev, irq->start, spacc_spacc_irq, 0,
1692 engine->name, engine)) {
1693 dev_err(engine->dev, "failed to request IRQ\n");
1694 return -EBUSY;
1695 }
1696
1697 engine->dev = &pdev->dev;
1698 engine->cipher_ctx_base = engine->regs + SPA_CIPH_KEY_BASE_REG_OFFSET;
1699 engine->hash_key_base = engine->regs + SPA_HASH_KEY_BASE_REG_OFFSET;
1700
1701 engine->req_pool = dmam_pool_create(engine->name, engine->dev,
1702 MAX_DDT_LEN * sizeof(struct spacc_ddt), 8, SZ_64K);
1703 if (!engine->req_pool)
1704 return -ENOMEM;
1705
1706 spin_lock_init(&engine->hw_lock);
1707
1708 engine->clk = clk_get(&pdev->dev, NULL);
1709 if (IS_ERR(engine->clk)) {
1710 dev_info(&pdev->dev, "clk unavailable\n");
1711 device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh);
1712 return PTR_ERR(engine->clk);
1713 }
1714
1715 if (clk_enable(engine->clk)) {
1716 dev_info(&pdev->dev, "unable to enable clk\n");
1717 clk_put(engine->clk);
1718 return -EIO;
1719 }
1720
1721 err = device_create_file(&pdev->dev, &dev_attr_stat_irq_thresh);
1722 if (err) {
1723 clk_disable(engine->clk);
1724 clk_put(engine->clk);
1725 return err;
1726 }
1727
1728
1729 /*
1730 * Use an IRQ threshold of 50% as a default. This seems to be a
1731 * reasonable trade off of latency against throughput but can be
1732 * changed at runtime.
1733 */
1734 engine->stat_irq_thresh = (engine->fifo_sz / 2);
1735
1736 /*
1737 * Configure the interrupts. We only use the STAT_CNT interrupt as we
1738 * only submit a new packet for processing when we complete another in
1739 * the queue. This minimizes time spent in the interrupt handler.
1740 */
1741 writel(engine->stat_irq_thresh << SPA_IRQ_CTRL_STAT_CNT_OFFSET,
1742 engine->regs + SPA_IRQ_CTRL_REG_OFFSET);
1743 writel(SPA_IRQ_EN_STAT_EN | SPA_IRQ_EN_GLBL_EN,
1744 engine->regs + SPA_IRQ_EN_REG_OFFSET);
1745
1746 setup_timer(&engine->packet_timeout, spacc_packet_timeout,
1747 (unsigned long)engine);
1748
1749 INIT_LIST_HEAD(&engine->pending);
1750 INIT_LIST_HEAD(&engine->completed);
1751 INIT_LIST_HEAD(&engine->in_progress);
1752 engine->in_flight = 0;
1753 tasklet_init(&engine->complete, spacc_spacc_complete,
1754 (unsigned long)engine);
1755
1756 platform_set_drvdata(pdev, engine);
1757
1758 INIT_LIST_HEAD(&engine->registered_algs);
1759 for (i = 0; i < engine->num_algs; ++i) {
1760 engine->algs[i].engine = engine;
1761 err = crypto_register_alg(&engine->algs[i].alg);
1762 if (!err) {
1763 list_add_tail(&engine->algs[i].entry,
1764 &engine->registered_algs);
1765 ret = 0;
1766 }
1767 if (err)
1768 dev_err(engine->dev, "failed to register alg \"%s\"\n",
1769 engine->algs[i].alg.cra_name);
1770 else
1771 dev_dbg(engine->dev, "registered alg \"%s\"\n",
1772 engine->algs[i].alg.cra_name);
1773 }
1774
1775 return ret;
1776}
1777
1778static int __devexit spacc_remove(struct platform_device *pdev)
1779{
1780 struct spacc_alg *alg, *next;
1781 struct spacc_engine *engine = platform_get_drvdata(pdev);
1782
1783 del_timer_sync(&engine->packet_timeout);
1784 device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh);
1785
1786 list_for_each_entry_safe(alg, next, &engine->registered_algs, entry) {
1787 list_del(&alg->entry);
1788 crypto_unregister_alg(&alg->alg);
1789 }
1790
1791 clk_disable(engine->clk);
1792 clk_put(engine->clk);
1793
1794 return 0;
1795}
1796
1797static int __devinit ipsec_probe(struct platform_device *pdev)
1798{
1799 return spacc_probe(pdev, SPACC_CRYPTO_IPSEC_MAX_CTXS,
1800 SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ,
1801 SPACC_CRYPTO_IPSEC_HASH_PG_SZ,
1802 SPACC_CRYPTO_IPSEC_FIFO_SZ, ipsec_engine_algs,
1803 ARRAY_SIZE(ipsec_engine_algs));
1804}
1805
1806static struct platform_driver ipsec_driver = {
1807 .probe = ipsec_probe,
1808 .remove = __devexit_p(spacc_remove),
1809 .driver = {
1810 .name = "picoxcell-ipsec",
1811#ifdef CONFIG_PM
1812 .pm = &spacc_pm_ops,
1813#endif /* CONFIG_PM */
1814 },
1815};
1816
1817static int __devinit l2_probe(struct platform_device *pdev)
1818{
1819 return spacc_probe(pdev, SPACC_CRYPTO_L2_MAX_CTXS,
1820 SPACC_CRYPTO_L2_CIPHER_PG_SZ,
1821 SPACC_CRYPTO_L2_HASH_PG_SZ, SPACC_CRYPTO_L2_FIFO_SZ,
1822 l2_engine_algs, ARRAY_SIZE(l2_engine_algs));
1823}
1824
1825static struct platform_driver l2_driver = {
1826 .probe = l2_probe,
1827 .remove = __devexit_p(spacc_remove),
1828 .driver = {
1829 .name = "picoxcell-l2",
1830#ifdef CONFIG_PM
1831 .pm = &spacc_pm_ops,
1832#endif /* CONFIG_PM */
1833 },
1834};
1835
1836static int __init spacc_init(void)
1837{
1838 int ret = platform_driver_register(&ipsec_driver);
1839 if (ret) {
1840 pr_err("failed to register ipsec spacc driver");
1841 goto out;
1842 }
1843
1844 ret = platform_driver_register(&l2_driver);
1845 if (ret) {
1846 pr_err("failed to register l2 spacc driver");
1847 goto l2_failed;
1848 }
1849
1850 return 0;
1851
1852l2_failed:
1853 platform_driver_unregister(&ipsec_driver);
1854out:
1855 return ret;
1856}
1857module_init(spacc_init);
1858
1859static void __exit spacc_exit(void)
1860{
1861 platform_driver_unregister(&ipsec_driver);
1862 platform_driver_unregister(&l2_driver);
1863}
1864module_exit(spacc_exit);
1865
1866MODULE_LICENSE("GPL");
1867MODULE_AUTHOR("Jamie Iles");
diff --git a/drivers/crypto/picoxcell_crypto_regs.h b/drivers/crypto/picoxcell_crypto_regs.h
new file mode 100644
index 000000000000..af93442564c9
--- /dev/null
+++ b/drivers/crypto/picoxcell_crypto_regs.h
@@ -0,0 +1,128 @@
1/*
2 * Copyright (c) 2010 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef __PICOXCELL_CRYPTO_REGS_H__
19#define __PICOXCELL_CRYPTO_REGS_H__
20
21#define SPA_STATUS_OK 0
22#define SPA_STATUS_ICV_FAIL 1
23#define SPA_STATUS_MEMORY_ERROR 2
24#define SPA_STATUS_BLOCK_ERROR 3
25
26#define SPA_IRQ_CTRL_STAT_CNT_OFFSET 16
27#define SPA_IRQ_STAT_STAT_MASK (1 << 4)
28#define SPA_FIFO_STAT_STAT_OFFSET 16
29#define SPA_FIFO_STAT_STAT_CNT_MASK (0x3F << SPA_FIFO_STAT_STAT_OFFSET)
30#define SPA_STATUS_RES_CODE_OFFSET 24
31#define SPA_STATUS_RES_CODE_MASK (0x3 << SPA_STATUS_RES_CODE_OFFSET)
32#define SPA_KEY_SZ_CTX_INDEX_OFFSET 8
33#define SPA_KEY_SZ_CIPHER_OFFSET 31
34
35#define SPA_IRQ_EN_REG_OFFSET 0x00000000
36#define SPA_IRQ_STAT_REG_OFFSET 0x00000004
37#define SPA_IRQ_CTRL_REG_OFFSET 0x00000008
38#define SPA_FIFO_STAT_REG_OFFSET 0x0000000C
39#define SPA_SDMA_BRST_SZ_REG_OFFSET 0x00000010
40#define SPA_SRC_PTR_REG_OFFSET 0x00000020
41#define SPA_DST_PTR_REG_OFFSET 0x00000024
42#define SPA_OFFSET_REG_OFFSET 0x00000028
43#define SPA_AAD_LEN_REG_OFFSET 0x0000002C
44#define SPA_PROC_LEN_REG_OFFSET 0x00000030
45#define SPA_ICV_LEN_REG_OFFSET 0x00000034
46#define SPA_ICV_OFFSET_REG_OFFSET 0x00000038
47#define SPA_SW_CTRL_REG_OFFSET 0x0000003C
48#define SPA_CTRL_REG_OFFSET 0x00000040
49#define SPA_AUX_INFO_REG_OFFSET 0x0000004C
50#define SPA_STAT_POP_REG_OFFSET 0x00000050
51#define SPA_STATUS_REG_OFFSET 0x00000054
52#define SPA_KEY_SZ_REG_OFFSET 0x00000100
53#define SPA_CIPH_KEY_BASE_REG_OFFSET 0x00004000
54#define SPA_HASH_KEY_BASE_REG_OFFSET 0x00008000
55#define SPA_RC4_CTX_BASE_REG_OFFSET 0x00020000
56
57#define SPA_IRQ_EN_REG_RESET 0x00000000
58#define SPA_IRQ_CTRL_REG_RESET 0x00000000
59#define SPA_FIFO_STAT_REG_RESET 0x00000000
60#define SPA_SDMA_BRST_SZ_REG_RESET 0x00000000
61#define SPA_SRC_PTR_REG_RESET 0x00000000
62#define SPA_DST_PTR_REG_RESET 0x00000000
63#define SPA_OFFSET_REG_RESET 0x00000000
64#define SPA_AAD_LEN_REG_RESET 0x00000000
65#define SPA_PROC_LEN_REG_RESET 0x00000000
66#define SPA_ICV_LEN_REG_RESET 0x00000000
67#define SPA_ICV_OFFSET_REG_RESET 0x00000000
68#define SPA_SW_CTRL_REG_RESET 0x00000000
69#define SPA_CTRL_REG_RESET 0x00000000
70#define SPA_AUX_INFO_REG_RESET 0x00000000
71#define SPA_STAT_POP_REG_RESET 0x00000000
72#define SPA_STATUS_REG_RESET 0x00000000
73#define SPA_KEY_SZ_REG_RESET 0x00000000
74
75#define SPA_CTRL_HASH_ALG_IDX 4
76#define SPA_CTRL_CIPH_MODE_IDX 8
77#define SPA_CTRL_HASH_MODE_IDX 12
78#define SPA_CTRL_CTX_IDX 16
79#define SPA_CTRL_ENCRYPT_IDX 24
80#define SPA_CTRL_AAD_COPY 25
81#define SPA_CTRL_ICV_PT 26
82#define SPA_CTRL_ICV_ENC 27
83#define SPA_CTRL_ICV_APPEND 28
84#define SPA_CTRL_KEY_EXP 29
85
86#define SPA_KEY_SZ_CXT_IDX 8
87#define SPA_KEY_SZ_CIPHER_IDX 31
88
89#define SPA_IRQ_EN_CMD0_EN (1 << 0)
90#define SPA_IRQ_EN_STAT_EN (1 << 4)
91#define SPA_IRQ_EN_GLBL_EN (1 << 31)
92
93#define SPA_CTRL_CIPH_ALG_NULL 0x00
94#define SPA_CTRL_CIPH_ALG_DES 0x01
95#define SPA_CTRL_CIPH_ALG_AES 0x02
96#define SPA_CTRL_CIPH_ALG_RC4 0x03
97#define SPA_CTRL_CIPH_ALG_MULTI2 0x04
98#define SPA_CTRL_CIPH_ALG_KASUMI 0x05
99
100#define SPA_CTRL_HASH_ALG_NULL (0x00 << SPA_CTRL_HASH_ALG_IDX)
101#define SPA_CTRL_HASH_ALG_MD5 (0x01 << SPA_CTRL_HASH_ALG_IDX)
102#define SPA_CTRL_HASH_ALG_SHA (0x02 << SPA_CTRL_HASH_ALG_IDX)
103#define SPA_CTRL_HASH_ALG_SHA224 (0x03 << SPA_CTRL_HASH_ALG_IDX)
104#define SPA_CTRL_HASH_ALG_SHA256 (0x04 << SPA_CTRL_HASH_ALG_IDX)
105#define SPA_CTRL_HASH_ALG_SHA384 (0x05 << SPA_CTRL_HASH_ALG_IDX)
106#define SPA_CTRL_HASH_ALG_SHA512 (0x06 << SPA_CTRL_HASH_ALG_IDX)
107#define SPA_CTRL_HASH_ALG_AESMAC (0x07 << SPA_CTRL_HASH_ALG_IDX)
108#define SPA_CTRL_HASH_ALG_AESCMAC (0x08 << SPA_CTRL_HASH_ALG_IDX)
109#define SPA_CTRL_HASH_ALG_KASF9 (0x09 << SPA_CTRL_HASH_ALG_IDX)
110
111#define SPA_CTRL_CIPH_MODE_NULL (0x00 << SPA_CTRL_CIPH_MODE_IDX)
112#define SPA_CTRL_CIPH_MODE_ECB (0x00 << SPA_CTRL_CIPH_MODE_IDX)
113#define SPA_CTRL_CIPH_MODE_CBC (0x01 << SPA_CTRL_CIPH_MODE_IDX)
114#define SPA_CTRL_CIPH_MODE_CTR (0x02 << SPA_CTRL_CIPH_MODE_IDX)
115#define SPA_CTRL_CIPH_MODE_CCM (0x03 << SPA_CTRL_CIPH_MODE_IDX)
116#define SPA_CTRL_CIPH_MODE_GCM (0x05 << SPA_CTRL_CIPH_MODE_IDX)
117#define SPA_CTRL_CIPH_MODE_OFB (0x07 << SPA_CTRL_CIPH_MODE_IDX)
118#define SPA_CTRL_CIPH_MODE_CFB (0x08 << SPA_CTRL_CIPH_MODE_IDX)
119#define SPA_CTRL_CIPH_MODE_F8 (0x09 << SPA_CTRL_CIPH_MODE_IDX)
120
121#define SPA_CTRL_HASH_MODE_RAW (0x00 << SPA_CTRL_HASH_MODE_IDX)
122#define SPA_CTRL_HASH_MODE_SSLMAC (0x01 << SPA_CTRL_HASH_MODE_IDX)
123#define SPA_CTRL_HASH_MODE_HMAC (0x02 << SPA_CTRL_HASH_MODE_IDX)
124
125#define SPA_FIFO_STAT_EMPTY (1 << 31)
126#define SPA_FIFO_CMD_FULL (1 << 7)
127
128#endif /* __PICOXCELL_CRYPTO_REGS_H__ */