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

crypto: caam - add crypto_engine support for HASH algorithms

Add crypto_engine support for HASH algorithms, to make use of
the engine queue.
The requests, with backlog flag, will be listed into crypto-engine
queue and processed by CAAM when free.
Only the backlog request are sent to crypto-engine since the others
can be handled by CAAM, if free, especially since JR has up to 1024
entries (more than the 10 entries from crypto-engine).

Signed-off-by: Iuliana Prodan <iuliana.prodan@nxp.com>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Iuliana Prodan and committed by
Herbert Xu
21b014f0 bf537950

+123 -51
+123 -51
drivers/crypto/caam/caamhash.c
··· 65 65 #include "sg_sw_sec4.h" 66 66 #include "key_gen.h" 67 67 #include "caamhash_desc.h" 68 + #include <crypto/engine.h> 68 69 69 70 #define CAAM_CRA_PRIORITY 3000 70 71 ··· 87 86 88 87 /* ahash per-session context */ 89 88 struct caam_hash_ctx { 89 + struct crypto_engine_ctx enginectx; 90 90 u32 sh_desc_update[DESC_HASH_MAX_USED_LEN] ____cacheline_aligned; 91 91 u32 sh_desc_update_first[DESC_HASH_MAX_USED_LEN] ____cacheline_aligned; 92 92 u32 sh_desc_fin[DESC_HASH_MAX_USED_LEN] ____cacheline_aligned; ··· 113 111 int buflen; 114 112 int next_buflen; 115 113 u8 caam_ctx[MAX_CTX_LEN] ____cacheline_aligned; 116 - int (*update)(struct ahash_request *req); 114 + int (*update)(struct ahash_request *req) ____cacheline_aligned; 117 115 int (*final)(struct ahash_request *req); 118 116 int (*finup)(struct ahash_request *req); 117 + struct ahash_edesc *edesc; 118 + void (*ahash_op_done)(struct device *jrdev, u32 *desc, u32 err, 119 + void *context); 119 120 }; 120 121 121 122 struct caam_export_state { ··· 526 521 * @sec4_sg_dma: physical mapped address of h/w link table 527 522 * @src_nents: number of segments in input scatterlist 528 523 * @sec4_sg_bytes: length of dma mapped sec4_sg space 524 + * @bklog: stored to determine if the request needs backlog 529 525 * @hw_desc: the h/w job descriptor followed by any referenced link tables 530 526 * @sec4_sg: h/w link table 531 527 */ ··· 534 528 dma_addr_t sec4_sg_dma; 535 529 int src_nents; 536 530 int sec4_sg_bytes; 531 + bool bklog; 537 532 u32 hw_desc[DESC_JOB_IO_LEN_MAX / sizeof(u32)] ____cacheline_aligned; 538 533 struct sec4_sg_entry sec4_sg[0]; 539 534 }; ··· 576 569 void *context, enum dma_data_direction dir) 577 570 { 578 571 struct ahash_request *req = context; 572 + struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); 579 573 struct ahash_edesc *edesc; 580 574 struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 581 575 int digestsize = crypto_ahash_digestsize(ahash); ··· 586 578 587 579 dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 588 580 589 - edesc = container_of(desc, struct ahash_edesc, hw_desc[0]); 581 + edesc = state->edesc; 582 + 590 583 if (err) 591 584 ecode = caam_jr_strstatus(jrdev, err); 592 585 ··· 599 590 DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, 600 591 ctx->ctx_len, 1); 601 592 602 - req->base.complete(&req->base, ecode); 593 + /* 594 + * If no backlog flag, the completion of the request is done 595 + * by CAAM, not crypto engine. 596 + */ 597 + if (!edesc->bklog) 598 + req->base.complete(&req->base, ecode); 599 + else 600 + crypto_finalize_hash_request(jrp->engine, req, ecode); 603 601 } 604 602 605 603 static void ahash_done(struct device *jrdev, u32 *desc, u32 err, ··· 625 609 void *context, enum dma_data_direction dir) 626 610 { 627 611 struct ahash_request *req = context; 612 + struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); 628 613 struct ahash_edesc *edesc; 629 614 struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 630 615 struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); ··· 635 618 636 619 dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 637 620 638 - edesc = container_of(desc, struct ahash_edesc, hw_desc[0]); 621 + edesc = state->edesc; 639 622 if (err) 640 623 ecode = caam_jr_strstatus(jrdev, err); 641 624 ··· 659 642 DUMP_PREFIX_ADDRESS, 16, 4, req->result, 660 643 digestsize, 1); 661 644 662 - req->base.complete(&req->base, ecode); 645 + /* 646 + * If no backlog flag, the completion of the request is done 647 + * by CAAM, not crypto engine. 648 + */ 649 + if (!edesc->bklog) 650 + req->base.complete(&req->base, ecode); 651 + else 652 + crypto_finalize_hash_request(jrp->engine, req, ecode); 653 + 663 654 } 664 655 665 656 static void ahash_done_bi(struct device *jrdev, u32 *desc, u32 err, ··· 692 667 { 693 668 struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 694 669 struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); 670 + struct caam_hash_state *state = ahash_request_ctx(req); 695 671 gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 696 672 GFP_KERNEL : GFP_ATOMIC; 697 673 struct ahash_edesc *edesc; ··· 703 677 dev_err(ctx->jrdev, "could not allocate extended descriptor\n"); 704 678 return NULL; 705 679 } 680 + 681 + state->edesc = edesc; 706 682 707 683 init_job_desc_shared(edesc->hw_desc, sh_desc_dma, desc_len(sh_desc), 708 684 HDR_SHARE_DEFER | HDR_REVERSE); ··· 746 718 options); 747 719 748 720 return 0; 721 + } 722 + 723 + static int ahash_do_one_req(struct crypto_engine *engine, void *areq) 724 + { 725 + struct ahash_request *req = ahash_request_cast(areq); 726 + struct caam_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 727 + struct caam_hash_state *state = ahash_request_ctx(req); 728 + struct device *jrdev = ctx->jrdev; 729 + u32 *desc = state->edesc->hw_desc; 730 + int ret; 731 + 732 + state->edesc->bklog = true; 733 + 734 + ret = caam_jr_enqueue(jrdev, desc, state->ahash_op_done, req); 735 + 736 + if (ret != -EINPROGRESS) { 737 + ahash_unmap(jrdev, state->edesc, req, 0); 738 + kfree(state->edesc); 739 + } else { 740 + ret = 0; 741 + } 742 + 743 + return ret; 744 + } 745 + 746 + static int ahash_enqueue_req(struct device *jrdev, 747 + void (*cbk)(struct device *jrdev, u32 *desc, 748 + u32 err, void *context), 749 + struct ahash_request *req, 750 + int dst_len, enum dma_data_direction dir) 751 + { 752 + struct caam_drv_private_jr *jrpriv = dev_get_drvdata(jrdev); 753 + struct caam_hash_state *state = ahash_request_ctx(req); 754 + struct ahash_edesc *edesc = state->edesc; 755 + u32 *desc = edesc->hw_desc; 756 + int ret; 757 + 758 + state->ahash_op_done = cbk; 759 + 760 + /* 761 + * Only the backlog request are sent to crypto-engine since the others 762 + * can be handled by CAAM, if free, especially since JR has up to 1024 763 + * entries (more than the 10 entries from crypto-engine). 764 + */ 765 + if (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG) 766 + ret = crypto_transfer_hash_request_to_engine(jrpriv->engine, 767 + req); 768 + else 769 + ret = caam_jr_enqueue(jrdev, desc, cbk, req); 770 + 771 + if ((ret != -EINPROGRESS) && (ret != -EBUSY)) { 772 + ahash_unmap_ctx(jrdev, edesc, req, dst_len, dir); 773 + kfree(edesc); 774 + } 775 + 776 + return ret; 749 777 } 750 778 751 779 /* submit update job descriptor */ ··· 911 827 DUMP_PREFIX_ADDRESS, 16, 4, desc, 912 828 desc_bytes(desc), 1); 913 829 914 - ret = caam_jr_enqueue(jrdev, desc, ahash_done_bi, req); 915 - if (ret != -EINPROGRESS) 916 - goto unmap_ctx; 830 + ret = ahash_enqueue_req(jrdev, ahash_done_bi, req, 831 + ctx->ctx_len, DMA_BIDIRECTIONAL); 917 832 } else if (*next_buflen) { 918 833 scatterwalk_map_and_copy(buf + *buflen, req->src, 0, 919 834 req->nbytes, 0); ··· 983 900 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 984 901 1); 985 902 986 - ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_src, req); 987 - if (ret == -EINPROGRESS) 988 - return ret; 989 - 903 + return ahash_enqueue_req(jrdev, ahash_done_ctx_src, req, 904 + digestsize, DMA_BIDIRECTIONAL); 990 905 unmap_ctx: 991 906 ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_BIDIRECTIONAL); 992 907 kfree(edesc); ··· 1057 976 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1058 977 1); 1059 978 1060 - ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_src, req); 1061 - if (ret == -EINPROGRESS) 1062 - return ret; 1063 - 979 + return ahash_enqueue_req(jrdev, ahash_done_ctx_src, req, 980 + digestsize, DMA_BIDIRECTIONAL); 1064 981 unmap_ctx: 1065 982 ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_BIDIRECTIONAL); 1066 983 kfree(edesc); ··· 1127 1048 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1128 1049 1); 1129 1050 1130 - ret = caam_jr_enqueue(jrdev, desc, ahash_done, req); 1131 - if (ret != -EINPROGRESS) { 1132 - ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE); 1133 - kfree(edesc); 1134 - } 1135 - 1136 - return ret; 1051 + return ahash_enqueue_req(jrdev, ahash_done, req, digestsize, 1052 + DMA_FROM_DEVICE); 1137 1053 } 1138 1054 1139 1055 /* submit ahash final if it the first job descriptor */ ··· 1172 1098 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1173 1099 1); 1174 1100 1175 - ret = caam_jr_enqueue(jrdev, desc, ahash_done, req); 1176 - if (ret != -EINPROGRESS) { 1177 - ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE); 1178 - kfree(edesc); 1179 - } 1180 - 1181 - return ret; 1101 + return ahash_enqueue_req(jrdev, ahash_done, req, 1102 + digestsize, DMA_FROM_DEVICE); 1182 1103 unmap: 1183 1104 ahash_unmap(jrdev, edesc, req, digestsize); 1184 1105 kfree(edesc); 1185 1106 return -ENOMEM; 1186 - 1187 1107 } 1188 1108 1189 1109 /* submit ahash update if it the first job descriptor after update */ ··· 1277 1209 DUMP_PREFIX_ADDRESS, 16, 4, desc, 1278 1210 desc_bytes(desc), 1); 1279 1211 1280 - ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_dst, req); 1281 - if (ret != -EINPROGRESS) 1282 - goto unmap_ctx; 1283 - 1212 + ret = ahash_enqueue_req(jrdev, ahash_done_ctx_dst, req, 1213 + ctx->ctx_len, DMA_TO_DEVICE); 1214 + if ((ret != -EINPROGRESS) && (ret != -EBUSY)) 1215 + return ret; 1284 1216 state->update = ahash_update_ctx; 1285 1217 state->finup = ahash_finup_ctx; 1286 1218 state->final = ahash_final_ctx; ··· 1368 1300 DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1369 1301 1); 1370 1302 1371 - ret = caam_jr_enqueue(jrdev, desc, ahash_done, req); 1372 - if (ret != -EINPROGRESS) { 1373 - ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE); 1374 - kfree(edesc); 1375 - } 1376 - 1377 - return ret; 1303 + return ahash_enqueue_req(jrdev, ahash_done, req, 1304 + digestsize, DMA_FROM_DEVICE); 1378 1305 unmap: 1379 1306 ahash_unmap(jrdev, edesc, req, digestsize); 1380 1307 kfree(edesc); ··· 1457 1394 DUMP_PREFIX_ADDRESS, 16, 4, desc, 1458 1395 desc_bytes(desc), 1); 1459 1396 1460 - ret = caam_jr_enqueue(jrdev, desc, ahash_done_ctx_dst, req); 1461 - if (ret != -EINPROGRESS) 1462 - goto unmap_ctx; 1463 - 1397 + ret = ahash_enqueue_req(jrdev, ahash_done_ctx_dst, req, 1398 + ctx->ctx_len, DMA_TO_DEVICE); 1399 + if ((ret != -EINPROGRESS) && (ret != -EBUSY)) 1400 + return ret; 1464 1401 state->update = ahash_update_ctx; 1465 1402 state->finup = ahash_finup_ctx; 1466 1403 state->final = ahash_final_ctx; ··· 1763 1700 HASH_MSG_LEN + SHA256_DIGEST_SIZE, 1764 1701 HASH_MSG_LEN + 64, 1765 1702 HASH_MSG_LEN + SHA512_DIGEST_SIZE }; 1703 + const size_t sh_desc_update_offset = offsetof(struct caam_hash_ctx, 1704 + sh_desc_update); 1766 1705 dma_addr_t dma_addr; 1767 1706 struct caam_drv_private *priv; 1768 1707 ··· 1817 1752 } 1818 1753 1819 1754 dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_update, 1820 - offsetof(struct caam_hash_ctx, key), 1755 + offsetof(struct caam_hash_ctx, key) - 1756 + sh_desc_update_offset, 1821 1757 ctx->dir, DMA_ATTR_SKIP_CPU_SYNC); 1822 1758 if (dma_mapping_error(ctx->jrdev, dma_addr)) { 1823 1759 dev_err(ctx->jrdev, "unable to map shared descriptors\n"); ··· 1836 1770 ctx->sh_desc_update_dma = dma_addr; 1837 1771 ctx->sh_desc_update_first_dma = dma_addr + 1838 1772 offsetof(struct caam_hash_ctx, 1839 - sh_desc_update_first); 1773 + sh_desc_update_first) - 1774 + sh_desc_update_offset; 1840 1775 ctx->sh_desc_fin_dma = dma_addr + offsetof(struct caam_hash_ctx, 1841 - sh_desc_fin); 1776 + sh_desc_fin) - 1777 + sh_desc_update_offset; 1842 1778 ctx->sh_desc_digest_dma = dma_addr + offsetof(struct caam_hash_ctx, 1843 - sh_desc_digest); 1779 + sh_desc_digest) - 1780 + sh_desc_update_offset; 1781 + 1782 + ctx->enginectx.op.do_one_request = ahash_do_one_req; 1844 1783 1845 1784 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), 1846 1785 sizeof(struct caam_hash_state)); ··· 1862 1791 struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm); 1863 1792 1864 1793 dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_update_dma, 1865 - offsetof(struct caam_hash_ctx, key), 1794 + offsetof(struct caam_hash_ctx, key) - 1795 + offsetof(struct caam_hash_ctx, sh_desc_update), 1866 1796 ctx->dir, DMA_ATTR_SKIP_CPU_SYNC); 1867 1797 if (ctx->key_dir != DMA_NONE) 1868 1798 dma_unmap_single_attrs(ctx->jrdev, ctx->adata.key_dma,