aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorNicolas Royer <nicolas@eukrea.com>2013-02-20 11:10:25 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2013-03-10 04:46:42 -0400
commit1f858040c2f78013fd2b10ddeb9dc157c3362b04 (patch)
treefbfd3f09b6d3881290b8e811ff8b4ed5fe1e25b1 /drivers/crypto
parentcadc4ab8f6f73719ef0e124320cdd210d1c9ff3e (diff)
crypto: atmel-tdes - add support for latest release of the IP (0x700)
Update from previous IP release (0x600): - add DMA support (previous IP release use PDC) Signed-off-by: Nicolas Royer <nicolas@eukrea.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Acked-by: Eric Bénard <eric@eukrea.com> Tested-by: Eric Bénard <eric@eukrea.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/atmel-tdes-regs.h2
-rw-r--r--drivers/crypto/atmel-tdes.c394
2 files changed, 343 insertions, 53 deletions
diff --git a/drivers/crypto/atmel-tdes-regs.h b/drivers/crypto/atmel-tdes-regs.h
index 5ac2a900d80c..f86734d0fda4 100644
--- a/drivers/crypto/atmel-tdes-regs.h
+++ b/drivers/crypto/atmel-tdes-regs.h
@@ -69,6 +69,8 @@
69#define TDES_XTEARNDR_XTEA_RNDS_MASK (0x3F << 0) 69#define TDES_XTEARNDR_XTEA_RNDS_MASK (0x3F << 0)
70#define TDES_XTEARNDR_XTEA_RNDS_OFFSET 0 70#define TDES_XTEARNDR_XTEA_RNDS_OFFSET 0
71 71
72#define TDES_HW_VERSION 0xFC
73
72#define TDES_RPR 0x100 74#define TDES_RPR 0x100
73#define TDES_RCR 0x104 75#define TDES_RCR 0x104
74#define TDES_TPR 0x108 76#define TDES_TPR 0x108
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
index 7c73fbb17538..4a99564a08e6 100644
--- a/drivers/crypto/atmel-tdes.c
+++ b/drivers/crypto/atmel-tdes.c
@@ -38,29 +38,35 @@
38#include <crypto/des.h> 38#include <crypto/des.h>
39#include <crypto/hash.h> 39#include <crypto/hash.h>
40#include <crypto/internal/hash.h> 40#include <crypto/internal/hash.h>
41#include <linux/platform_data/crypto-atmel.h>
41#include "atmel-tdes-regs.h" 42#include "atmel-tdes-regs.h"
42 43
43/* TDES flags */ 44/* TDES flags */
44#define TDES_FLAGS_MODE_MASK 0x007f 45#define TDES_FLAGS_MODE_MASK 0x00ff
45#define TDES_FLAGS_ENCRYPT BIT(0) 46#define TDES_FLAGS_ENCRYPT BIT(0)
46#define TDES_FLAGS_CBC BIT(1) 47#define TDES_FLAGS_CBC BIT(1)
47#define TDES_FLAGS_CFB BIT(2) 48#define TDES_FLAGS_CFB BIT(2)
48#define TDES_FLAGS_CFB8 BIT(3) 49#define TDES_FLAGS_CFB8 BIT(3)
49#define TDES_FLAGS_CFB16 BIT(4) 50#define TDES_FLAGS_CFB16 BIT(4)
50#define TDES_FLAGS_CFB32 BIT(5) 51#define TDES_FLAGS_CFB32 BIT(5)
51#define TDES_FLAGS_OFB BIT(6) 52#define TDES_FLAGS_CFB64 BIT(6)
53#define TDES_FLAGS_OFB BIT(7)
52 54
53#define TDES_FLAGS_INIT BIT(16) 55#define TDES_FLAGS_INIT BIT(16)
54#define TDES_FLAGS_FAST BIT(17) 56#define TDES_FLAGS_FAST BIT(17)
55#define TDES_FLAGS_BUSY BIT(18) 57#define TDES_FLAGS_BUSY BIT(18)
58#define TDES_FLAGS_DMA BIT(19)
56 59
57#define ATMEL_TDES_QUEUE_LENGTH 1 60#define ATMEL_TDES_QUEUE_LENGTH 50
58 61
59#define CFB8_BLOCK_SIZE 1 62#define CFB8_BLOCK_SIZE 1
60#define CFB16_BLOCK_SIZE 2 63#define CFB16_BLOCK_SIZE 2
61#define CFB32_BLOCK_SIZE 4 64#define CFB32_BLOCK_SIZE 4
62#define CFB64_BLOCK_SIZE 8
63 65
66struct atmel_tdes_caps {
67 bool has_dma;
68 u32 has_cfb_3keys;
69};
64 70
65struct atmel_tdes_dev; 71struct atmel_tdes_dev;
66 72
@@ -70,12 +76,19 @@ struct atmel_tdes_ctx {
70 int keylen; 76 int keylen;
71 u32 key[3*DES_KEY_SIZE / sizeof(u32)]; 77 u32 key[3*DES_KEY_SIZE / sizeof(u32)];
72 unsigned long flags; 78 unsigned long flags;
79
80 u16 block_size;
73}; 81};
74 82
75struct atmel_tdes_reqctx { 83struct atmel_tdes_reqctx {
76 unsigned long mode; 84 unsigned long mode;
77}; 85};
78 86
87struct atmel_tdes_dma {
88 struct dma_chan *chan;
89 struct dma_slave_config dma_conf;
90};
91
79struct atmel_tdes_dev { 92struct atmel_tdes_dev {
80 struct list_head list; 93 struct list_head list;
81 unsigned long phys_base; 94 unsigned long phys_base;
@@ -99,8 +112,10 @@ struct atmel_tdes_dev {
99 size_t total; 112 size_t total;
100 113
101 struct scatterlist *in_sg; 114 struct scatterlist *in_sg;
115 unsigned int nb_in_sg;
102 size_t in_offset; 116 size_t in_offset;
103 struct scatterlist *out_sg; 117 struct scatterlist *out_sg;
118 unsigned int nb_out_sg;
104 size_t out_offset; 119 size_t out_offset;
105 120
106 size_t buflen; 121 size_t buflen;
@@ -109,10 +124,16 @@ struct atmel_tdes_dev {
109 void *buf_in; 124 void *buf_in;
110 int dma_in; 125 int dma_in;
111 dma_addr_t dma_addr_in; 126 dma_addr_t dma_addr_in;
127 struct atmel_tdes_dma dma_lch_in;
112 128
113 void *buf_out; 129 void *buf_out;
114 int dma_out; 130 int dma_out;
115 dma_addr_t dma_addr_out; 131 dma_addr_t dma_addr_out;
132 struct atmel_tdes_dma dma_lch_out;
133
134 struct atmel_tdes_caps caps;
135
136 u32 hw_version;
116}; 137};
117 138
118struct atmel_tdes_drv { 139struct atmel_tdes_drv {
@@ -207,6 +228,31 @@ static int atmel_tdes_hw_init(struct atmel_tdes_dev *dd)
207 return 0; 228 return 0;
208} 229}
209 230
231static inline unsigned int atmel_tdes_get_version(struct atmel_tdes_dev *dd)
232{
233 return atmel_tdes_read(dd, TDES_HW_VERSION) & 0x00000fff;
234}
235
236static void atmel_tdes_hw_version_init(struct atmel_tdes_dev *dd)
237{
238 atmel_tdes_hw_init(dd);
239
240 dd->hw_version = atmel_tdes_get_version(dd);
241
242 dev_info(dd->dev,
243 "version: 0x%x\n", dd->hw_version);
244
245 clk_disable_unprepare(dd->iclk);
246}
247
248static void atmel_tdes_dma_callback(void *data)
249{
250 struct atmel_tdes_dev *dd = data;
251
252 /* dma_lch_out - completed */
253 tasklet_schedule(&dd->done_task);
254}
255
210static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd) 256static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
211{ 257{
212 int err; 258 int err;
@@ -217,7 +263,9 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
217 if (err) 263 if (err)
218 return err; 264 return err;
219 265
220 atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS); 266 if (!dd->caps.has_dma)
267 atmel_tdes_write(dd, TDES_PTCR,
268 TDES_PTCR_TXTDIS | TDES_PTCR_RXTDIS);
221 269
222 /* MR register must be set before IV registers */ 270 /* MR register must be set before IV registers */
223 if (dd->ctx->keylen > (DES_KEY_SIZE << 1)) { 271 if (dd->ctx->keylen > (DES_KEY_SIZE << 1)) {
@@ -241,6 +289,8 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
241 valmr |= TDES_MR_CFBS_16b; 289 valmr |= TDES_MR_CFBS_16b;
242 else if (dd->flags & TDES_FLAGS_CFB32) 290 else if (dd->flags & TDES_FLAGS_CFB32)
243 valmr |= TDES_MR_CFBS_32b; 291 valmr |= TDES_MR_CFBS_32b;
292 else if (dd->flags & TDES_FLAGS_CFB64)
293 valmr |= TDES_MR_CFBS_64b;
244 } else if (dd->flags & TDES_FLAGS_OFB) { 294 } else if (dd->flags & TDES_FLAGS_OFB) {
245 valmr |= TDES_MR_OPMOD_OFB; 295 valmr |= TDES_MR_OPMOD_OFB;
246 } 296 }
@@ -262,7 +312,7 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
262 return 0; 312 return 0;
263} 313}
264 314
265static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd) 315static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd)
266{ 316{
267 int err = 0; 317 int err = 0;
268 size_t count; 318 size_t count;
@@ -288,7 +338,7 @@ static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd)
288 return err; 338 return err;
289} 339}
290 340
291static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) 341static int atmel_tdes_buff_init(struct atmel_tdes_dev *dd)
292{ 342{
293 int err = -ENOMEM; 343 int err = -ENOMEM;
294 344
@@ -333,7 +383,7 @@ err_alloc:
333 return err; 383 return err;
334} 384}
335 385
336static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd) 386static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd)
337{ 387{
338 dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen, 388 dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
339 DMA_FROM_DEVICE); 389 DMA_FROM_DEVICE);
@@ -343,7 +393,7 @@ static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd)
343 free_page((unsigned long)dd->buf_in); 393 free_page((unsigned long)dd->buf_in);
344} 394}
345 395
346static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, 396static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
347 dma_addr_t dma_addr_out, int length) 397 dma_addr_t dma_addr_out, int length)
348{ 398{
349 struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); 399 struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -379,7 +429,76 @@ static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
379 return 0; 429 return 0;
380} 430}
381 431
382static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd) 432static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
433 dma_addr_t dma_addr_out, int length)
434{
435 struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
436 struct atmel_tdes_dev *dd = ctx->dd;
437 struct scatterlist sg[2];
438 struct dma_async_tx_descriptor *in_desc, *out_desc;
439
440 dd->dma_size = length;
441
442 if (!(dd->flags & TDES_FLAGS_FAST)) {
443 dma_sync_single_for_device(dd->dev, dma_addr_in, length,
444 DMA_TO_DEVICE);
445 }
446
447 if (dd->flags & TDES_FLAGS_CFB8) {
448 dd->dma_lch_in.dma_conf.dst_addr_width =
449 DMA_SLAVE_BUSWIDTH_1_BYTE;
450 dd->dma_lch_out.dma_conf.src_addr_width =
451 DMA_SLAVE_BUSWIDTH_1_BYTE;
452 } else if (dd->flags & TDES_FLAGS_CFB16) {
453 dd->dma_lch_in.dma_conf.dst_addr_width =
454 DMA_SLAVE_BUSWIDTH_2_BYTES;
455 dd->dma_lch_out.dma_conf.src_addr_width =
456 DMA_SLAVE_BUSWIDTH_2_BYTES;
457 } else {
458 dd->dma_lch_in.dma_conf.dst_addr_width =
459 DMA_SLAVE_BUSWIDTH_4_BYTES;
460 dd->dma_lch_out.dma_conf.src_addr_width =
461 DMA_SLAVE_BUSWIDTH_4_BYTES;
462 }
463
464 dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf);
465 dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf);
466
467 dd->flags |= TDES_FLAGS_DMA;
468
469 sg_init_table(&sg[0], 1);
470 sg_dma_address(&sg[0]) = dma_addr_in;
471 sg_dma_len(&sg[0]) = length;
472
473 sg_init_table(&sg[1], 1);
474 sg_dma_address(&sg[1]) = dma_addr_out;
475 sg_dma_len(&sg[1]) = length;
476
477 in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg[0],
478 1, DMA_MEM_TO_DEV,
479 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
480 if (!in_desc)
481 return -EINVAL;
482
483 out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg[1],
484 1, DMA_DEV_TO_MEM,
485 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
486 if (!out_desc)
487 return -EINVAL;
488
489 out_desc->callback = atmel_tdes_dma_callback;
490 out_desc->callback_param = dd;
491
492 dmaengine_submit(out_desc);
493 dma_async_issue_pending(dd->dma_lch_out.chan);
494
495 dmaengine_submit(in_desc);
496 dma_async_issue_pending(dd->dma_lch_in.chan);
497
498 return 0;
499}
500
501static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd)
383{ 502{
384 struct crypto_tfm *tfm = crypto_ablkcipher_tfm( 503 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
385 crypto_ablkcipher_reqtfm(dd->req)); 504 crypto_ablkcipher_reqtfm(dd->req));
@@ -387,23 +506,23 @@ static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd)
387 size_t count; 506 size_t count;
388 dma_addr_t addr_in, addr_out; 507 dma_addr_t addr_in, addr_out;
389 508
390 if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) { 509 if ((!dd->in_offset) && (!dd->out_offset)) {
391 /* check for alignment */ 510 /* check for alignment */
392 in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)); 511 in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)) &&
393 out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)); 512 IS_ALIGNED(dd->in_sg->length, dd->ctx->block_size);
394 513 out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)) &&
514 IS_ALIGNED(dd->out_sg->length, dd->ctx->block_size);
395 fast = in && out; 515 fast = in && out;
516
517 if (sg_dma_len(dd->in_sg) != sg_dma_len(dd->out_sg))
518 fast = 0;
396 } 519 }
397 520
521
398 if (fast) { 522 if (fast) {
399 count = min(dd->total, sg_dma_len(dd->in_sg)); 523 count = min(dd->total, sg_dma_len(dd->in_sg));
400 count = min(count, sg_dma_len(dd->out_sg)); 524 count = min(count, sg_dma_len(dd->out_sg));
401 525
402 if (count != dd->total) {
403 pr_err("request length != buffer length\n");
404 return -EINVAL;
405 }
406
407 err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 526 err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
408 if (!err) { 527 if (!err) {
409 dev_err(dd->dev, "dma_map_sg() error\n"); 528 dev_err(dd->dev, "dma_map_sg() error\n");
@@ -433,13 +552,16 @@ static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd)
433 addr_out = dd->dma_addr_out; 552 addr_out = dd->dma_addr_out;
434 553
435 dd->flags &= ~TDES_FLAGS_FAST; 554 dd->flags &= ~TDES_FLAGS_FAST;
436
437 } 555 }
438 556
439 dd->total -= count; 557 dd->total -= count;
440 558
441 err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count); 559 if (dd->caps.has_dma)
442 if (err) { 560 err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count);
561 else
562 err = atmel_tdes_crypt_pdc(tfm, addr_in, addr_out, count);
563
564 if (err && (dd->flags & TDES_FLAGS_FAST)) {
443 dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 565 dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
444 dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); 566 dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
445 } 567 }
@@ -447,7 +569,6 @@ static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd)
447 return err; 569 return err;
448} 570}
449 571
450
451static void atmel_tdes_finish_req(struct atmel_tdes_dev *dd, int err) 572static void atmel_tdes_finish_req(struct atmel_tdes_dev *dd, int err)
452{ 573{
453 struct ablkcipher_request *req = dd->req; 574 struct ablkcipher_request *req = dd->req;
@@ -506,7 +627,7 @@ static int atmel_tdes_handle_queue(struct atmel_tdes_dev *dd,
506 627
507 err = atmel_tdes_write_ctrl(dd); 628 err = atmel_tdes_write_ctrl(dd);
508 if (!err) 629 if (!err)
509 err = atmel_tdes_crypt_dma_start(dd); 630 err = atmel_tdes_crypt_start(dd);
510 if (err) { 631 if (err) {
511 /* des_task will not finish it, so do it here */ 632 /* des_task will not finish it, so do it here */
512 atmel_tdes_finish_req(dd, err); 633 atmel_tdes_finish_req(dd, err);
@@ -516,41 +637,145 @@ static int atmel_tdes_handle_queue(struct atmel_tdes_dev *dd,
516 return ret; 637 return ret;
517} 638}
518 639
640static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd)
641{
642 int err = -EINVAL;
643 size_t count;
644
645 if (dd->flags & TDES_FLAGS_DMA) {
646 err = 0;
647 if (dd->flags & TDES_FLAGS_FAST) {
648 dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
649 dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
650 } else {
651 dma_sync_single_for_device(dd->dev, dd->dma_addr_out,
652 dd->dma_size, DMA_FROM_DEVICE);
653
654 /* copy data */
655 count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset,
656 dd->buf_out, dd->buflen, dd->dma_size, 1);
657 if (count != dd->dma_size) {
658 err = -EINVAL;
659 pr_err("not all data converted: %u\n", count);
660 }
661 }
662 }
663 return err;
664}
519 665
520static int atmel_tdes_crypt(struct ablkcipher_request *req, unsigned long mode) 666static int atmel_tdes_crypt(struct ablkcipher_request *req, unsigned long mode)
521{ 667{
522 struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx( 668 struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx(
523 crypto_ablkcipher_reqtfm(req)); 669 crypto_ablkcipher_reqtfm(req));
524 struct atmel_tdes_reqctx *rctx = ablkcipher_request_ctx(req); 670 struct atmel_tdes_reqctx *rctx = ablkcipher_request_ctx(req);
525 struct atmel_tdes_dev *dd;
526 671
527 if (mode & TDES_FLAGS_CFB8) { 672 if (mode & TDES_FLAGS_CFB8) {
528 if (!IS_ALIGNED(req->nbytes, CFB8_BLOCK_SIZE)) { 673 if (!IS_ALIGNED(req->nbytes, CFB8_BLOCK_SIZE)) {
529 pr_err("request size is not exact amount of CFB8 blocks\n"); 674 pr_err("request size is not exact amount of CFB8 blocks\n");
530 return -EINVAL; 675 return -EINVAL;
531 } 676 }
677 ctx->block_size = CFB8_BLOCK_SIZE;
532 } else if (mode & TDES_FLAGS_CFB16) { 678 } else if (mode & TDES_FLAGS_CFB16) {
533 if (!IS_ALIGNED(req->nbytes, CFB16_BLOCK_SIZE)) { 679 if (!IS_ALIGNED(req->nbytes, CFB16_BLOCK_SIZE)) {
534 pr_err("request size is not exact amount of CFB16 blocks\n"); 680 pr_err("request size is not exact amount of CFB16 blocks\n");
535 return -EINVAL; 681 return -EINVAL;
536 } 682 }
683 ctx->block_size = CFB16_BLOCK_SIZE;
537 } else if (mode & TDES_FLAGS_CFB32) { 684 } else if (mode & TDES_FLAGS_CFB32) {
538 if (!IS_ALIGNED(req->nbytes, CFB32_BLOCK_SIZE)) { 685 if (!IS_ALIGNED(req->nbytes, CFB32_BLOCK_SIZE)) {
539 pr_err("request size is not exact amount of CFB32 blocks\n"); 686 pr_err("request size is not exact amount of CFB32 blocks\n");
540 return -EINVAL; 687 return -EINVAL;
541 } 688 }
542 } else if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { 689 ctx->block_size = CFB32_BLOCK_SIZE;
543 pr_err("request size is not exact amount of DES blocks\n"); 690 } else {
544 return -EINVAL; 691 if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) {
692 pr_err("request size is not exact amount of DES blocks\n");
693 return -EINVAL;
694 }
695 ctx->block_size = DES_BLOCK_SIZE;
545 } 696 }
546 697
547 dd = atmel_tdes_find_dev(ctx); 698 rctx->mode = mode;
548 if (!dd) 699
700 return atmel_tdes_handle_queue(ctx->dd, req);
701}
702
703static bool atmel_tdes_filter(struct dma_chan *chan, void *slave)
704{
705 struct at_dma_slave *sl = slave;
706
707 if (sl && sl->dma_dev == chan->device->dev) {
708 chan->private = sl;
709 return true;
710 } else {
711 return false;
712 }
713}
714
715static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd,
716 struct crypto_platform_data *pdata)
717{
718 int err = -ENOMEM;
719 dma_cap_mask_t mask_in, mask_out;
720
721 if (pdata && pdata->dma_slave->txdata.dma_dev &&
722 pdata->dma_slave->rxdata.dma_dev) {
723
724 /* Try to grab 2 DMA channels */
725 dma_cap_zero(mask_in);
726 dma_cap_set(DMA_SLAVE, mask_in);
727
728 dd->dma_lch_in.chan = dma_request_channel(mask_in,
729 atmel_tdes_filter, &pdata->dma_slave->rxdata);
730
731 if (!dd->dma_lch_in.chan)
732 goto err_dma_in;
733
734 dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
735 dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
736 TDES_IDATA1R;
737 dd->dma_lch_in.dma_conf.src_maxburst = 1;
738 dd->dma_lch_in.dma_conf.src_addr_width =
739 DMA_SLAVE_BUSWIDTH_4_BYTES;
740 dd->dma_lch_in.dma_conf.dst_maxburst = 1;
741 dd->dma_lch_in.dma_conf.dst_addr_width =
742 DMA_SLAVE_BUSWIDTH_4_BYTES;
743 dd->dma_lch_in.dma_conf.device_fc = false;
744
745 dma_cap_zero(mask_out);
746 dma_cap_set(DMA_SLAVE, mask_out);
747 dd->dma_lch_out.chan = dma_request_channel(mask_out,
748 atmel_tdes_filter, &pdata->dma_slave->txdata);
749
750 if (!dd->dma_lch_out.chan)
751 goto err_dma_out;
752
753 dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
754 dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
755 TDES_ODATA1R;
756 dd->dma_lch_out.dma_conf.src_maxburst = 1;
757 dd->dma_lch_out.dma_conf.src_addr_width =
758 DMA_SLAVE_BUSWIDTH_4_BYTES;
759 dd->dma_lch_out.dma_conf.dst_maxburst = 1;
760 dd->dma_lch_out.dma_conf.dst_addr_width =
761 DMA_SLAVE_BUSWIDTH_4_BYTES;
762 dd->dma_lch_out.dma_conf.device_fc = false;
763
764 return 0;
765 } else {
549 return -ENODEV; 766 return -ENODEV;
767 }
550 768
551 rctx->mode = mode; 769err_dma_out:
770 dma_release_channel(dd->dma_lch_in.chan);
771err_dma_in:
772 return err;
773}
552 774
553 return atmel_tdes_handle_queue(dd, req); 775static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd)
776{
777 dma_release_channel(dd->dma_lch_in.chan);
778 dma_release_channel(dd->dma_lch_out.chan);
554} 779}
555 780
556static int atmel_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, 781static int atmel_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
@@ -590,7 +815,8 @@ static int atmel_tdes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
590 /* 815 /*
591 * HW bug in cfb 3-keys mode. 816 * HW bug in cfb 3-keys mode.
592 */ 817 */
593 if (strstr(alg_name, "cfb") && (keylen != 2*DES_KEY_SIZE)) { 818 if (!ctx->dd->caps.has_cfb_3keys && strstr(alg_name, "cfb")
819 && (keylen != 2*DES_KEY_SIZE)) {
594 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 820 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
595 return -EINVAL; 821 return -EINVAL;
596 } else if ((keylen != 2*DES_KEY_SIZE) && (keylen != 3*DES_KEY_SIZE)) { 822 } else if ((keylen != 2*DES_KEY_SIZE) && (keylen != 3*DES_KEY_SIZE)) {
@@ -678,8 +904,15 @@ static int atmel_tdes_ofb_decrypt(struct ablkcipher_request *req)
678 904
679static int atmel_tdes_cra_init(struct crypto_tfm *tfm) 905static int atmel_tdes_cra_init(struct crypto_tfm *tfm)
680{ 906{
907 struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
908 struct atmel_tdes_dev *dd;
909
681 tfm->crt_ablkcipher.reqsize = sizeof(struct atmel_tdes_reqctx); 910 tfm->crt_ablkcipher.reqsize = sizeof(struct atmel_tdes_reqctx);
682 911
912 dd = atmel_tdes_find_dev(ctx);
913 if (!dd)
914 return -ENODEV;
915
683 return 0; 916 return 0;
684} 917}
685 918
@@ -695,7 +928,7 @@ static struct crypto_alg tdes_algs[] = {
695 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 928 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
696 .cra_blocksize = DES_BLOCK_SIZE, 929 .cra_blocksize = DES_BLOCK_SIZE,
697 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 930 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
698 .cra_alignmask = 0, 931 .cra_alignmask = 0x7,
699 .cra_type = &crypto_ablkcipher_type, 932 .cra_type = &crypto_ablkcipher_type,
700 .cra_module = THIS_MODULE, 933 .cra_module = THIS_MODULE,
701 .cra_init = atmel_tdes_cra_init, 934 .cra_init = atmel_tdes_cra_init,
@@ -715,7 +948,7 @@ static struct crypto_alg tdes_algs[] = {
715 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 948 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
716 .cra_blocksize = DES_BLOCK_SIZE, 949 .cra_blocksize = DES_BLOCK_SIZE,
717 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 950 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
718 .cra_alignmask = 0, 951 .cra_alignmask = 0x7,
719 .cra_type = &crypto_ablkcipher_type, 952 .cra_type = &crypto_ablkcipher_type,
720 .cra_module = THIS_MODULE, 953 .cra_module = THIS_MODULE,
721 .cra_init = atmel_tdes_cra_init, 954 .cra_init = atmel_tdes_cra_init,
@@ -736,7 +969,7 @@ static struct crypto_alg tdes_algs[] = {
736 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 969 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
737 .cra_blocksize = DES_BLOCK_SIZE, 970 .cra_blocksize = DES_BLOCK_SIZE,
738 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 971 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
739 .cra_alignmask = 0, 972 .cra_alignmask = 0x7,
740 .cra_type = &crypto_ablkcipher_type, 973 .cra_type = &crypto_ablkcipher_type,
741 .cra_module = THIS_MODULE, 974 .cra_module = THIS_MODULE,
742 .cra_init = atmel_tdes_cra_init, 975 .cra_init = atmel_tdes_cra_init,
@@ -778,7 +1011,7 @@ static struct crypto_alg tdes_algs[] = {
778 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1011 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
779 .cra_blocksize = CFB16_BLOCK_SIZE, 1012 .cra_blocksize = CFB16_BLOCK_SIZE,
780 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1013 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
781 .cra_alignmask = 0, 1014 .cra_alignmask = 0x1,
782 .cra_type = &crypto_ablkcipher_type, 1015 .cra_type = &crypto_ablkcipher_type,
783 .cra_module = THIS_MODULE, 1016 .cra_module = THIS_MODULE,
784 .cra_init = atmel_tdes_cra_init, 1017 .cra_init = atmel_tdes_cra_init,
@@ -799,7 +1032,7 @@ static struct crypto_alg tdes_algs[] = {
799 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1032 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
800 .cra_blocksize = CFB32_BLOCK_SIZE, 1033 .cra_blocksize = CFB32_BLOCK_SIZE,
801 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1034 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
802 .cra_alignmask = 0, 1035 .cra_alignmask = 0x3,
803 .cra_type = &crypto_ablkcipher_type, 1036 .cra_type = &crypto_ablkcipher_type,
804 .cra_module = THIS_MODULE, 1037 .cra_module = THIS_MODULE,
805 .cra_init = atmel_tdes_cra_init, 1038 .cra_init = atmel_tdes_cra_init,
@@ -820,7 +1053,7 @@ static struct crypto_alg tdes_algs[] = {
820 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1053 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
821 .cra_blocksize = DES_BLOCK_SIZE, 1054 .cra_blocksize = DES_BLOCK_SIZE,
822 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1055 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
823 .cra_alignmask = 0, 1056 .cra_alignmask = 0x7,
824 .cra_type = &crypto_ablkcipher_type, 1057 .cra_type = &crypto_ablkcipher_type,
825 .cra_module = THIS_MODULE, 1058 .cra_module = THIS_MODULE,
826 .cra_init = atmel_tdes_cra_init, 1059 .cra_init = atmel_tdes_cra_init,
@@ -841,7 +1074,7 @@ static struct crypto_alg tdes_algs[] = {
841 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1074 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
842 .cra_blocksize = DES_BLOCK_SIZE, 1075 .cra_blocksize = DES_BLOCK_SIZE,
843 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1076 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
844 .cra_alignmask = 0, 1077 .cra_alignmask = 0x7,
845 .cra_type = &crypto_ablkcipher_type, 1078 .cra_type = &crypto_ablkcipher_type,
846 .cra_module = THIS_MODULE, 1079 .cra_module = THIS_MODULE,
847 .cra_init = atmel_tdes_cra_init, 1080 .cra_init = atmel_tdes_cra_init,
@@ -861,7 +1094,7 @@ static struct crypto_alg tdes_algs[] = {
861 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1094 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
862 .cra_blocksize = DES_BLOCK_SIZE, 1095 .cra_blocksize = DES_BLOCK_SIZE,
863 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1096 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
864 .cra_alignmask = 0, 1097 .cra_alignmask = 0x7,
865 .cra_type = &crypto_ablkcipher_type, 1098 .cra_type = &crypto_ablkcipher_type,
866 .cra_module = THIS_MODULE, 1099 .cra_module = THIS_MODULE,
867 .cra_init = atmel_tdes_cra_init, 1100 .cra_init = atmel_tdes_cra_init,
@@ -882,7 +1115,7 @@ static struct crypto_alg tdes_algs[] = {
882 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1115 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
883 .cra_blocksize = DES_BLOCK_SIZE, 1116 .cra_blocksize = DES_BLOCK_SIZE,
884 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1117 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
885 .cra_alignmask = 0, 1118 .cra_alignmask = 0x7,
886 .cra_type = &crypto_ablkcipher_type, 1119 .cra_type = &crypto_ablkcipher_type,
887 .cra_module = THIS_MODULE, 1120 .cra_module = THIS_MODULE,
888 .cra_init = atmel_tdes_cra_init, 1121 .cra_init = atmel_tdes_cra_init,
@@ -924,7 +1157,7 @@ static struct crypto_alg tdes_algs[] = {
924 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1157 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
925 .cra_blocksize = CFB16_BLOCK_SIZE, 1158 .cra_blocksize = CFB16_BLOCK_SIZE,
926 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1159 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
927 .cra_alignmask = 0, 1160 .cra_alignmask = 0x1,
928 .cra_type = &crypto_ablkcipher_type, 1161 .cra_type = &crypto_ablkcipher_type,
929 .cra_module = THIS_MODULE, 1162 .cra_module = THIS_MODULE,
930 .cra_init = atmel_tdes_cra_init, 1163 .cra_init = atmel_tdes_cra_init,
@@ -945,7 +1178,7 @@ static struct crypto_alg tdes_algs[] = {
945 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1178 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
946 .cra_blocksize = CFB32_BLOCK_SIZE, 1179 .cra_blocksize = CFB32_BLOCK_SIZE,
947 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1180 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
948 .cra_alignmask = 0, 1181 .cra_alignmask = 0x3,
949 .cra_type = &crypto_ablkcipher_type, 1182 .cra_type = &crypto_ablkcipher_type,
950 .cra_module = THIS_MODULE, 1183 .cra_module = THIS_MODULE,
951 .cra_init = atmel_tdes_cra_init, 1184 .cra_init = atmel_tdes_cra_init,
@@ -966,7 +1199,7 @@ static struct crypto_alg tdes_algs[] = {
966 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1199 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
967 .cra_blocksize = DES_BLOCK_SIZE, 1200 .cra_blocksize = DES_BLOCK_SIZE,
968 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1201 .cra_ctxsize = sizeof(struct atmel_tdes_ctx),
969 .cra_alignmask = 0, 1202 .cra_alignmask = 0x7,
970 .cra_type = &crypto_ablkcipher_type, 1203 .cra_type = &crypto_ablkcipher_type,
971 .cra_module = THIS_MODULE, 1204 .cra_module = THIS_MODULE,
972 .cra_init = atmel_tdes_cra_init, 1205 .cra_init = atmel_tdes_cra_init,
@@ -994,14 +1227,24 @@ static void atmel_tdes_done_task(unsigned long data)
994 struct atmel_tdes_dev *dd = (struct atmel_tdes_dev *) data; 1227 struct atmel_tdes_dev *dd = (struct atmel_tdes_dev *) data;
995 int err; 1228 int err;
996 1229
997 err = atmel_tdes_crypt_dma_stop(dd); 1230 if (!(dd->flags & TDES_FLAGS_DMA))
1231 err = atmel_tdes_crypt_pdc_stop(dd);
1232 else
1233 err = atmel_tdes_crypt_dma_stop(dd);
998 1234
999 err = dd->err ? : err; 1235 err = dd->err ? : err;
1000 1236
1001 if (dd->total && !err) { 1237 if (dd->total && !err) {
1002 err = atmel_tdes_crypt_dma_start(dd); 1238 if (dd->flags & TDES_FLAGS_FAST) {
1239 dd->in_sg = sg_next(dd->in_sg);
1240 dd->out_sg = sg_next(dd->out_sg);
1241 if (!dd->in_sg || !dd->out_sg)
1242 err = -EINVAL;
1243 }
1003 if (!err) 1244 if (!err)
1004 return; 1245 err = atmel_tdes_crypt_start(dd);
1246 if (!err)
1247 return; /* DMA started. Not fininishing. */
1005 } 1248 }
1006 1249
1007 atmel_tdes_finish_req(dd, err); 1250 atmel_tdes_finish_req(dd, err);
@@ -1053,9 +1296,31 @@ err_tdes_algs:
1053 return err; 1296 return err;
1054} 1297}
1055 1298
1299static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd)
1300{
1301
1302 dd->caps.has_dma = 0;
1303 dd->caps.has_cfb_3keys = 0;
1304
1305 /* keep only major version number */
1306 switch (dd->hw_version & 0xf00) {
1307 case 0x700:
1308 dd->caps.has_dma = 1;
1309 dd->caps.has_cfb_3keys = 1;
1310 break;
1311 case 0x600:
1312 break;
1313 default:
1314 dev_warn(dd->dev,
1315 "Unmanaged tdes version, set minimum capabilities\n");
1316 break;
1317 }
1318}
1319
1056static int atmel_tdes_probe(struct platform_device *pdev) 1320static int atmel_tdes_probe(struct platform_device *pdev)
1057{ 1321{
1058 struct atmel_tdes_dev *tdes_dd; 1322 struct atmel_tdes_dev *tdes_dd;
1323 struct crypto_platform_data *pdata;
1059 struct device *dev = &pdev->dev; 1324 struct device *dev = &pdev->dev;
1060 struct resource *tdes_res; 1325 struct resource *tdes_res;
1061 unsigned long tdes_phys_size; 1326 unsigned long tdes_phys_size;
@@ -1109,7 +1374,7 @@ static int atmel_tdes_probe(struct platform_device *pdev)
1109 } 1374 }
1110 1375
1111 /* Initializing the clock */ 1376 /* Initializing the clock */
1112 tdes_dd->iclk = clk_get(&pdev->dev, NULL); 1377 tdes_dd->iclk = clk_get(&pdev->dev, "tdes_clk");
1113 if (IS_ERR(tdes_dd->iclk)) { 1378 if (IS_ERR(tdes_dd->iclk)) {
1114 dev_err(dev, "clock intialization failed.\n"); 1379 dev_err(dev, "clock intialization failed.\n");
1115 err = PTR_ERR(tdes_dd->iclk); 1380 err = PTR_ERR(tdes_dd->iclk);
@@ -1123,9 +1388,25 @@ static int atmel_tdes_probe(struct platform_device *pdev)
1123 goto tdes_io_err; 1388 goto tdes_io_err;
1124 } 1389 }
1125 1390
1126 err = atmel_tdes_dma_init(tdes_dd); 1391 atmel_tdes_hw_version_init(tdes_dd);
1392
1393 atmel_tdes_get_cap(tdes_dd);
1394
1395 err = atmel_tdes_buff_init(tdes_dd);
1127 if (err) 1396 if (err)
1128 goto err_tdes_dma; 1397 goto err_tdes_buff;
1398
1399 if (tdes_dd->caps.has_dma) {
1400 pdata = pdev->dev.platform_data;
1401 if (!pdata) {
1402 dev_err(&pdev->dev, "platform data not available\n");
1403 err = -ENXIO;
1404 goto err_pdata;
1405 }
1406 err = atmel_tdes_dma_init(tdes_dd, pdata);
1407 if (err)
1408 goto err_tdes_dma;
1409 }
1129 1410
1130 spin_lock(&atmel_tdes.lock); 1411 spin_lock(&atmel_tdes.lock);
1131 list_add_tail(&tdes_dd->list, &atmel_tdes.dev_list); 1412 list_add_tail(&tdes_dd->list, &atmel_tdes.dev_list);
@@ -1143,8 +1424,12 @@ err_algs:
1143 spin_lock(&atmel_tdes.lock); 1424 spin_lock(&atmel_tdes.lock);
1144 list_del(&tdes_dd->list); 1425 list_del(&tdes_dd->list);
1145 spin_unlock(&atmel_tdes.lock); 1426 spin_unlock(&atmel_tdes.lock);
1146 atmel_tdes_dma_cleanup(tdes_dd); 1427 if (tdes_dd->caps.has_dma)
1428 atmel_tdes_dma_cleanup(tdes_dd);
1147err_tdes_dma: 1429err_tdes_dma:
1430err_pdata:
1431 atmel_tdes_buff_cleanup(tdes_dd);
1432err_tdes_buff:
1148 iounmap(tdes_dd->io_base); 1433 iounmap(tdes_dd->io_base);
1149tdes_io_err: 1434tdes_io_err:
1150 clk_put(tdes_dd->iclk); 1435 clk_put(tdes_dd->iclk);
@@ -1178,7 +1463,10 @@ static int atmel_tdes_remove(struct platform_device *pdev)
1178 tasklet_kill(&tdes_dd->done_task); 1463 tasklet_kill(&tdes_dd->done_task);
1179 tasklet_kill(&tdes_dd->queue_task); 1464 tasklet_kill(&tdes_dd->queue_task);
1180 1465
1181 atmel_tdes_dma_cleanup(tdes_dd); 1466 if (tdes_dd->caps.has_dma)
1467 atmel_tdes_dma_cleanup(tdes_dd);
1468
1469 atmel_tdes_buff_cleanup(tdes_dd);
1182 1470
1183 iounmap(tdes_dd->io_base); 1471 iounmap(tdes_dd->io_base);
1184 1472