Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nicolas Royer and committed by
Herbert Xu
1f858040 cadc4ab8

+344 -54
+2
drivers/crypto/atmel-tdes-regs.h
··· 69 69 #define TDES_XTEARNDR_XTEA_RNDS_MASK (0x3F << 0) 70 70 #define TDES_XTEARNDR_XTEA_RNDS_OFFSET 0 71 71 72 + #define TDES_HW_VERSION 0xFC 73 + 72 74 #define TDES_RPR 0x100 73 75 #define TDES_RCR 0x104 74 76 #define TDES_TPR 0x108
+342 -54
drivers/crypto/atmel-tdes.c
··· 38 38 #include <crypto/des.h> 39 39 #include <crypto/hash.h> 40 40 #include <crypto/internal/hash.h> 41 + #include <linux/platform_data/crypto-atmel.h> 41 42 #include "atmel-tdes-regs.h" 42 43 43 44 /* TDES flags */ 44 - #define TDES_FLAGS_MODE_MASK 0x007f 45 + #define TDES_FLAGS_MODE_MASK 0x00ff 45 46 #define TDES_FLAGS_ENCRYPT BIT(0) 46 47 #define TDES_FLAGS_CBC BIT(1) 47 48 #define TDES_FLAGS_CFB BIT(2) 48 49 #define TDES_FLAGS_CFB8 BIT(3) 49 50 #define TDES_FLAGS_CFB16 BIT(4) 50 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 55 #define TDES_FLAGS_INIT BIT(16) 54 56 #define TDES_FLAGS_FAST BIT(17) 55 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 62 #define CFB8_BLOCK_SIZE 1 60 63 #define CFB16_BLOCK_SIZE 2 61 64 #define CFB32_BLOCK_SIZE 4 62 - #define CFB64_BLOCK_SIZE 8 63 65 66 + struct atmel_tdes_caps { 67 + bool has_dma; 68 + u32 has_cfb_3keys; 69 + }; 64 70 65 71 struct atmel_tdes_dev; 66 72 ··· 76 70 int keylen; 77 71 u32 key[3*DES_KEY_SIZE / sizeof(u32)]; 78 72 unsigned long flags; 73 + 74 + u16 block_size; 79 75 }; 80 76 81 77 struct atmel_tdes_reqctx { 82 78 unsigned long mode; 79 + }; 80 + 81 + struct atmel_tdes_dma { 82 + struct dma_chan *chan; 83 + struct dma_slave_config dma_conf; 83 84 }; 84 85 85 86 struct atmel_tdes_dev { ··· 112 99 size_t total; 113 100 114 101 struct scatterlist *in_sg; 102 + unsigned int nb_in_sg; 115 103 size_t in_offset; 116 104 struct scatterlist *out_sg; 105 + unsigned int nb_out_sg; 117 106 size_t out_offset; 118 107 119 108 size_t buflen; ··· 124 109 void *buf_in; 125 110 int dma_in; 126 111 dma_addr_t dma_addr_in; 112 + struct atmel_tdes_dma dma_lch_in; 127 113 128 114 void *buf_out; 129 115 int dma_out; 130 116 dma_addr_t dma_addr_out; 117 + struct atmel_tdes_dma dma_lch_out; 118 + 119 + struct atmel_tdes_caps caps; 120 + 121 + u32 hw_version; 131 122 }; 132 123 133 124 struct atmel_tdes_drv { ··· 228 207 return 0; 229 208 } 230 209 210 + static inline unsigned int atmel_tdes_get_version(struct atmel_tdes_dev *dd) 211 + { 212 + return atmel_tdes_read(dd, TDES_HW_VERSION) & 0x00000fff; 213 + } 214 + 215 + static void atmel_tdes_hw_version_init(struct atmel_tdes_dev *dd) 216 + { 217 + atmel_tdes_hw_init(dd); 218 + 219 + dd->hw_version = atmel_tdes_get_version(dd); 220 + 221 + dev_info(dd->dev, 222 + "version: 0x%x\n", dd->hw_version); 223 + 224 + clk_disable_unprepare(dd->iclk); 225 + } 226 + 227 + static void atmel_tdes_dma_callback(void *data) 228 + { 229 + struct atmel_tdes_dev *dd = data; 230 + 231 + /* dma_lch_out - completed */ 232 + tasklet_schedule(&dd->done_task); 233 + } 234 + 231 235 static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd) 232 236 { 233 237 int err; ··· 263 217 if (err) 264 218 return err; 265 219 266 - atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS); 220 + if (!dd->caps.has_dma) 221 + atmel_tdes_write(dd, TDES_PTCR, 222 + TDES_PTCR_TXTDIS | TDES_PTCR_RXTDIS); 267 223 268 224 /* MR register must be set before IV registers */ 269 225 if (dd->ctx->keylen > (DES_KEY_SIZE << 1)) { ··· 289 241 valmr |= TDES_MR_CFBS_16b; 290 242 else if (dd->flags & TDES_FLAGS_CFB32) 291 243 valmr |= TDES_MR_CFBS_32b; 244 + else if (dd->flags & TDES_FLAGS_CFB64) 245 + valmr |= TDES_MR_CFBS_64b; 292 246 } else if (dd->flags & TDES_FLAGS_OFB) { 293 247 valmr |= TDES_MR_OPMOD_OFB; 294 248 } ··· 312 262 return 0; 313 263 } 314 264 315 - static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd) 265 + static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd) 316 266 { 317 267 int err = 0; 318 268 size_t count; ··· 338 288 return err; 339 289 } 340 290 341 - static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) 291 + static int atmel_tdes_buff_init(struct atmel_tdes_dev *dd) 342 292 { 343 293 int err = -ENOMEM; 344 294 ··· 383 333 return err; 384 334 } 385 335 386 - static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd) 336 + static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd) 387 337 { 388 338 dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen, 389 339 DMA_FROM_DEVICE); ··· 393 343 free_page((unsigned long)dd->buf_in); 394 344 } 395 345 396 - static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, 346 + static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, 397 347 dma_addr_t dma_addr_out, int length) 398 348 { 399 349 struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); ··· 429 379 return 0; 430 380 } 431 381 432 - static int atmel_tdes_crypt_dma_start(struct atmel_tdes_dev *dd) 382 + static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, 383 + dma_addr_t dma_addr_out, int length) 384 + { 385 + struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); 386 + struct atmel_tdes_dev *dd = ctx->dd; 387 + struct scatterlist sg[2]; 388 + struct dma_async_tx_descriptor *in_desc, *out_desc; 389 + 390 + dd->dma_size = length; 391 + 392 + if (!(dd->flags & TDES_FLAGS_FAST)) { 393 + dma_sync_single_for_device(dd->dev, dma_addr_in, length, 394 + DMA_TO_DEVICE); 395 + } 396 + 397 + if (dd->flags & TDES_FLAGS_CFB8) { 398 + dd->dma_lch_in.dma_conf.dst_addr_width = 399 + DMA_SLAVE_BUSWIDTH_1_BYTE; 400 + dd->dma_lch_out.dma_conf.src_addr_width = 401 + DMA_SLAVE_BUSWIDTH_1_BYTE; 402 + } else if (dd->flags & TDES_FLAGS_CFB16) { 403 + dd->dma_lch_in.dma_conf.dst_addr_width = 404 + DMA_SLAVE_BUSWIDTH_2_BYTES; 405 + dd->dma_lch_out.dma_conf.src_addr_width = 406 + DMA_SLAVE_BUSWIDTH_2_BYTES; 407 + } else { 408 + dd->dma_lch_in.dma_conf.dst_addr_width = 409 + DMA_SLAVE_BUSWIDTH_4_BYTES; 410 + dd->dma_lch_out.dma_conf.src_addr_width = 411 + DMA_SLAVE_BUSWIDTH_4_BYTES; 412 + } 413 + 414 + dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); 415 + dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf); 416 + 417 + dd->flags |= TDES_FLAGS_DMA; 418 + 419 + sg_init_table(&sg[0], 1); 420 + sg_dma_address(&sg[0]) = dma_addr_in; 421 + sg_dma_len(&sg[0]) = length; 422 + 423 + sg_init_table(&sg[1], 1); 424 + sg_dma_address(&sg[1]) = dma_addr_out; 425 + sg_dma_len(&sg[1]) = length; 426 + 427 + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg[0], 428 + 1, DMA_MEM_TO_DEV, 429 + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 430 + if (!in_desc) 431 + return -EINVAL; 432 + 433 + out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg[1], 434 + 1, DMA_DEV_TO_MEM, 435 + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 436 + if (!out_desc) 437 + return -EINVAL; 438 + 439 + out_desc->callback = atmel_tdes_dma_callback; 440 + out_desc->callback_param = dd; 441 + 442 + dmaengine_submit(out_desc); 443 + dma_async_issue_pending(dd->dma_lch_out.chan); 444 + 445 + dmaengine_submit(in_desc); 446 + dma_async_issue_pending(dd->dma_lch_in.chan); 447 + 448 + return 0; 449 + } 450 + 451 + static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd) 433 452 { 434 453 struct crypto_tfm *tfm = crypto_ablkcipher_tfm( 435 454 crypto_ablkcipher_reqtfm(dd->req)); ··· 506 387 size_t count; 507 388 dma_addr_t addr_in, addr_out; 508 389 509 - if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) { 390 + if ((!dd->in_offset) && (!dd->out_offset)) { 510 391 /* check for alignment */ 511 - in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)); 512 - out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)); 513 - 392 + in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32)) && 393 + IS_ALIGNED(dd->in_sg->length, dd->ctx->block_size); 394 + out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32)) && 395 + IS_ALIGNED(dd->out_sg->length, dd->ctx->block_size); 514 396 fast = in && out; 397 + 398 + if (sg_dma_len(dd->in_sg) != sg_dma_len(dd->out_sg)) 399 + fast = 0; 515 400 } 401 + 516 402 517 403 if (fast) { 518 404 count = min(dd->total, sg_dma_len(dd->in_sg)); 519 405 count = min(count, sg_dma_len(dd->out_sg)); 520 - 521 - if (count != dd->total) { 522 - pr_err("request length != buffer length\n"); 523 - return -EINVAL; 524 - } 525 406 526 407 err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 527 408 if (!err) { ··· 552 433 addr_out = dd->dma_addr_out; 553 434 554 435 dd->flags &= ~TDES_FLAGS_FAST; 555 - 556 436 } 557 437 558 438 dd->total -= count; 559 439 560 - err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count); 561 - if (err) { 440 + if (dd->caps.has_dma) 441 + err = atmel_tdes_crypt_dma(tfm, addr_in, addr_out, count); 442 + else 443 + err = atmel_tdes_crypt_pdc(tfm, addr_in, addr_out, count); 444 + 445 + if (err && (dd->flags & TDES_FLAGS_FAST)) { 562 446 dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 563 447 dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); 564 448 } 565 449 566 450 return err; 567 451 } 568 - 569 452 570 453 static void atmel_tdes_finish_req(struct atmel_tdes_dev *dd, int err) 571 454 { ··· 627 506 628 507 err = atmel_tdes_write_ctrl(dd); 629 508 if (!err) 630 - err = atmel_tdes_crypt_dma_start(dd); 509 + err = atmel_tdes_crypt_start(dd); 631 510 if (err) { 632 511 /* des_task will not finish it, so do it here */ 633 512 atmel_tdes_finish_req(dd, err); ··· 637 516 return ret; 638 517 } 639 518 519 + static int atmel_tdes_crypt_dma_stop(struct atmel_tdes_dev *dd) 520 + { 521 + int err = -EINVAL; 522 + size_t count; 523 + 524 + if (dd->flags & TDES_FLAGS_DMA) { 525 + err = 0; 526 + if (dd->flags & TDES_FLAGS_FAST) { 527 + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); 528 + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 529 + } else { 530 + dma_sync_single_for_device(dd->dev, dd->dma_addr_out, 531 + dd->dma_size, DMA_FROM_DEVICE); 532 + 533 + /* copy data */ 534 + count = atmel_tdes_sg_copy(&dd->out_sg, &dd->out_offset, 535 + dd->buf_out, dd->buflen, dd->dma_size, 1); 536 + if (count != dd->dma_size) { 537 + err = -EINVAL; 538 + pr_err("not all data converted: %u\n", count); 539 + } 540 + } 541 + } 542 + return err; 543 + } 640 544 641 545 static int atmel_tdes_crypt(struct ablkcipher_request *req, unsigned long mode) 642 546 { 643 547 struct atmel_tdes_ctx *ctx = crypto_ablkcipher_ctx( 644 548 crypto_ablkcipher_reqtfm(req)); 645 549 struct atmel_tdes_reqctx *rctx = ablkcipher_request_ctx(req); 646 - struct atmel_tdes_dev *dd; 647 550 648 551 if (mode & TDES_FLAGS_CFB8) { 649 552 if (!IS_ALIGNED(req->nbytes, CFB8_BLOCK_SIZE)) { 650 553 pr_err("request size is not exact amount of CFB8 blocks\n"); 651 554 return -EINVAL; 652 555 } 556 + ctx->block_size = CFB8_BLOCK_SIZE; 653 557 } else if (mode & TDES_FLAGS_CFB16) { 654 558 if (!IS_ALIGNED(req->nbytes, CFB16_BLOCK_SIZE)) { 655 559 pr_err("request size is not exact amount of CFB16 blocks\n"); 656 560 return -EINVAL; 657 561 } 562 + ctx->block_size = CFB16_BLOCK_SIZE; 658 563 } else if (mode & TDES_FLAGS_CFB32) { 659 564 if (!IS_ALIGNED(req->nbytes, CFB32_BLOCK_SIZE)) { 660 565 pr_err("request size is not exact amount of CFB32 blocks\n"); 661 566 return -EINVAL; 662 567 } 663 - } else if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { 664 - pr_err("request size is not exact amount of DES blocks\n"); 665 - return -EINVAL; 568 + ctx->block_size = CFB32_BLOCK_SIZE; 569 + } else { 570 + if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { 571 + pr_err("request size is not exact amount of DES blocks\n"); 572 + return -EINVAL; 573 + } 574 + ctx->block_size = DES_BLOCK_SIZE; 666 575 } 667 - 668 - dd = atmel_tdes_find_dev(ctx); 669 - if (!dd) 670 - return -ENODEV; 671 576 672 577 rctx->mode = mode; 673 578 674 - return atmel_tdes_handle_queue(dd, req); 579 + return atmel_tdes_handle_queue(ctx->dd, req); 580 + } 581 + 582 + static bool atmel_tdes_filter(struct dma_chan *chan, void *slave) 583 + { 584 + struct at_dma_slave *sl = slave; 585 + 586 + if (sl && sl->dma_dev == chan->device->dev) { 587 + chan->private = sl; 588 + return true; 589 + } else { 590 + return false; 591 + } 592 + } 593 + 594 + static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd, 595 + struct crypto_platform_data *pdata) 596 + { 597 + int err = -ENOMEM; 598 + dma_cap_mask_t mask_in, mask_out; 599 + 600 + if (pdata && pdata->dma_slave->txdata.dma_dev && 601 + pdata->dma_slave->rxdata.dma_dev) { 602 + 603 + /* Try to grab 2 DMA channels */ 604 + dma_cap_zero(mask_in); 605 + dma_cap_set(DMA_SLAVE, mask_in); 606 + 607 + dd->dma_lch_in.chan = dma_request_channel(mask_in, 608 + atmel_tdes_filter, &pdata->dma_slave->rxdata); 609 + 610 + if (!dd->dma_lch_in.chan) 611 + goto err_dma_in; 612 + 613 + dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; 614 + dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + 615 + TDES_IDATA1R; 616 + dd->dma_lch_in.dma_conf.src_maxburst = 1; 617 + dd->dma_lch_in.dma_conf.src_addr_width = 618 + DMA_SLAVE_BUSWIDTH_4_BYTES; 619 + dd->dma_lch_in.dma_conf.dst_maxburst = 1; 620 + dd->dma_lch_in.dma_conf.dst_addr_width = 621 + DMA_SLAVE_BUSWIDTH_4_BYTES; 622 + dd->dma_lch_in.dma_conf.device_fc = false; 623 + 624 + dma_cap_zero(mask_out); 625 + dma_cap_set(DMA_SLAVE, mask_out); 626 + dd->dma_lch_out.chan = dma_request_channel(mask_out, 627 + atmel_tdes_filter, &pdata->dma_slave->txdata); 628 + 629 + if (!dd->dma_lch_out.chan) 630 + goto err_dma_out; 631 + 632 + dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; 633 + dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + 634 + TDES_ODATA1R; 635 + dd->dma_lch_out.dma_conf.src_maxburst = 1; 636 + dd->dma_lch_out.dma_conf.src_addr_width = 637 + DMA_SLAVE_BUSWIDTH_4_BYTES; 638 + dd->dma_lch_out.dma_conf.dst_maxburst = 1; 639 + dd->dma_lch_out.dma_conf.dst_addr_width = 640 + DMA_SLAVE_BUSWIDTH_4_BYTES; 641 + dd->dma_lch_out.dma_conf.device_fc = false; 642 + 643 + return 0; 644 + } else { 645 + return -ENODEV; 646 + } 647 + 648 + err_dma_out: 649 + dma_release_channel(dd->dma_lch_in.chan); 650 + err_dma_in: 651 + return err; 652 + } 653 + 654 + static void atmel_tdes_dma_cleanup(struct atmel_tdes_dev *dd) 655 + { 656 + dma_release_channel(dd->dma_lch_in.chan); 657 + dma_release_channel(dd->dma_lch_out.chan); 675 658 } 676 659 677 660 static int atmel_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, ··· 815 590 /* 816 591 * HW bug in cfb 3-keys mode. 817 592 */ 818 - if (strstr(alg_name, "cfb") && (keylen != 2*DES_KEY_SIZE)) { 593 + if (!ctx->dd->caps.has_cfb_3keys && strstr(alg_name, "cfb") 594 + && (keylen != 2*DES_KEY_SIZE)) { 819 595 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 820 596 return -EINVAL; 821 597 } else if ((keylen != 2*DES_KEY_SIZE) && (keylen != 3*DES_KEY_SIZE)) { ··· 904 678 905 679 static int atmel_tdes_cra_init(struct crypto_tfm *tfm) 906 680 { 681 + struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm); 682 + struct atmel_tdes_dev *dd; 683 + 907 684 tfm->crt_ablkcipher.reqsize = sizeof(struct atmel_tdes_reqctx); 685 + 686 + dd = atmel_tdes_find_dev(ctx); 687 + if (!dd) 688 + return -ENODEV; 908 689 909 690 return 0; 910 691 } ··· 928 695 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 929 696 .cra_blocksize = DES_BLOCK_SIZE, 930 697 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 931 - .cra_alignmask = 0, 698 + .cra_alignmask = 0x7, 932 699 .cra_type = &crypto_ablkcipher_type, 933 700 .cra_module = THIS_MODULE, 934 701 .cra_init = atmel_tdes_cra_init, ··· 948 715 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 949 716 .cra_blocksize = DES_BLOCK_SIZE, 950 717 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 951 - .cra_alignmask = 0, 718 + .cra_alignmask = 0x7, 952 719 .cra_type = &crypto_ablkcipher_type, 953 720 .cra_module = THIS_MODULE, 954 721 .cra_init = atmel_tdes_cra_init, ··· 969 736 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 970 737 .cra_blocksize = DES_BLOCK_SIZE, 971 738 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 972 - .cra_alignmask = 0, 739 + .cra_alignmask = 0x7, 973 740 .cra_type = &crypto_ablkcipher_type, 974 741 .cra_module = THIS_MODULE, 975 742 .cra_init = atmel_tdes_cra_init, ··· 1011 778 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1012 779 .cra_blocksize = CFB16_BLOCK_SIZE, 1013 780 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1014 - .cra_alignmask = 0, 781 + .cra_alignmask = 0x1, 1015 782 .cra_type = &crypto_ablkcipher_type, 1016 783 .cra_module = THIS_MODULE, 1017 784 .cra_init = atmel_tdes_cra_init, ··· 1032 799 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1033 800 .cra_blocksize = CFB32_BLOCK_SIZE, 1034 801 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1035 - .cra_alignmask = 0, 802 + .cra_alignmask = 0x3, 1036 803 .cra_type = &crypto_ablkcipher_type, 1037 804 .cra_module = THIS_MODULE, 1038 805 .cra_init = atmel_tdes_cra_init, ··· 1053 820 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1054 821 .cra_blocksize = DES_BLOCK_SIZE, 1055 822 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1056 - .cra_alignmask = 0, 823 + .cra_alignmask = 0x7, 1057 824 .cra_type = &crypto_ablkcipher_type, 1058 825 .cra_module = THIS_MODULE, 1059 826 .cra_init = atmel_tdes_cra_init, ··· 1074 841 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1075 842 .cra_blocksize = DES_BLOCK_SIZE, 1076 843 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1077 - .cra_alignmask = 0, 844 + .cra_alignmask = 0x7, 1078 845 .cra_type = &crypto_ablkcipher_type, 1079 846 .cra_module = THIS_MODULE, 1080 847 .cra_init = atmel_tdes_cra_init, ··· 1094 861 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1095 862 .cra_blocksize = DES_BLOCK_SIZE, 1096 863 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1097 - .cra_alignmask = 0, 864 + .cra_alignmask = 0x7, 1098 865 .cra_type = &crypto_ablkcipher_type, 1099 866 .cra_module = THIS_MODULE, 1100 867 .cra_init = atmel_tdes_cra_init, ··· 1115 882 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1116 883 .cra_blocksize = DES_BLOCK_SIZE, 1117 884 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1118 - .cra_alignmask = 0, 885 + .cra_alignmask = 0x7, 1119 886 .cra_type = &crypto_ablkcipher_type, 1120 887 .cra_module = THIS_MODULE, 1121 888 .cra_init = atmel_tdes_cra_init, ··· 1157 924 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1158 925 .cra_blocksize = CFB16_BLOCK_SIZE, 1159 926 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1160 - .cra_alignmask = 0, 927 + .cra_alignmask = 0x1, 1161 928 .cra_type = &crypto_ablkcipher_type, 1162 929 .cra_module = THIS_MODULE, 1163 930 .cra_init = atmel_tdes_cra_init, ··· 1178 945 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1179 946 .cra_blocksize = CFB32_BLOCK_SIZE, 1180 947 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1181 - .cra_alignmask = 0, 948 + .cra_alignmask = 0x3, 1182 949 .cra_type = &crypto_ablkcipher_type, 1183 950 .cra_module = THIS_MODULE, 1184 951 .cra_init = atmel_tdes_cra_init, ··· 1199 966 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 1200 967 .cra_blocksize = DES_BLOCK_SIZE, 1201 968 .cra_ctxsize = sizeof(struct atmel_tdes_ctx), 1202 - .cra_alignmask = 0, 969 + .cra_alignmask = 0x7, 1203 970 .cra_type = &crypto_ablkcipher_type, 1204 971 .cra_module = THIS_MODULE, 1205 972 .cra_init = atmel_tdes_cra_init, ··· 1227 994 struct atmel_tdes_dev *dd = (struct atmel_tdes_dev *) data; 1228 995 int err; 1229 996 1230 - err = atmel_tdes_crypt_dma_stop(dd); 997 + if (!(dd->flags & TDES_FLAGS_DMA)) 998 + err = atmel_tdes_crypt_pdc_stop(dd); 999 + else 1000 + err = atmel_tdes_crypt_dma_stop(dd); 1231 1001 1232 1002 err = dd->err ? : err; 1233 1003 1234 1004 if (dd->total && !err) { 1235 - err = atmel_tdes_crypt_dma_start(dd); 1005 + if (dd->flags & TDES_FLAGS_FAST) { 1006 + dd->in_sg = sg_next(dd->in_sg); 1007 + dd->out_sg = sg_next(dd->out_sg); 1008 + if (!dd->in_sg || !dd->out_sg) 1009 + err = -EINVAL; 1010 + } 1236 1011 if (!err) 1237 - return; 1012 + err = atmel_tdes_crypt_start(dd); 1013 + if (!err) 1014 + return; /* DMA started. Not fininishing. */ 1238 1015 } 1239 1016 1240 1017 atmel_tdes_finish_req(dd, err); ··· 1296 1053 return err; 1297 1054 } 1298 1055 1056 + static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd) 1057 + { 1058 + 1059 + dd->caps.has_dma = 0; 1060 + dd->caps.has_cfb_3keys = 0; 1061 + 1062 + /* keep only major version number */ 1063 + switch (dd->hw_version & 0xf00) { 1064 + case 0x700: 1065 + dd->caps.has_dma = 1; 1066 + dd->caps.has_cfb_3keys = 1; 1067 + break; 1068 + case 0x600: 1069 + break; 1070 + default: 1071 + dev_warn(dd->dev, 1072 + "Unmanaged tdes version, set minimum capabilities\n"); 1073 + break; 1074 + } 1075 + } 1076 + 1299 1077 static int atmel_tdes_probe(struct platform_device *pdev) 1300 1078 { 1301 1079 struct atmel_tdes_dev *tdes_dd; 1080 + struct crypto_platform_data *pdata; 1302 1081 struct device *dev = &pdev->dev; 1303 1082 struct resource *tdes_res; 1304 1083 unsigned long tdes_phys_size; ··· 1374 1109 } 1375 1110 1376 1111 /* Initializing the clock */ 1377 - tdes_dd->iclk = clk_get(&pdev->dev, NULL); 1112 + tdes_dd->iclk = clk_get(&pdev->dev, "tdes_clk"); 1378 1113 if (IS_ERR(tdes_dd->iclk)) { 1379 1114 dev_err(dev, "clock intialization failed.\n"); 1380 1115 err = PTR_ERR(tdes_dd->iclk); ··· 1388 1123 goto tdes_io_err; 1389 1124 } 1390 1125 1391 - err = atmel_tdes_dma_init(tdes_dd); 1126 + atmel_tdes_hw_version_init(tdes_dd); 1127 + 1128 + atmel_tdes_get_cap(tdes_dd); 1129 + 1130 + err = atmel_tdes_buff_init(tdes_dd); 1392 1131 if (err) 1393 - goto err_tdes_dma; 1132 + goto err_tdes_buff; 1133 + 1134 + if (tdes_dd->caps.has_dma) { 1135 + pdata = pdev->dev.platform_data; 1136 + if (!pdata) { 1137 + dev_err(&pdev->dev, "platform data not available\n"); 1138 + err = -ENXIO; 1139 + goto err_pdata; 1140 + } 1141 + err = atmel_tdes_dma_init(tdes_dd, pdata); 1142 + if (err) 1143 + goto err_tdes_dma; 1144 + } 1394 1145 1395 1146 spin_lock(&atmel_tdes.lock); 1396 1147 list_add_tail(&tdes_dd->list, &atmel_tdes.dev_list); ··· 1424 1143 spin_lock(&atmel_tdes.lock); 1425 1144 list_del(&tdes_dd->list); 1426 1145 spin_unlock(&atmel_tdes.lock); 1427 - atmel_tdes_dma_cleanup(tdes_dd); 1146 + if (tdes_dd->caps.has_dma) 1147 + atmel_tdes_dma_cleanup(tdes_dd); 1428 1148 err_tdes_dma: 1149 + err_pdata: 1150 + atmel_tdes_buff_cleanup(tdes_dd); 1151 + err_tdes_buff: 1429 1152 iounmap(tdes_dd->io_base); 1430 1153 tdes_io_err: 1431 1154 clk_put(tdes_dd->iclk); ··· 1463 1178 tasklet_kill(&tdes_dd->done_task); 1464 1179 tasklet_kill(&tdes_dd->queue_task); 1465 1180 1466 - atmel_tdes_dma_cleanup(tdes_dd); 1181 + if (tdes_dd->caps.has_dma) 1182 + atmel_tdes_dma_cleanup(tdes_dd); 1183 + 1184 + atmel_tdes_buff_cleanup(tdes_dd); 1467 1185 1468 1186 iounmap(tdes_dd->io_base); 1469 1187