aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Kang <Yuan.Kang@freescale.com>2012-06-22 20:48:49 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2012-06-27 02:42:05 -0400
commit643b39b031f546c7c3c60ef360b8260aa2b32762 (patch)
tree71658c6a049937d65b48ebe7bc9a159eb655885a
parentb0e09bae37eeacb213d9baf8fcb4d48934a4ada5 (diff)
crypto: caam - chaining support
support chained scatterlists for aead, ablkcipher and ahash. Signed-off-by: Yuan Kang <Yuan.Kang@freescale.com> - fix dma unmap leak - un-unlikely src == dst, due to experience with AF_ALG Signed-off-by: Kudupudi Ugendreshwar <B38865@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/caam/caamalg.c114
-rw-r--r--drivers/crypto/caam/caamhash.c53
-rw-r--r--drivers/crypto/caam/sg_sw_sec4.h44
3 files changed, 147 insertions, 64 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 5ab480a12b51..0c1ea8492eff 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -654,8 +654,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
654/* 654/*
655 * aead_edesc - s/w-extended aead descriptor 655 * aead_edesc - s/w-extended aead descriptor
656 * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist 656 * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist
657 * @assoc_chained: if source is chained
657 * @src_nents: number of segments in input scatterlist 658 * @src_nents: number of segments in input scatterlist
659 * @src_chained: if source is chained
658 * @dst_nents: number of segments in output scatterlist 660 * @dst_nents: number of segments in output scatterlist
661 * @dst_chained: if destination is chained
659 * @iv_dma: dma address of iv for checking continuity and link table 662 * @iv_dma: dma address of iv for checking continuity and link table
660 * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) 663 * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
661 * @sec4_sg_bytes: length of dma mapped sec4_sg space 664 * @sec4_sg_bytes: length of dma mapped sec4_sg space
@@ -664,8 +667,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
664 */ 667 */
665struct aead_edesc { 668struct aead_edesc {
666 int assoc_nents; 669 int assoc_nents;
670 bool assoc_chained;
667 int src_nents; 671 int src_nents;
672 bool src_chained;
668 int dst_nents; 673 int dst_nents;
674 bool dst_chained;
669 dma_addr_t iv_dma; 675 dma_addr_t iv_dma;
670 int sec4_sg_bytes; 676 int sec4_sg_bytes;
671 dma_addr_t sec4_sg_dma; 677 dma_addr_t sec4_sg_dma;
@@ -676,7 +682,9 @@ struct aead_edesc {
676/* 682/*
677 * ablkcipher_edesc - s/w-extended ablkcipher descriptor 683 * ablkcipher_edesc - s/w-extended ablkcipher descriptor
678 * @src_nents: number of segments in input scatterlist 684 * @src_nents: number of segments in input scatterlist
685 * @src_chained: if source is chained
679 * @dst_nents: number of segments in output scatterlist 686 * @dst_nents: number of segments in output scatterlist
687 * @dst_chained: if destination is chained
680 * @iv_dma: dma address of iv for checking continuity and link table 688 * @iv_dma: dma address of iv for checking continuity and link table
681 * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) 689 * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
682 * @sec4_sg_bytes: length of dma mapped sec4_sg space 690 * @sec4_sg_bytes: length of dma mapped sec4_sg space
@@ -685,7 +693,9 @@ struct aead_edesc {
685 */ 693 */
686struct ablkcipher_edesc { 694struct ablkcipher_edesc {
687 int src_nents; 695 int src_nents;
696 bool src_chained;
688 int dst_nents; 697 int dst_nents;
698 bool dst_chained;
689 dma_addr_t iv_dma; 699 dma_addr_t iv_dma;
690 int sec4_sg_bytes; 700 int sec4_sg_bytes;
691 dma_addr_t sec4_sg_dma; 701 dma_addr_t sec4_sg_dma;
@@ -694,15 +704,19 @@ struct ablkcipher_edesc {
694}; 704};
695 705
696static void caam_unmap(struct device *dev, struct scatterlist *src, 706static void caam_unmap(struct device *dev, struct scatterlist *src,
697 struct scatterlist *dst, int src_nents, int dst_nents, 707 struct scatterlist *dst, int src_nents,
708 bool src_chained, int dst_nents, bool dst_chained,
698 dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma, 709 dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
699 int sec4_sg_bytes) 710 int sec4_sg_bytes)
700{ 711{
701 if (unlikely(dst != src)) { 712 if (dst != src) {
702 dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); 713 dma_unmap_sg_chained(dev, src, src_nents ? : 1, DMA_TO_DEVICE,
703 dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); 714 src_chained);
715 dma_unmap_sg_chained(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE,
716 dst_chained);
704 } else { 717 } else {
705 dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); 718 dma_unmap_sg_chained(dev, src, src_nents ? : 1,
719 DMA_BIDIRECTIONAL, src_chained);
706 } 720 }
707 721
708 if (iv_dma) 722 if (iv_dma)
@@ -719,12 +733,13 @@ static void aead_unmap(struct device *dev,
719 struct crypto_aead *aead = crypto_aead_reqtfm(req); 733 struct crypto_aead *aead = crypto_aead_reqtfm(req);
720 int ivsize = crypto_aead_ivsize(aead); 734 int ivsize = crypto_aead_ivsize(aead);
721 735
722 dma_unmap_sg(dev, req->assoc, edesc->assoc_nents, DMA_TO_DEVICE); 736 dma_unmap_sg_chained(dev, req->assoc, edesc->assoc_nents,
737 DMA_TO_DEVICE, edesc->assoc_chained);
723 738
724 caam_unmap(dev, req->src, req->dst, 739 caam_unmap(dev, req->src, req->dst,
725 edesc->src_nents, edesc->dst_nents, 740 edesc->src_nents, edesc->src_chained, edesc->dst_nents,
726 edesc->iv_dma, ivsize, edesc->sec4_sg_dma, 741 edesc->dst_chained, edesc->iv_dma, ivsize,
727 edesc->sec4_sg_bytes); 742 edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
728} 743}
729 744
730static void ablkcipher_unmap(struct device *dev, 745static void ablkcipher_unmap(struct device *dev,
@@ -735,9 +750,9 @@ static void ablkcipher_unmap(struct device *dev,
735 int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 750 int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
736 751
737 caam_unmap(dev, req->src, req->dst, 752 caam_unmap(dev, req->src, req->dst,
738 edesc->src_nents, edesc->dst_nents, 753 edesc->src_nents, edesc->src_chained, edesc->dst_nents,
739 edesc->iv_dma, ivsize, edesc->sec4_sg_dma, 754 edesc->dst_chained, edesc->iv_dma, ivsize,
740 edesc->sec4_sg_bytes); 755 edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
741} 756}
742 757
743static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err, 758static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
@@ -1128,25 +1143,26 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1128 dma_addr_t iv_dma = 0; 1143 dma_addr_t iv_dma = 0;
1129 int sgc; 1144 int sgc;
1130 bool all_contig = true; 1145 bool all_contig = true;
1146 bool assoc_chained = false, src_chained = false, dst_chained = false;
1131 int ivsize = crypto_aead_ivsize(aead); 1147 int ivsize = crypto_aead_ivsize(aead);
1132 int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; 1148 int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
1133 1149
1134 assoc_nents = sg_count(req->assoc, req->assoclen); 1150 assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
1135 src_nents = sg_count(req->src, req->cryptlen); 1151 src_nents = sg_count(req->src, req->cryptlen, &src_chained);
1136 1152
1137 if (unlikely(req->dst != req->src)) 1153 if (unlikely(req->dst != req->src))
1138 dst_nents = sg_count(req->dst, req->cryptlen); 1154 dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
1139 1155
1140 sgc = dma_map_sg(jrdev, req->assoc, assoc_nents ? : 1, 1156 sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
1141 DMA_BIDIRECTIONAL); 1157 DMA_BIDIRECTIONAL, assoc_chained);
1142 if (likely(req->src == req->dst)) { 1158 if (likely(req->src == req->dst)) {
1143 sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, 1159 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1144 DMA_BIDIRECTIONAL); 1160 DMA_BIDIRECTIONAL, src_chained);
1145 } else { 1161 } else {
1146 sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, 1162 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1147 DMA_TO_DEVICE); 1163 DMA_TO_DEVICE, src_chained);
1148 sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, 1164 sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
1149 DMA_FROM_DEVICE); 1165 DMA_FROM_DEVICE, dst_chained);
1150 } 1166 }
1151 1167
1152 /* Check if data are contiguous */ 1168 /* Check if data are contiguous */
@@ -1172,8 +1188,11 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1172 } 1188 }
1173 1189
1174 edesc->assoc_nents = assoc_nents; 1190 edesc->assoc_nents = assoc_nents;
1191 edesc->assoc_chained = assoc_chained;
1175 edesc->src_nents = src_nents; 1192 edesc->src_nents = src_nents;
1193 edesc->src_chained = src_chained;
1176 edesc->dst_nents = dst_nents; 1194 edesc->dst_nents = dst_nents;
1195 edesc->dst_chained = dst_chained;
1177 edesc->iv_dma = iv_dma; 1196 edesc->iv_dma = iv_dma;
1178 edesc->sec4_sg_bytes = sec4_sg_bytes; 1197 edesc->sec4_sg_bytes = sec4_sg_bytes;
1179 edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + 1198 edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
@@ -1307,24 +1326,25 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
1307 int sgc; 1326 int sgc;
1308 u32 contig = GIV_SRC_CONTIG | GIV_DST_CONTIG; 1327 u32 contig = GIV_SRC_CONTIG | GIV_DST_CONTIG;
1309 int ivsize = crypto_aead_ivsize(aead); 1328 int ivsize = crypto_aead_ivsize(aead);
1329 bool assoc_chained = false, src_chained = false, dst_chained = false;
1310 int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; 1330 int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
1311 1331
1312 assoc_nents = sg_count(req->assoc, req->assoclen); 1332 assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
1313 src_nents = sg_count(req->src, req->cryptlen); 1333 src_nents = sg_count(req->src, req->cryptlen, &src_chained);
1314 1334
1315 if (unlikely(req->dst != req->src)) 1335 if (unlikely(req->dst != req->src))
1316 dst_nents = sg_count(req->dst, req->cryptlen); 1336 dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
1317 1337
1318 sgc = dma_map_sg(jrdev, req->assoc, assoc_nents ? : 1, 1338 sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
1319 DMA_BIDIRECTIONAL); 1339 DMA_BIDIRECTIONAL, assoc_chained);
1320 if (likely(req->src == req->dst)) { 1340 if (likely(req->src == req->dst)) {
1321 sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, 1341 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1322 DMA_BIDIRECTIONAL); 1342 DMA_BIDIRECTIONAL, src_chained);
1323 } else { 1343 } else {
1324 sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, 1344 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1325 DMA_TO_DEVICE); 1345 DMA_TO_DEVICE, src_chained);
1326 sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, 1346 sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
1327 DMA_FROM_DEVICE); 1347 DMA_FROM_DEVICE, dst_chained);
1328 } 1348 }
1329 1349
1330 /* Check if data are contiguous */ 1350 /* Check if data are contiguous */
@@ -1358,8 +1378,11 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
1358 } 1378 }
1359 1379
1360 edesc->assoc_nents = assoc_nents; 1380 edesc->assoc_nents = assoc_nents;
1381 edesc->assoc_chained = assoc_chained;
1361 edesc->src_nents = src_nents; 1382 edesc->src_nents = src_nents;
1383 edesc->src_chained = src_chained;
1362 edesc->dst_nents = dst_nents; 1384 edesc->dst_nents = dst_nents;
1385 edesc->dst_chained = dst_chained;
1363 edesc->iv_dma = iv_dma; 1386 edesc->iv_dma = iv_dma;
1364 edesc->sec4_sg_bytes = sec4_sg_bytes; 1387 edesc->sec4_sg_bytes = sec4_sg_bytes;
1365 edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) + 1388 edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
@@ -1459,21 +1482,22 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
1459 bool iv_contig = false; 1482 bool iv_contig = false;
1460 int sgc; 1483 int sgc;
1461 int ivsize = crypto_ablkcipher_ivsize(ablkcipher); 1484 int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1485 bool src_chained = false, dst_chained = false;
1462 int sec4_sg_index; 1486 int sec4_sg_index;
1463 1487
1464 src_nents = sg_count(req->src, req->nbytes); 1488 src_nents = sg_count(req->src, req->nbytes, &src_chained);
1465 1489
1466 if (unlikely(req->dst != req->src)) 1490 if (req->dst != req->src)
1467 dst_nents = sg_count(req->dst, req->nbytes); 1491 dst_nents = sg_count(req->dst, req->nbytes, &dst_chained);
1468 1492
1469 if (likely(req->src == req->dst)) { 1493 if (likely(req->src == req->dst)) {
1470 sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, 1494 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1471 DMA_BIDIRECTIONAL); 1495 DMA_BIDIRECTIONAL, src_chained);
1472 } else { 1496 } else {
1473 sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1, 1497 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1474 DMA_TO_DEVICE); 1498 DMA_TO_DEVICE, src_chained);
1475 sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1, 1499 sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
1476 DMA_FROM_DEVICE); 1500 DMA_FROM_DEVICE, dst_chained);
1477 } 1501 }
1478 1502
1479 /* 1503 /*
@@ -1497,7 +1521,9 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
1497 } 1521 }
1498 1522
1499 edesc->src_nents = src_nents; 1523 edesc->src_nents = src_nents;
1524 edesc->src_chained = src_chained;
1500 edesc->dst_nents = dst_nents; 1525 edesc->dst_nents = dst_nents;
1526 edesc->dst_chained = dst_chained;
1501 edesc->sec4_sg_bytes = sec4_sg_bytes; 1527 edesc->sec4_sg_bytes = sec4_sg_bytes;
1502 edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) + 1528 edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
1503 desc_bytes; 1529 desc_bytes;
@@ -1510,7 +1536,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
1510 sec4_sg_index += 1 + src_nents; 1536 sec4_sg_index += 1 + src_nents;
1511 } 1537 }
1512 1538
1513 if (unlikely(dst_nents)) { 1539 if (dst_nents) {
1514 sg_to_sec4_sg_last(req->dst, dst_nents, 1540 sg_to_sec4_sg_last(req->dst, dst_nents,
1515 edesc->sec4_sg + sec4_sg_index, 0); 1541 edesc->sec4_sg + sec4_sg_index, 0);
1516 } 1542 }
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 7dcf28f48149..895aaf2bca92 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -175,9 +175,10 @@ static inline dma_addr_t buf_map_to_sec4_sg(struct device *jrdev,
175/* Map req->src and put it in link table */ 175/* Map req->src and put it in link table */
176static inline void src_map_to_sec4_sg(struct device *jrdev, 176static inline void src_map_to_sec4_sg(struct device *jrdev,
177 struct scatterlist *src, int src_nents, 177 struct scatterlist *src, int src_nents,
178 struct sec4_sg_entry *sec4_sg) 178 struct sec4_sg_entry *sec4_sg,
179 bool chained)
179{ 180{
180 dma_map_sg(jrdev, src, src_nents, DMA_TO_DEVICE); 181 dma_map_sg_chained(jrdev, src, src_nents, DMA_TO_DEVICE, chained);
181 sg_to_sec4_sg_last(src, src_nents, sec4_sg, 0); 182 sg_to_sec4_sg_last(src, src_nents, sec4_sg, 0);
182} 183}
183 184
@@ -563,6 +564,7 @@ badkey:
563 * ahash_edesc - s/w-extended ahash descriptor 564 * ahash_edesc - s/w-extended ahash descriptor
564 * @dst_dma: physical mapped address of req->result 565 * @dst_dma: physical mapped address of req->result
565 * @sec4_sg_dma: physical mapped address of h/w link table 566 * @sec4_sg_dma: physical mapped address of h/w link table
567 * @chained: if source is chained
566 * @src_nents: number of segments in input scatterlist 568 * @src_nents: number of segments in input scatterlist
567 * @sec4_sg_bytes: length of dma mapped sec4_sg space 569 * @sec4_sg_bytes: length of dma mapped sec4_sg space
568 * @sec4_sg: pointer to h/w link table 570 * @sec4_sg: pointer to h/w link table
@@ -571,6 +573,7 @@ badkey:
571struct ahash_edesc { 573struct ahash_edesc {
572 dma_addr_t dst_dma; 574 dma_addr_t dst_dma;
573 dma_addr_t sec4_sg_dma; 575 dma_addr_t sec4_sg_dma;
576 bool chained;
574 int src_nents; 577 int src_nents;
575 int sec4_sg_bytes; 578 int sec4_sg_bytes;
576 struct sec4_sg_entry *sec4_sg; 579 struct sec4_sg_entry *sec4_sg;
@@ -582,7 +585,8 @@ static inline void ahash_unmap(struct device *dev,
582 struct ahash_request *req, int dst_len) 585 struct ahash_request *req, int dst_len)
583{ 586{
584 if (edesc->src_nents) 587 if (edesc->src_nents)
585 dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE); 588 dma_unmap_sg_chained(dev, req->src, edesc->src_nents,
589 DMA_TO_DEVICE, edesc->chained);
586 if (edesc->dst_dma) 590 if (edesc->dst_dma)
587 dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE); 591 dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE);
588 592
@@ -775,6 +779,7 @@ static int ahash_update_ctx(struct ahash_request *req)
775 dma_addr_t ptr = ctx->sh_desc_update_dma; 779 dma_addr_t ptr = ctx->sh_desc_update_dma;
776 int src_nents, sec4_sg_bytes, sec4_sg_src_index; 780 int src_nents, sec4_sg_bytes, sec4_sg_src_index;
777 struct ahash_edesc *edesc; 781 struct ahash_edesc *edesc;
782 bool chained = false;
778 int ret = 0; 783 int ret = 0;
779 int sh_len; 784 int sh_len;
780 785
@@ -783,7 +788,8 @@ static int ahash_update_ctx(struct ahash_request *req)
783 to_hash = in_len - *next_buflen; 788 to_hash = in_len - *next_buflen;
784 789
785 if (to_hash) { 790 if (to_hash) {
786 src_nents = __sg_count(req->src, req->nbytes - (*next_buflen)); 791 src_nents = __sg_count(req->src, req->nbytes - (*next_buflen),
792 &chained);
787 sec4_sg_src_index = 1 + (*buflen ? 1 : 0); 793 sec4_sg_src_index = 1 + (*buflen ? 1 : 0);
788 sec4_sg_bytes = (sec4_sg_src_index + src_nents) * 794 sec4_sg_bytes = (sec4_sg_src_index + src_nents) *
789 sizeof(struct sec4_sg_entry); 795 sizeof(struct sec4_sg_entry);
@@ -801,6 +807,7 @@ static int ahash_update_ctx(struct ahash_request *req)
801 } 807 }
802 808
803 edesc->src_nents = src_nents; 809 edesc->src_nents = src_nents;
810 edesc->chained = chained;
804 edesc->sec4_sg_bytes = sec4_sg_bytes; 811 edesc->sec4_sg_bytes = sec4_sg_bytes;
805 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + 812 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
806 DESC_JOB_IO_LEN; 813 DESC_JOB_IO_LEN;
@@ -818,7 +825,8 @@ static int ahash_update_ctx(struct ahash_request *req)
818 825
819 if (src_nents) { 826 if (src_nents) {
820 src_map_to_sec4_sg(jrdev, req->src, src_nents, 827 src_map_to_sec4_sg(jrdev, req->src, src_nents,
821 edesc->sec4_sg + sec4_sg_src_index); 828 edesc->sec4_sg + sec4_sg_src_index,
829 chained);
822 if (*next_buflen) { 830 if (*next_buflen) {
823 sg_copy_part(next_buf, req->src, to_hash - 831 sg_copy_part(next_buf, req->src, to_hash -
824 *buflen, req->nbytes); 832 *buflen, req->nbytes);
@@ -958,10 +966,11 @@ static int ahash_finup_ctx(struct ahash_request *req)
958 int src_nents; 966 int src_nents;
959 int digestsize = crypto_ahash_digestsize(ahash); 967 int digestsize = crypto_ahash_digestsize(ahash);
960 struct ahash_edesc *edesc; 968 struct ahash_edesc *edesc;
969 bool chained = false;
961 int ret = 0; 970 int ret = 0;
962 int sh_len; 971 int sh_len;
963 972
964 src_nents = __sg_count(req->src, req->nbytes); 973 src_nents = __sg_count(req->src, req->nbytes, &chained);
965 sec4_sg_src_index = 1 + (buflen ? 1 : 0); 974 sec4_sg_src_index = 1 + (buflen ? 1 : 0);
966 sec4_sg_bytes = (sec4_sg_src_index + src_nents) * 975 sec4_sg_bytes = (sec4_sg_src_index + src_nents) *
967 sizeof(struct sec4_sg_entry); 976 sizeof(struct sec4_sg_entry);
@@ -979,6 +988,7 @@ static int ahash_finup_ctx(struct ahash_request *req)
979 init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); 988 init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE);
980 989
981 edesc->src_nents = src_nents; 990 edesc->src_nents = src_nents;
991 edesc->chained = chained;
982 edesc->sec4_sg_bytes = sec4_sg_bytes; 992 edesc->sec4_sg_bytes = sec4_sg_bytes;
983 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + 993 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
984 DESC_JOB_IO_LEN; 994 DESC_JOB_IO_LEN;
@@ -993,7 +1003,7 @@ static int ahash_finup_ctx(struct ahash_request *req)
993 last_buflen); 1003 last_buflen);
994 1004
995 src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1005 src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg +
996 sec4_sg_src_index); 1006 sec4_sg_src_index, chained);
997 1007
998 append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + 1008 append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len +
999 buflen + req->nbytes, LDST_SGF); 1009 buflen + req->nbytes, LDST_SGF);
@@ -1030,12 +1040,14 @@ static int ahash_digest(struct ahash_request *req)
1030 int src_nents, sec4_sg_bytes; 1040 int src_nents, sec4_sg_bytes;
1031 dma_addr_t src_dma; 1041 dma_addr_t src_dma;
1032 struct ahash_edesc *edesc; 1042 struct ahash_edesc *edesc;
1043 bool chained = false;
1033 int ret = 0; 1044 int ret = 0;
1034 u32 options; 1045 u32 options;
1035 int sh_len; 1046 int sh_len;
1036 1047
1037 src_nents = sg_count(req->src, req->nbytes); 1048 src_nents = sg_count(req->src, req->nbytes, &chained);
1038 dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE); 1049 dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE,
1050 chained);
1039 sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry); 1051 sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry);
1040 1052
1041 /* allocate space for base edesc and hw desc commands, link tables */ 1053 /* allocate space for base edesc and hw desc commands, link tables */
@@ -1050,6 +1062,7 @@ static int ahash_digest(struct ahash_request *req)
1050 edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, 1062 edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1051 sec4_sg_bytes, DMA_TO_DEVICE); 1063 sec4_sg_bytes, DMA_TO_DEVICE);
1052 edesc->src_nents = src_nents; 1064 edesc->src_nents = src_nents;
1065 edesc->chained = chained;
1053 1066
1054 sh_len = desc_len(sh_desc); 1067 sh_len = desc_len(sh_desc);
1055 desc = edesc->hw_desc; 1068 desc = edesc->hw_desc;
@@ -1157,6 +1170,7 @@ static int ahash_update_no_ctx(struct ahash_request *req)
1157 struct ahash_edesc *edesc; 1170 struct ahash_edesc *edesc;
1158 u32 *desc, *sh_desc = ctx->sh_desc_update_first; 1171 u32 *desc, *sh_desc = ctx->sh_desc_update_first;
1159 dma_addr_t ptr = ctx->sh_desc_update_first_dma; 1172 dma_addr_t ptr = ctx->sh_desc_update_first_dma;
1173 bool chained = false;
1160 int ret = 0; 1174 int ret = 0;
1161 int sh_len; 1175 int sh_len;
1162 1176
@@ -1164,7 +1178,8 @@ static int ahash_update_no_ctx(struct ahash_request *req)
1164 to_hash = in_len - *next_buflen; 1178 to_hash = in_len - *next_buflen;
1165 1179
1166 if (to_hash) { 1180 if (to_hash) {
1167 src_nents = __sg_count(req->src, req->nbytes - (*next_buflen)); 1181 src_nents = __sg_count(req->src, req->nbytes - (*next_buflen),
1182 &chained);
1168 sec4_sg_bytes = (1 + src_nents) * 1183 sec4_sg_bytes = (1 + src_nents) *
1169 sizeof(struct sec4_sg_entry); 1184 sizeof(struct sec4_sg_entry);
1170 1185
@@ -1181,6 +1196,7 @@ static int ahash_update_no_ctx(struct ahash_request *req)
1181 } 1196 }
1182 1197
1183 edesc->src_nents = src_nents; 1198 edesc->src_nents = src_nents;
1199 edesc->chained = chained;
1184 edesc->sec4_sg_bytes = sec4_sg_bytes; 1200 edesc->sec4_sg_bytes = sec4_sg_bytes;
1185 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + 1201 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
1186 DESC_JOB_IO_LEN; 1202 DESC_JOB_IO_LEN;
@@ -1191,7 +1207,7 @@ static int ahash_update_no_ctx(struct ahash_request *req)
1191 state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, 1207 state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg,
1192 buf, *buflen); 1208 buf, *buflen);
1193 src_map_to_sec4_sg(jrdev, req->src, src_nents, 1209 src_map_to_sec4_sg(jrdev, req->src, src_nents,
1194 edesc->sec4_sg + 1); 1210 edesc->sec4_sg + 1, chained);
1195 if (*next_buflen) { 1211 if (*next_buflen) {
1196 sg_copy_part(next_buf, req->src, to_hash - *buflen, 1212 sg_copy_part(next_buf, req->src, to_hash - *buflen,
1197 req->nbytes); 1213 req->nbytes);
@@ -1258,10 +1274,11 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
1258 int sec4_sg_bytes, sec4_sg_src_index, src_nents; 1274 int sec4_sg_bytes, sec4_sg_src_index, src_nents;
1259 int digestsize = crypto_ahash_digestsize(ahash); 1275 int digestsize = crypto_ahash_digestsize(ahash);
1260 struct ahash_edesc *edesc; 1276 struct ahash_edesc *edesc;
1277 bool chained = false;
1261 int sh_len; 1278 int sh_len;
1262 int ret = 0; 1279 int ret = 0;
1263 1280
1264 src_nents = __sg_count(req->src, req->nbytes); 1281 src_nents = __sg_count(req->src, req->nbytes, &chained);
1265 sec4_sg_src_index = 2; 1282 sec4_sg_src_index = 2;
1266 sec4_sg_bytes = (sec4_sg_src_index + src_nents) * 1283 sec4_sg_bytes = (sec4_sg_src_index + src_nents) *
1267 sizeof(struct sec4_sg_entry); 1284 sizeof(struct sec4_sg_entry);
@@ -1279,6 +1296,7 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
1279 init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE); 1296 init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE);
1280 1297
1281 edesc->src_nents = src_nents; 1298 edesc->src_nents = src_nents;
1299 edesc->chained = chained;
1282 edesc->sec4_sg_bytes = sec4_sg_bytes; 1300 edesc->sec4_sg_bytes = sec4_sg_bytes;
1283 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + 1301 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
1284 DESC_JOB_IO_LEN; 1302 DESC_JOB_IO_LEN;
@@ -1289,7 +1307,8 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
1289 state->buf_dma, buflen, 1307 state->buf_dma, buflen,
1290 last_buflen); 1308 last_buflen);
1291 1309
1292 src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1); 1310 src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1,
1311 chained);
1293 1312
1294 append_seq_in_ptr(desc, edesc->sec4_sg_dma, buflen + 1313 append_seq_in_ptr(desc, edesc->sec4_sg_dma, buflen +
1295 req->nbytes, LDST_SGF); 1314 req->nbytes, LDST_SGF);
@@ -1332,6 +1351,7 @@ static int ahash_update_first(struct ahash_request *req)
1332 dma_addr_t src_dma; 1351 dma_addr_t src_dma;
1333 u32 options; 1352 u32 options;
1334 struct ahash_edesc *edesc; 1353 struct ahash_edesc *edesc;
1354 bool chained = false;
1335 int ret = 0; 1355 int ret = 0;
1336 int sh_len; 1356 int sh_len;
1337 1357
@@ -1340,8 +1360,10 @@ static int ahash_update_first(struct ahash_request *req)
1340 to_hash = req->nbytes - *next_buflen; 1360 to_hash = req->nbytes - *next_buflen;
1341 1361
1342 if (to_hash) { 1362 if (to_hash) {
1343 src_nents = sg_count(req->src, req->nbytes - (*next_buflen)); 1363 src_nents = sg_count(req->src, req->nbytes - (*next_buflen),
1344 dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE); 1364 &chained);
1365 dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1366 DMA_TO_DEVICE, chained);
1345 sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry); 1367 sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry);
1346 1368
1347 /* 1369 /*
@@ -1357,6 +1379,7 @@ static int ahash_update_first(struct ahash_request *req)
1357 } 1379 }
1358 1380
1359 edesc->src_nents = src_nents; 1381 edesc->src_nents = src_nents;
1382 edesc->chained = chained;
1360 edesc->sec4_sg_bytes = sec4_sg_bytes; 1383 edesc->sec4_sg_bytes = sec4_sg_bytes;
1361 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) + 1384 edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
1362 DESC_JOB_IO_LEN; 1385 DESC_JOB_IO_LEN;
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h
index 2dda9e3a5e67..e0037c8ee243 100644
--- a/drivers/crypto/caam/sg_sw_sec4.h
+++ b/drivers/crypto/caam/sg_sw_sec4.h
@@ -37,7 +37,7 @@ sg_to_sec4_sg(struct scatterlist *sg, int sg_count,
37 dma_to_sec4_sg_one(sec4_sg_ptr, sg_dma_address(sg), 37 dma_to_sec4_sg_one(sec4_sg_ptr, sg_dma_address(sg),
38 sg_dma_len(sg), offset); 38 sg_dma_len(sg), offset);
39 sec4_sg_ptr++; 39 sec4_sg_ptr++;
40 sg = sg_next(sg); 40 sg = scatterwalk_sg_next(sg);
41 sg_count--; 41 sg_count--;
42 } 42 }
43 return sec4_sg_ptr - 1; 43 return sec4_sg_ptr - 1;
@@ -56,7 +56,8 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count,
56} 56}
57 57
58/* count number of elements in scatterlist */ 58/* count number of elements in scatterlist */
59static inline int __sg_count(struct scatterlist *sg_list, int nbytes) 59static inline int __sg_count(struct scatterlist *sg_list, int nbytes,
60 bool *chained)
60{ 61{
61 struct scatterlist *sg = sg_list; 62 struct scatterlist *sg = sg_list;
62 int sg_nents = 0; 63 int sg_nents = 0;
@@ -65,7 +66,7 @@ static inline int __sg_count(struct scatterlist *sg_list, int nbytes)
65 sg_nents++; 66 sg_nents++;
66 nbytes -= sg->length; 67 nbytes -= sg->length;
67 if (!sg_is_last(sg) && (sg + 1)->length == 0) 68 if (!sg_is_last(sg) && (sg + 1)->length == 0)
68 BUG(); /* Not support chaining */ 69 *chained = true;
69 sg = scatterwalk_sg_next(sg); 70 sg = scatterwalk_sg_next(sg);
70 } 71 }
71 72
@@ -73,9 +74,10 @@ static inline int __sg_count(struct scatterlist *sg_list, int nbytes)
73} 74}
74 75
75/* derive number of elements in scatterlist, but return 0 for 1 */ 76/* derive number of elements in scatterlist, but return 0 for 1 */
76static inline int sg_count(struct scatterlist *sg_list, int nbytes) 77static inline int sg_count(struct scatterlist *sg_list, int nbytes,
78 bool *chained)
77{ 79{
78 int sg_nents = __sg_count(sg_list, nbytes); 80 int sg_nents = __sg_count(sg_list, nbytes, chained);
79 81
80 if (likely(sg_nents == 1)) 82 if (likely(sg_nents == 1))
81 return 0; 83 return 0;
@@ -83,6 +85,38 @@ static inline int sg_count(struct scatterlist *sg_list, int nbytes)
83 return sg_nents; 85 return sg_nents;
84} 86}
85 87
88static int dma_map_sg_chained(struct device *dev, struct scatterlist *sg,
89 unsigned int nents, enum dma_data_direction dir,
90 bool chained)
91{
92 if (unlikely(chained)) {
93 int i;
94 for (i = 0; i < nents; i++) {
95 dma_map_sg(dev, sg, 1, dir);
96 sg = scatterwalk_sg_next(sg);
97 }
98 } else {
99 dma_map_sg(dev, sg, nents, dir);
100 }
101 return nents;
102}
103
104static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg,
105 unsigned int nents, enum dma_data_direction dir,
106 bool chained)
107{
108 if (unlikely(chained)) {
109 int i;
110 for (i = 0; i < nents; i++) {
111 dma_unmap_sg(dev, sg, 1, dir);
112 sg = scatterwalk_sg_next(sg);
113 }
114 } else {
115 dma_unmap_sg(dev, sg, nents, dir);
116 }
117 return nents;
118}
119
86/* Copy from len bytes of sg to dest, starting from beginning */ 120/* Copy from len bytes of sg to dest, starting from beginning */
87static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) 121static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
88{ 122{