4 * Support for ATMEL DES/TDES HW acceleration.
6 * Copyright (c) 2012 Eukréa Electromatique - ATMEL
7 * Author: Nicolas Royer <nicolas@eukrea.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
13 * Some ideas are from omap-aes.c drivers.
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <linux/err.h>
21 #include <linux/clk.h>
23 #include <linux/hw_random.h>
24 #include <linux/platform_device.h>
26 #include <linux/device.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/errno.h>
30 #include <linux/interrupt.h>
31 #include <linux/kernel.h>
32 #include <linux/clk.h>
33 #include <linux/irq.h>
35 #include <linux/platform_device.h>
36 #include <linux/scatterlist.h>
37 #include <linux/dma-mapping.h>
38 #include <linux/delay.h>
39 #include <linux/crypto.h>
40 #include <linux/cryptohash.h>
41 #include <crypto/scatterwalk.h>
42 #include <crypto/algapi.h>
43 #include <crypto/des.h>
44 #include <crypto/hash.h>
45 #include <crypto/internal/hash.h>
46 #include "atmel-tdes-regs.h"
49 #define TDES_FLAGS_MODE_MASK 0x007f
50 #define TDES_FLAGS_ENCRYPT BIT(0)
51 #define TDES_FLAGS_CBC BIT(1)
52 #define TDES_FLAGS_CFB BIT(2)
53 #define TDES_FLAGS_CFB8 BIT(3)
54 #define TDES_FLAGS_CFB16 BIT(4)
55 #define TDES_FLAGS_CFB32 BIT(5)
56 #define TDES_FLAGS_OFB BIT(6)
58 #define TDES_FLAGS_INIT BIT(16)
59 #define TDES_FLAGS_FAST BIT(17)
60 #define TDES_FLAGS_BUSY BIT(18)
62 #define ATMEL_TDES_QUEUE_LENGTH 1
64 #define CFB8_BLOCK_SIZE 1
65 #define CFB16_BLOCK_SIZE 2
66 #define CFB32_BLOCK_SIZE 4
67 #define CFB64_BLOCK_SIZE 8
70 struct atmel_tdes_dev
;
72 struct atmel_tdes_ctx
{
73 struct atmel_tdes_dev
*dd
;
76 u32 key
[3*DES_KEY_SIZE
/ sizeof(u32
)];
80 struct atmel_tdes_reqctx
{
84 struct atmel_tdes_dev
{
85 struct list_head list
;
86 unsigned long phys_base
;
87 void __iomem
*io_base
;
89 struct atmel_tdes_ctx
*ctx
;
98 struct crypto_queue queue
;
100 struct tasklet_struct done_task
;
101 struct tasklet_struct queue_task
;
103 struct ablkcipher_request
*req
;
106 struct scatterlist
*in_sg
;
108 struct scatterlist
*out_sg
;
116 dma_addr_t dma_addr_in
;
120 dma_addr_t dma_addr_out
;
123 struct atmel_tdes_drv
{
124 struct list_head dev_list
;
128 static struct atmel_tdes_drv atmel_tdes
= {
129 .dev_list
= LIST_HEAD_INIT(atmel_tdes
.dev_list
),
130 .lock
= __SPIN_LOCK_UNLOCKED(atmel_tdes
.lock
),
133 static int atmel_tdes_sg_copy(struct scatterlist
**sg
, size_t *offset
,
134 void *buf
, size_t buflen
, size_t total
, int out
)
136 unsigned int count
, off
= 0;
138 while (buflen
&& total
) {
139 count
= min((*sg
)->length
- *offset
, total
);
140 count
= min(count
, buflen
);
145 scatterwalk_map_and_copy(buf
+ off
, *sg
, *offset
, count
, out
);
152 if (*offset
== (*sg
)->length
) {
164 static inline u32
atmel_tdes_read(struct atmel_tdes_dev
*dd
, u32 offset
)
166 return readl_relaxed(dd
->io_base
+ offset
);
169 static inline void atmel_tdes_write(struct atmel_tdes_dev
*dd
,
170 u32 offset
, u32 value
)
172 writel_relaxed(value
, dd
->io_base
+ offset
);
175 static void atmel_tdes_write_n(struct atmel_tdes_dev
*dd
, u32 offset
,
176 u32
*value
, int count
)
178 for (; count
--; value
++, offset
+= 4)
179 atmel_tdes_write(dd
, offset
, *value
);
182 static struct atmel_tdes_dev
*atmel_tdes_find_dev(struct atmel_tdes_ctx
*ctx
)
184 struct atmel_tdes_dev
*tdes_dd
= NULL
;
185 struct atmel_tdes_dev
*tmp
;
187 spin_lock_bh(&atmel_tdes
.lock
);
189 list_for_each_entry(tmp
, &atmel_tdes
.dev_list
, list
) {
197 spin_unlock_bh(&atmel_tdes
.lock
);
202 static int atmel_tdes_hw_init(struct atmel_tdes_dev
*dd
)
204 clk_prepare_enable(dd
->iclk
);
206 if (!(dd
->flags
& TDES_FLAGS_INIT
)) {
207 atmel_tdes_write(dd
, TDES_CR
, TDES_CR_SWRST
);
208 dd
->flags
|= TDES_FLAGS_INIT
;
215 static int atmel_tdes_write_ctrl(struct atmel_tdes_dev
*dd
)
218 u32 valcr
= 0, valmr
= TDES_MR_SMOD_PDC
;
220 err
= atmel_tdes_hw_init(dd
);
225 atmel_tdes_write(dd
, TDES_PTCR
, TDES_PTCR_TXTDIS
|TDES_PTCR_RXTDIS
);
227 /* MR register must be set before IV registers */
228 if (dd
->ctx
->keylen
> (DES_KEY_SIZE
<< 1)) {
229 valmr
|= TDES_MR_KEYMOD_3KEY
;
230 valmr
|= TDES_MR_TDESMOD_TDES
;
231 } else if (dd
->ctx
->keylen
> DES_KEY_SIZE
) {
232 valmr
|= TDES_MR_KEYMOD_2KEY
;
233 valmr
|= TDES_MR_TDESMOD_TDES
;
235 valmr
|= TDES_MR_TDESMOD_DES
;
238 if (dd
->flags
& TDES_FLAGS_CBC
) {
239 valmr
|= TDES_MR_OPMOD_CBC
;
240 } else if (dd
->flags
& TDES_FLAGS_CFB
) {
241 valmr
|= TDES_MR_OPMOD_CFB
;
243 if (dd
->flags
& TDES_FLAGS_CFB8
)
244 valmr
|= TDES_MR_CFBS_8b
;
245 else if (dd
->flags
& TDES_FLAGS_CFB16
)
246 valmr
|= TDES_MR_CFBS_16b
;
247 else if (dd
->flags
& TDES_FLAGS_CFB32
)
248 valmr
|= TDES_MR_CFBS_32b
;
249 } else if (dd
->flags
& TDES_FLAGS_OFB
) {
250 valmr
|= TDES_MR_OPMOD_OFB
;
253 if ((dd
->flags
& TDES_FLAGS_ENCRYPT
) || (dd
->flags
& TDES_FLAGS_OFB
))
254 valmr
|= TDES_MR_CYPHER_ENC
;
256 atmel_tdes_write(dd
, TDES_CR
, valcr
);
257 atmel_tdes_write(dd
, TDES_MR
, valmr
);
259 atmel_tdes_write_n(dd
, TDES_KEY1W1R
, dd
->ctx
->key
,
260 dd
->ctx
->keylen
>> 2);
262 if (((dd
->flags
& TDES_FLAGS_CBC
) || (dd
->flags
& TDES_FLAGS_CFB
) ||
263 (dd
->flags
& TDES_FLAGS_OFB
)) && dd
->req
->info
) {
264 atmel_tdes_write_n(dd
, TDES_IV1R
, dd
->req
->info
, 2);
270 static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev
*dd
)
275 atmel_tdes_write(dd
, TDES_PTCR
, TDES_PTCR_TXTDIS
|TDES_PTCR_RXTDIS
);
277 if (dd
->flags
& TDES_FLAGS_FAST
) {
278 dma_unmap_sg(dd
->dev
, dd
->out_sg
, 1, DMA_FROM_DEVICE
);
279 dma_unmap_sg(dd
->dev
, dd
->in_sg
, 1, DMA_TO_DEVICE
);
281 dma_sync_single_for_device(dd
->dev
, dd
->dma_addr_out
,
282 dd
->dma_size
, DMA_FROM_DEVICE
);
285 count
= atmel_tdes_sg_copy(&dd
->out_sg
, &dd
->out_offset
,
286 dd
->buf_out
, dd
->buflen
, dd
->dma_size
, 1);
287 if (count
!= dd
->dma_size
) {
289 pr_err("not all data converted: %u\n", count
);
296 static int atmel_tdes_dma_init(struct atmel_tdes_dev
*dd
)
300 dd
->buf_in
= (void *)__get_free_pages(GFP_KERNEL
, 0);
301 dd
->buf_out
= (void *)__get_free_pages(GFP_KERNEL
, 0);
302 dd
->buflen
= PAGE_SIZE
;
303 dd
->buflen
&= ~(DES_BLOCK_SIZE
- 1);
305 if (!dd
->buf_in
|| !dd
->buf_out
) {
306 dev_err(dd
->dev
, "unable to alloc pages.\n");
311 dd
->dma_addr_in
= dma_map_single(dd
->dev
, dd
->buf_in
,
312 dd
->buflen
, DMA_TO_DEVICE
);
313 if (dma_mapping_error(dd
->dev
, dd
->dma_addr_in
)) {
314 dev_err(dd
->dev
, "dma %d bytes error\n", dd
->buflen
);
319 dd
->dma_addr_out
= dma_map_single(dd
->dev
, dd
->buf_out
,
320 dd
->buflen
, DMA_FROM_DEVICE
);
321 if (dma_mapping_error(dd
->dev
, dd
->dma_addr_out
)) {
322 dev_err(dd
->dev
, "dma %d bytes error\n", dd
->buflen
);
330 dma_unmap_single(dd
->dev
, dd
->dma_addr_in
, dd
->buflen
,
333 free_page((unsigned long)dd
->buf_out
);
334 free_page((unsigned long)dd
->buf_in
);
337 pr_err("error: %d\n", err
);
341 static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev
*dd
)
343 dma_unmap_single(dd
->dev
, dd
->dma_addr_out
, dd
->buflen
,
345 dma_unmap_single(dd
->dev
, dd
->dma_addr_in
, dd
->buflen
,
347 free_page((unsigned long)dd
->buf_out
);
348 free_page((unsigned long)dd
->buf_in
);
351 static int atmel_tdes_crypt_dma(struct crypto_tfm
*tfm
, dma_addr_t dma_addr_in
,
352 dma_addr_t dma_addr_out
, int length
)
354 struct atmel_tdes_ctx
*ctx
= crypto_tfm_ctx(tfm
);
355 struct atmel_tdes_dev
*dd
= ctx
->dd
;
358 dd
->dma_size
= length
;
360 if (!(dd
->flags
& TDES_FLAGS_FAST
)) {
361 dma_sync_single_for_device(dd
->dev
, dma_addr_in
, length
,
365 if ((dd
->flags
& TDES_FLAGS_CFB
) && (dd
->flags
& TDES_FLAGS_CFB8
))
366 len32
= DIV_ROUND_UP(length
, sizeof(u8
));
367 else if ((dd
->flags
& TDES_FLAGS_CFB
) && (dd
->flags
& TDES_FLAGS_CFB16
))
368 len32
= DIV_ROUND_UP(length
, sizeof(u16
));
370 len32
= DIV_ROUND_UP(length
, sizeof(u32
));
372 atmel_tdes_write(dd
, TDES_PTCR
, TDES_PTCR_TXTDIS
|TDES_PTCR_RXTDIS
);
373 atmel_tdes_write(dd
, TDES_TPR
, dma_addr_in
);
374 atmel_tdes_write(dd
, TDES_TCR
, len32
);
375 atmel_tdes_write(dd
, TDES_RPR
, dma_addr_out
);
376 atmel_tdes_write(dd
, TDES_RCR
, len32
);
378 /* Enable Interrupt */
379 atmel_tdes_write(dd
, TDES_IER
, TDES_INT_ENDRX
);
381 /* Start DMA transfer */
382 atmel_tdes_write(dd
, TDES_PTCR
, TDES_PTCR_TXTEN
| TDES_PTCR_RXTEN
);
387 static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev
*dd
)
389 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(
390 crypto_ablkcipher_reqtfm(dd
->req
));
391 int err
, fast
= 0, in
, out
;
393 dma_addr_t addr_in
, addr_out
;
395 if (sg_is_last(dd
->in_sg
) && sg_is_last(dd
->out_sg
)) {
396 /* check for alignment */
397 in
= IS_ALIGNED((u32
)dd
->in_sg
->offset
, sizeof(u32
));
398 out
= IS_ALIGNED((u32
)dd
->out_sg
->offset
, sizeof(u32
));
404 count
= min(dd
->total
, sg_dma_len(dd
->in_sg
));
405 count
= min(count
, sg_dma_len(dd
->out_sg
));
407 if (count
!= dd
->total
) {
408 pr_err("request length != buffer length\n");
412 err
= dma_map_sg(dd
->dev
, dd
->in_sg
, 1, DMA_TO_DEVICE
);
414 dev_err(dd
->dev
, "dma_map_sg() error\n");
418 err
= dma_map_sg(dd
->dev
, dd
->out_sg
, 1,
421 dev_err(dd
->dev
, "dma_map_sg() error\n");
422 dma_unmap_sg(dd
->dev
, dd
->in_sg
, 1,
427 addr_in
= sg_dma_address(dd
->in_sg
);
428 addr_out
= sg_dma_address(dd
->out_sg
);
430 dd
->flags
|= TDES_FLAGS_FAST
;
433 /* use cache buffers */
434 count
= atmel_tdes_sg_copy(&dd
->in_sg
, &dd
->in_offset
,
435 dd
->buf_in
, dd
->buflen
, dd
->total
, 0);
437 addr_in
= dd
->dma_addr_in
;
438 addr_out
= dd
->dma_addr_out
;
440 dd
->flags
&= ~TDES_FLAGS_FAST
;
446 err
= atmel_tdes_crypt_dma(tfm
, addr_in
, addr_out
, count
);
448 dma_unmap_sg(dd
->dev
, dd
->in_sg
, 1, DMA_TO_DEVICE
);
449 dma_unmap_sg(dd
->dev
, dd
->out_sg
, 1, DMA_TO_DEVICE
);
456 static void atmel_tdes_finish_req(struct atmel_tdes_dev
*dd
, int err
)
458 struct ablkcipher_request
*req
= dd
->req
;
460 clk_disable_unprepare(dd
->iclk
);
462 dd
->flags
&= ~TDES_FLAGS_BUSY
;
464 req
->base
.complete(&req
->base
, err
);
467 static int atmel_tdes_handle_queue(struct atmel_tdes_dev
*dd
,
468 struct ablkcipher_request
*req
)
470 struct crypto_async_request
*async_req
, *backlog
;
471 struct atmel_tdes_ctx
*ctx
;
472 struct atmel_tdes_reqctx
*rctx
;
476 spin_lock_irqsave(&dd
->lock
, flags
);
478 ret
= ablkcipher_enqueue_request(&dd
->queue
, req
);
479 if (dd
->flags
& TDES_FLAGS_BUSY
) {
480 spin_unlock_irqrestore(&dd
->lock
, flags
);
483 backlog
= crypto_get_backlog(&dd
->queue
);
484 async_req
= crypto_dequeue_request(&dd
->queue
);
486 dd
->flags
|= TDES_FLAGS_BUSY
;
487 spin_unlock_irqrestore(&dd
->lock
, flags
);
493 backlog
->complete(backlog
, -EINPROGRESS
);
495 req
= ablkcipher_request_cast(async_req
);
497 /* assign new request to device */
499 dd
->total
= req
->nbytes
;
501 dd
->in_sg
= req
->src
;
503 dd
->out_sg
= req
->dst
;
505 rctx
= ablkcipher_request_ctx(req
);
506 ctx
= crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req
));
507 rctx
->mode
&= TDES_FLAGS_MODE_MASK
;
508 dd
->flags
= (dd
->flags
& ~TDES_FLAGS_MODE_MASK
) | rctx
->mode
;
512 err
= atmel_tdes_write_ctrl(dd
);
514 err
= atmel_tdes_crypt_dma_start(dd
);
516 /* des_task will not finish it, so do it here */
517 atmel_tdes_finish_req(dd
, err
);
518 tasklet_schedule(&dd
->queue_task
);
525 static int atmel_tdes_crypt(struct ablkcipher_request
*req
, unsigned long mode
)
527 struct atmel_tdes_ctx
*ctx
= crypto_ablkcipher_ctx(
528 crypto_ablkcipher_reqtfm(req
));
529 struct atmel_tdes_reqctx
*rctx
= ablkcipher_request_ctx(req
);
530 struct atmel_tdes_dev
*dd
;
532 if (mode
& TDES_FLAGS_CFB8
) {
533 if (!IS_ALIGNED(req
->nbytes
, CFB8_BLOCK_SIZE
)) {
534 pr_err("request size is not exact amount of CFB8 blocks\n");
537 } else if (mode
& TDES_FLAGS_CFB16
) {
538 if (!IS_ALIGNED(req
->nbytes
, CFB16_BLOCK_SIZE
)) {
539 pr_err("request size is not exact amount of CFB16 blocks\n");
542 } else if (mode
& TDES_FLAGS_CFB32
) {
543 if (!IS_ALIGNED(req
->nbytes
, CFB32_BLOCK_SIZE
)) {
544 pr_err("request size is not exact amount of CFB32 blocks\n");
547 } else if (!IS_ALIGNED(req
->nbytes
, DES_BLOCK_SIZE
)) {
548 pr_err("request size is not exact amount of DES blocks\n");
552 dd
= atmel_tdes_find_dev(ctx
);
558 return atmel_tdes_handle_queue(dd
, req
);
561 static int atmel_des_setkey(struct crypto_ablkcipher
*tfm
, const u8
*key
,
564 u32 tmp
[DES_EXPKEY_WORDS
];
566 struct crypto_tfm
*ctfm
= crypto_ablkcipher_tfm(tfm
);
568 struct atmel_tdes_ctx
*ctx
= crypto_ablkcipher_ctx(tfm
);
570 if (keylen
!= DES_KEY_SIZE
) {
571 crypto_ablkcipher_set_flags(tfm
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
575 err
= des_ekey(tmp
, key
);
576 if (err
== 0 && (ctfm
->crt_flags
& CRYPTO_TFM_REQ_WEAK_KEY
)) {
577 ctfm
->crt_flags
|= CRYPTO_TFM_RES_WEAK_KEY
;
581 memcpy(ctx
->key
, key
, keylen
);
582 ctx
->keylen
= keylen
;
587 static int atmel_tdes_setkey(struct crypto_ablkcipher
*tfm
, const u8
*key
,
590 struct atmel_tdes_ctx
*ctx
= crypto_ablkcipher_ctx(tfm
);
591 const char *alg_name
;
593 alg_name
= crypto_tfm_alg_name(crypto_ablkcipher_tfm(tfm
));
596 * HW bug in cfb 3-keys mode.
598 if (strstr(alg_name
, "cfb") && (keylen
!= 2*DES_KEY_SIZE
)) {
599 crypto_ablkcipher_set_flags(tfm
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
601 } else if ((keylen
!= 2*DES_KEY_SIZE
) && (keylen
!= 3*DES_KEY_SIZE
)) {
602 crypto_ablkcipher_set_flags(tfm
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
606 memcpy(ctx
->key
, key
, keylen
);
607 ctx
->keylen
= keylen
;
612 static int atmel_tdes_ecb_encrypt(struct ablkcipher_request
*req
)
614 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
);
617 static int atmel_tdes_ecb_decrypt(struct ablkcipher_request
*req
)
619 return atmel_tdes_crypt(req
, 0);
622 static int atmel_tdes_cbc_encrypt(struct ablkcipher_request
*req
)
624 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
| TDES_FLAGS_CBC
);
627 static int atmel_tdes_cbc_decrypt(struct ablkcipher_request
*req
)
629 return atmel_tdes_crypt(req
, TDES_FLAGS_CBC
);
631 static int atmel_tdes_cfb_encrypt(struct ablkcipher_request
*req
)
633 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
| TDES_FLAGS_CFB
);
636 static int atmel_tdes_cfb_decrypt(struct ablkcipher_request
*req
)
638 return atmel_tdes_crypt(req
, TDES_FLAGS_CFB
);
641 static int atmel_tdes_cfb8_encrypt(struct ablkcipher_request
*req
)
643 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
| TDES_FLAGS_CFB
|
647 static int atmel_tdes_cfb8_decrypt(struct ablkcipher_request
*req
)
649 return atmel_tdes_crypt(req
, TDES_FLAGS_CFB
| TDES_FLAGS_CFB8
);
652 static int atmel_tdes_cfb16_encrypt(struct ablkcipher_request
*req
)
654 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
| TDES_FLAGS_CFB
|
658 static int atmel_tdes_cfb16_decrypt(struct ablkcipher_request
*req
)
660 return atmel_tdes_crypt(req
, TDES_FLAGS_CFB
| TDES_FLAGS_CFB16
);
663 static int atmel_tdes_cfb32_encrypt(struct ablkcipher_request
*req
)
665 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
| TDES_FLAGS_CFB
|
669 static int atmel_tdes_cfb32_decrypt(struct ablkcipher_request
*req
)
671 return atmel_tdes_crypt(req
, TDES_FLAGS_CFB
| TDES_FLAGS_CFB32
);
674 static int atmel_tdes_ofb_encrypt(struct ablkcipher_request
*req
)
676 return atmel_tdes_crypt(req
, TDES_FLAGS_ENCRYPT
| TDES_FLAGS_OFB
);
679 static int atmel_tdes_ofb_decrypt(struct ablkcipher_request
*req
)
681 return atmel_tdes_crypt(req
, TDES_FLAGS_OFB
);
684 static int atmel_tdes_cra_init(struct crypto_tfm
*tfm
)
686 tfm
->crt_ablkcipher
.reqsize
= sizeof(struct atmel_tdes_reqctx
);
691 static void atmel_tdes_cra_exit(struct crypto_tfm
*tfm
)
695 static struct crypto_alg tdes_algs
[] = {
697 .cra_name
= "ecb(des)",
698 .cra_driver_name
= "atmel-ecb-des",
700 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
701 .cra_blocksize
= DES_BLOCK_SIZE
,
702 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
704 .cra_type
= &crypto_ablkcipher_type
,
705 .cra_module
= THIS_MODULE
,
706 .cra_init
= atmel_tdes_cra_init
,
707 .cra_exit
= atmel_tdes_cra_exit
,
708 .cra_u
.ablkcipher
= {
709 .min_keysize
= DES_KEY_SIZE
,
710 .max_keysize
= DES_KEY_SIZE
,
711 .setkey
= atmel_des_setkey
,
712 .encrypt
= atmel_tdes_ecb_encrypt
,
713 .decrypt
= atmel_tdes_ecb_decrypt
,
717 .cra_name
= "cbc(des)",
718 .cra_driver_name
= "atmel-cbc-des",
720 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
721 .cra_blocksize
= DES_BLOCK_SIZE
,
722 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
724 .cra_type
= &crypto_ablkcipher_type
,
725 .cra_module
= THIS_MODULE
,
726 .cra_init
= atmel_tdes_cra_init
,
727 .cra_exit
= atmel_tdes_cra_exit
,
728 .cra_u
.ablkcipher
= {
729 .min_keysize
= DES_KEY_SIZE
,
730 .max_keysize
= DES_KEY_SIZE
,
731 .ivsize
= DES_BLOCK_SIZE
,
732 .setkey
= atmel_des_setkey
,
733 .encrypt
= atmel_tdes_cbc_encrypt
,
734 .decrypt
= atmel_tdes_cbc_decrypt
,
738 .cra_name
= "cfb(des)",
739 .cra_driver_name
= "atmel-cfb-des",
741 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
742 .cra_blocksize
= DES_BLOCK_SIZE
,
743 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
745 .cra_type
= &crypto_ablkcipher_type
,
746 .cra_module
= THIS_MODULE
,
747 .cra_init
= atmel_tdes_cra_init
,
748 .cra_exit
= atmel_tdes_cra_exit
,
749 .cra_u
.ablkcipher
= {
750 .min_keysize
= DES_KEY_SIZE
,
751 .max_keysize
= DES_KEY_SIZE
,
752 .ivsize
= DES_BLOCK_SIZE
,
753 .setkey
= atmel_des_setkey
,
754 .encrypt
= atmel_tdes_cfb_encrypt
,
755 .decrypt
= atmel_tdes_cfb_decrypt
,
759 .cra_name
= "cfb8(des)",
760 .cra_driver_name
= "atmel-cfb8-des",
762 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
763 .cra_blocksize
= CFB8_BLOCK_SIZE
,
764 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
766 .cra_type
= &crypto_ablkcipher_type
,
767 .cra_module
= THIS_MODULE
,
768 .cra_init
= atmel_tdes_cra_init
,
769 .cra_exit
= atmel_tdes_cra_exit
,
770 .cra_u
.ablkcipher
= {
771 .min_keysize
= DES_KEY_SIZE
,
772 .max_keysize
= DES_KEY_SIZE
,
773 .ivsize
= DES_BLOCK_SIZE
,
774 .setkey
= atmel_des_setkey
,
775 .encrypt
= atmel_tdes_cfb8_encrypt
,
776 .decrypt
= atmel_tdes_cfb8_decrypt
,
780 .cra_name
= "cfb16(des)",
781 .cra_driver_name
= "atmel-cfb16-des",
783 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
784 .cra_blocksize
= CFB16_BLOCK_SIZE
,
785 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
787 .cra_type
= &crypto_ablkcipher_type
,
788 .cra_module
= THIS_MODULE
,
789 .cra_init
= atmel_tdes_cra_init
,
790 .cra_exit
= atmel_tdes_cra_exit
,
791 .cra_u
.ablkcipher
= {
792 .min_keysize
= DES_KEY_SIZE
,
793 .max_keysize
= DES_KEY_SIZE
,
794 .ivsize
= DES_BLOCK_SIZE
,
795 .setkey
= atmel_des_setkey
,
796 .encrypt
= atmel_tdes_cfb16_encrypt
,
797 .decrypt
= atmel_tdes_cfb16_decrypt
,
801 .cra_name
= "cfb32(des)",
802 .cra_driver_name
= "atmel-cfb32-des",
804 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
805 .cra_blocksize
= CFB32_BLOCK_SIZE
,
806 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
808 .cra_type
= &crypto_ablkcipher_type
,
809 .cra_module
= THIS_MODULE
,
810 .cra_init
= atmel_tdes_cra_init
,
811 .cra_exit
= atmel_tdes_cra_exit
,
812 .cra_u
.ablkcipher
= {
813 .min_keysize
= DES_KEY_SIZE
,
814 .max_keysize
= DES_KEY_SIZE
,
815 .ivsize
= DES_BLOCK_SIZE
,
816 .setkey
= atmel_des_setkey
,
817 .encrypt
= atmel_tdes_cfb32_encrypt
,
818 .decrypt
= atmel_tdes_cfb32_decrypt
,
822 .cra_name
= "ofb(des)",
823 .cra_driver_name
= "atmel-ofb-des",
825 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
826 .cra_blocksize
= DES_BLOCK_SIZE
,
827 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
829 .cra_type
= &crypto_ablkcipher_type
,
830 .cra_module
= THIS_MODULE
,
831 .cra_init
= atmel_tdes_cra_init
,
832 .cra_exit
= atmel_tdes_cra_exit
,
833 .cra_u
.ablkcipher
= {
834 .min_keysize
= DES_KEY_SIZE
,
835 .max_keysize
= DES_KEY_SIZE
,
836 .ivsize
= DES_BLOCK_SIZE
,
837 .setkey
= atmel_des_setkey
,
838 .encrypt
= atmel_tdes_ofb_encrypt
,
839 .decrypt
= atmel_tdes_ofb_decrypt
,
843 .cra_name
= "ecb(des3_ede)",
844 .cra_driver_name
= "atmel-ecb-tdes",
846 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
847 .cra_blocksize
= DES_BLOCK_SIZE
,
848 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
850 .cra_type
= &crypto_ablkcipher_type
,
851 .cra_module
= THIS_MODULE
,
852 .cra_init
= atmel_tdes_cra_init
,
853 .cra_exit
= atmel_tdes_cra_exit
,
854 .cra_u
.ablkcipher
= {
855 .min_keysize
= 2 * DES_KEY_SIZE
,
856 .max_keysize
= 3 * DES_KEY_SIZE
,
857 .setkey
= atmel_tdes_setkey
,
858 .encrypt
= atmel_tdes_ecb_encrypt
,
859 .decrypt
= atmel_tdes_ecb_decrypt
,
863 .cra_name
= "cbc(des3_ede)",
864 .cra_driver_name
= "atmel-cbc-tdes",
866 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
867 .cra_blocksize
= DES_BLOCK_SIZE
,
868 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
870 .cra_type
= &crypto_ablkcipher_type
,
871 .cra_module
= THIS_MODULE
,
872 .cra_init
= atmel_tdes_cra_init
,
873 .cra_exit
= atmel_tdes_cra_exit
,
874 .cra_u
.ablkcipher
= {
875 .min_keysize
= 2*DES_KEY_SIZE
,
876 .max_keysize
= 3*DES_KEY_SIZE
,
877 .ivsize
= DES_BLOCK_SIZE
,
878 .setkey
= atmel_tdes_setkey
,
879 .encrypt
= atmel_tdes_cbc_encrypt
,
880 .decrypt
= atmel_tdes_cbc_decrypt
,
884 .cra_name
= "cfb(des3_ede)",
885 .cra_driver_name
= "atmel-cfb-tdes",
887 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
888 .cra_blocksize
= DES_BLOCK_SIZE
,
889 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
891 .cra_type
= &crypto_ablkcipher_type
,
892 .cra_module
= THIS_MODULE
,
893 .cra_init
= atmel_tdes_cra_init
,
894 .cra_exit
= atmel_tdes_cra_exit
,
895 .cra_u
.ablkcipher
= {
896 .min_keysize
= 2*DES_KEY_SIZE
,
897 .max_keysize
= 2*DES_KEY_SIZE
,
898 .ivsize
= DES_BLOCK_SIZE
,
899 .setkey
= atmel_tdes_setkey
,
900 .encrypt
= atmel_tdes_cfb_encrypt
,
901 .decrypt
= atmel_tdes_cfb_decrypt
,
905 .cra_name
= "cfb8(des3_ede)",
906 .cra_driver_name
= "atmel-cfb8-tdes",
908 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
909 .cra_blocksize
= CFB8_BLOCK_SIZE
,
910 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
912 .cra_type
= &crypto_ablkcipher_type
,
913 .cra_module
= THIS_MODULE
,
914 .cra_init
= atmel_tdes_cra_init
,
915 .cra_exit
= atmel_tdes_cra_exit
,
916 .cra_u
.ablkcipher
= {
917 .min_keysize
= 2*DES_KEY_SIZE
,
918 .max_keysize
= 2*DES_KEY_SIZE
,
919 .ivsize
= DES_BLOCK_SIZE
,
920 .setkey
= atmel_tdes_setkey
,
921 .encrypt
= atmel_tdes_cfb8_encrypt
,
922 .decrypt
= atmel_tdes_cfb8_decrypt
,
926 .cra_name
= "cfb16(des3_ede)",
927 .cra_driver_name
= "atmel-cfb16-tdes",
929 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
930 .cra_blocksize
= CFB16_BLOCK_SIZE
,
931 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
933 .cra_type
= &crypto_ablkcipher_type
,
934 .cra_module
= THIS_MODULE
,
935 .cra_init
= atmel_tdes_cra_init
,
936 .cra_exit
= atmel_tdes_cra_exit
,
937 .cra_u
.ablkcipher
= {
938 .min_keysize
= 2*DES_KEY_SIZE
,
939 .max_keysize
= 2*DES_KEY_SIZE
,
940 .ivsize
= DES_BLOCK_SIZE
,
941 .setkey
= atmel_tdes_setkey
,
942 .encrypt
= atmel_tdes_cfb16_encrypt
,
943 .decrypt
= atmel_tdes_cfb16_decrypt
,
947 .cra_name
= "cfb32(des3_ede)",
948 .cra_driver_name
= "atmel-cfb32-tdes",
950 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
951 .cra_blocksize
= CFB32_BLOCK_SIZE
,
952 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
954 .cra_type
= &crypto_ablkcipher_type
,
955 .cra_module
= THIS_MODULE
,
956 .cra_init
= atmel_tdes_cra_init
,
957 .cra_exit
= atmel_tdes_cra_exit
,
958 .cra_u
.ablkcipher
= {
959 .min_keysize
= 2*DES_KEY_SIZE
,
960 .max_keysize
= 2*DES_KEY_SIZE
,
961 .ivsize
= DES_BLOCK_SIZE
,
962 .setkey
= atmel_tdes_setkey
,
963 .encrypt
= atmel_tdes_cfb32_encrypt
,
964 .decrypt
= atmel_tdes_cfb32_decrypt
,
968 .cra_name
= "ofb(des3_ede)",
969 .cra_driver_name
= "atmel-ofb-tdes",
971 .cra_flags
= CRYPTO_ALG_TYPE_ABLKCIPHER
| CRYPTO_ALG_ASYNC
,
972 .cra_blocksize
= DES_BLOCK_SIZE
,
973 .cra_ctxsize
= sizeof(struct atmel_tdes_ctx
),
975 .cra_type
= &crypto_ablkcipher_type
,
976 .cra_module
= THIS_MODULE
,
977 .cra_init
= atmel_tdes_cra_init
,
978 .cra_exit
= atmel_tdes_cra_exit
,
979 .cra_u
.ablkcipher
= {
980 .min_keysize
= 2*DES_KEY_SIZE
,
981 .max_keysize
= 3*DES_KEY_SIZE
,
982 .ivsize
= DES_BLOCK_SIZE
,
983 .setkey
= atmel_tdes_setkey
,
984 .encrypt
= atmel_tdes_ofb_encrypt
,
985 .decrypt
= atmel_tdes_ofb_decrypt
,
990 static void atmel_tdes_queue_task(unsigned long data
)
992 struct atmel_tdes_dev
*dd
= (struct atmel_tdes_dev
*)data
;
994 atmel_tdes_handle_queue(dd
, NULL
);
997 static void atmel_tdes_done_task(unsigned long data
)
999 struct atmel_tdes_dev
*dd
= (struct atmel_tdes_dev
*) data
;
1002 err
= atmel_tdes_crypt_dma_stop(dd
);
1004 err
= dd
->err
? : err
;
1006 if (dd
->total
&& !err
) {
1007 err
= atmel_tdes_crypt_dma_start(dd
);
1012 atmel_tdes_finish_req(dd
, err
);
1013 atmel_tdes_handle_queue(dd
, NULL
);
1016 static irqreturn_t
atmel_tdes_irq(int irq
, void *dev_id
)
1018 struct atmel_tdes_dev
*tdes_dd
= dev_id
;
1021 reg
= atmel_tdes_read(tdes_dd
, TDES_ISR
);
1022 if (reg
& atmel_tdes_read(tdes_dd
, TDES_IMR
)) {
1023 atmel_tdes_write(tdes_dd
, TDES_IDR
, reg
);
1024 if (TDES_FLAGS_BUSY
& tdes_dd
->flags
)
1025 tasklet_schedule(&tdes_dd
->done_task
);
1027 dev_warn(tdes_dd
->dev
, "TDES interrupt when no active requests.\n");
1034 static void atmel_tdes_unregister_algs(struct atmel_tdes_dev
*dd
)
1038 for (i
= 0; i
< ARRAY_SIZE(tdes_algs
); i
++)
1039 crypto_unregister_alg(&tdes_algs
[i
]);
1042 static int atmel_tdes_register_algs(struct atmel_tdes_dev
*dd
)
1046 for (i
= 0; i
< ARRAY_SIZE(tdes_algs
); i
++) {
1047 INIT_LIST_HEAD(&tdes_algs
[i
].cra_list
);
1048 err
= crypto_register_alg(&tdes_algs
[i
]);
1056 for (j
= 0; j
< i
; j
++)
1057 crypto_unregister_alg(&tdes_algs
[j
]);
1062 static int __devinit
atmel_tdes_probe(struct platform_device
*pdev
)
1064 struct atmel_tdes_dev
*tdes_dd
;
1065 struct device
*dev
= &pdev
->dev
;
1066 struct resource
*tdes_res
;
1067 unsigned long tdes_phys_size
;
1070 tdes_dd
= kzalloc(sizeof(struct atmel_tdes_dev
), GFP_KERNEL
);
1071 if (tdes_dd
== NULL
) {
1072 dev_err(dev
, "unable to alloc data struct.\n");
1079 platform_set_drvdata(pdev
, tdes_dd
);
1081 INIT_LIST_HEAD(&tdes_dd
->list
);
1083 tasklet_init(&tdes_dd
->done_task
, atmel_tdes_done_task
,
1084 (unsigned long)tdes_dd
);
1085 tasklet_init(&tdes_dd
->queue_task
, atmel_tdes_queue_task
,
1086 (unsigned long)tdes_dd
);
1088 crypto_init_queue(&tdes_dd
->queue
, ATMEL_TDES_QUEUE_LENGTH
);
1092 /* Get the base address */
1093 tdes_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1095 dev_err(dev
, "no MEM resource info\n");
1099 tdes_dd
->phys_base
= tdes_res
->start
;
1100 tdes_phys_size
= resource_size(tdes_res
);
1103 tdes_dd
->irq
= platform_get_irq(pdev
, 0);
1104 if (tdes_dd
->irq
< 0) {
1105 dev_err(dev
, "no IRQ resource info\n");
1110 err
= request_irq(tdes_dd
->irq
, atmel_tdes_irq
, IRQF_SHARED
,
1111 "atmel-tdes", tdes_dd
);
1113 dev_err(dev
, "unable to request tdes irq.\n");
1117 /* Initializing the clock */
1118 tdes_dd
->iclk
= clk_get(&pdev
->dev
, NULL
);
1119 if (IS_ERR(tdes_dd
->iclk
)) {
1120 dev_err(dev
, "clock intialization failed.\n");
1121 err
= PTR_ERR(tdes_dd
->iclk
);
1125 tdes_dd
->io_base
= ioremap(tdes_dd
->phys_base
, tdes_phys_size
);
1126 if (!tdes_dd
->io_base
) {
1127 dev_err(dev
, "can't ioremap\n");
1132 err
= atmel_tdes_dma_init(tdes_dd
);
1136 spin_lock(&atmel_tdes
.lock
);
1137 list_add_tail(&tdes_dd
->list
, &atmel_tdes
.dev_list
);
1138 spin_unlock(&atmel_tdes
.lock
);
1140 err
= atmel_tdes_register_algs(tdes_dd
);
1144 dev_info(dev
, "Atmel DES/TDES\n");
1149 spin_lock(&atmel_tdes
.lock
);
1150 list_del(&tdes_dd
->list
);
1151 spin_unlock(&atmel_tdes
.lock
);
1152 atmel_tdes_dma_cleanup(tdes_dd
);
1154 iounmap(tdes_dd
->io_base
);
1156 clk_put(tdes_dd
->iclk
);
1158 free_irq(tdes_dd
->irq
, tdes_dd
);
1161 tasklet_kill(&tdes_dd
->done_task
);
1162 tasklet_kill(&tdes_dd
->queue_task
);
1166 dev_err(dev
, "initialization failed.\n");
1171 static int __devexit
atmel_tdes_remove(struct platform_device
*pdev
)
1173 static struct atmel_tdes_dev
*tdes_dd
;
1175 tdes_dd
= platform_get_drvdata(pdev
);
1178 spin_lock(&atmel_tdes
.lock
);
1179 list_del(&tdes_dd
->list
);
1180 spin_unlock(&atmel_tdes
.lock
);
1182 atmel_tdes_unregister_algs(tdes_dd
);
1184 tasklet_kill(&tdes_dd
->done_task
);
1185 tasklet_kill(&tdes_dd
->queue_task
);
1187 atmel_tdes_dma_cleanup(tdes_dd
);
1189 iounmap(tdes_dd
->io_base
);
1191 clk_put(tdes_dd
->iclk
);
1193 if (tdes_dd
->irq
>= 0)
1194 free_irq(tdes_dd
->irq
, tdes_dd
);
1202 static struct platform_driver atmel_tdes_driver
= {
1203 .probe
= atmel_tdes_probe
,
1204 .remove
= __devexit_p(atmel_tdes_remove
),
1206 .name
= "atmel_tdes",
1207 .owner
= THIS_MODULE
,
1211 module_platform_driver(atmel_tdes_driver
);
1213 MODULE_DESCRIPTION("Atmel DES/TDES hw acceleration support.");
1214 MODULE_LICENSE("GPL v2");
1215 MODULE_AUTHOR("Nicolas Royer - Eukréa Electromatique");