]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/crypto/caam/caamhash.c
Merge remote-tracking branch 'omap/for-next'
[karo-tx-linux.git] / drivers / crypto / caam / caamhash.c
index 94433b9fc200dc5f5322d29819ebfe74f3fd90f1..49106ea42887097a152ec21b7457004eec9f7fbd 100644 (file)
@@ -134,6 +134,15 @@ struct caam_hash_state {
        int current_buf;
 };
 
+struct caam_export_state {
+       u8 buf[CAAM_MAX_HASH_BLOCK_SIZE];
+       u8 caam_ctx[MAX_CTX_LEN];
+       int buflen;
+       int (*update)(struct ahash_request *req);
+       int (*final)(struct ahash_request *req);
+       int (*finup)(struct ahash_request *req);
+};
+
 /* Common job descriptor seq in/out ptr routines */
 
 /* Map state->caam_ctx, and append seq_out_ptr command that points to it */
@@ -181,10 +190,9 @@ static inline dma_addr_t buf_map_to_sec4_sg(struct device *jrdev,
 /* Map req->src and put it in link table */
 static inline void src_map_to_sec4_sg(struct device *jrdev,
                                      struct scatterlist *src, int src_nents,
-                                     struct sec4_sg_entry *sec4_sg,
-                                     bool chained)
+                                     struct sec4_sg_entry *sec4_sg)
 {
-       dma_map_sg_chained(jrdev, src, src_nents, DMA_TO_DEVICE, chained);
+       dma_map_sg(jrdev, src, src_nents, DMA_TO_DEVICE);
        sg_to_sec4_sg_last(src, src_nents, sec4_sg, 0);
 }
 
@@ -585,7 +593,6 @@ badkey:
  * ahash_edesc - s/w-extended ahash descriptor
  * @dst_dma: physical mapped address of req->result
  * @sec4_sg_dma: physical mapped address of h/w link table
- * @chained: if source is chained
  * @src_nents: number of segments in input scatterlist
  * @sec4_sg_bytes: length of dma mapped sec4_sg space
  * @sec4_sg: pointer to h/w link table
@@ -594,7 +601,6 @@ badkey:
 struct ahash_edesc {
        dma_addr_t dst_dma;
        dma_addr_t sec4_sg_dma;
-       bool chained;
        int src_nents;
        int sec4_sg_bytes;
        struct sec4_sg_entry *sec4_sg;
@@ -606,8 +612,7 @@ static inline void ahash_unmap(struct device *dev,
                        struct ahash_request *req, int dst_len)
 {
        if (edesc->src_nents)
-               dma_unmap_sg_chained(dev, req->src, edesc->src_nents,
-                                    DMA_TO_DEVICE, edesc->chained);
+               dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE);
        if (edesc->dst_dma)
                dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE);
 
@@ -788,7 +793,6 @@ static int ahash_update_ctx(struct ahash_request *req)
        dma_addr_t ptr = ctx->sh_desc_update_dma;
        int src_nents, sec4_sg_bytes, sec4_sg_src_index;
        struct ahash_edesc *edesc;
-       bool chained = false;
        int ret = 0;
        int sh_len;
 
@@ -797,8 +801,8 @@ static int ahash_update_ctx(struct ahash_request *req)
        to_hash = in_len - *next_buflen;
 
        if (to_hash) {
-               src_nents = __sg_count(req->src, req->nbytes - (*next_buflen),
-                                      &chained);
+               src_nents = sg_nents_for_len(req->src,
+                                            req->nbytes - (*next_buflen));
                sec4_sg_src_index = 1 + (*buflen ? 1 : 0);
                sec4_sg_bytes = (sec4_sg_src_index + src_nents) *
                                 sizeof(struct sec4_sg_entry);
@@ -816,7 +820,6 @@ static int ahash_update_ctx(struct ahash_request *req)
                }
 
                edesc->src_nents = src_nents;
-               edesc->chained = chained;
                edesc->sec4_sg_bytes = sec4_sg_bytes;
                edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
                                 DESC_JOB_IO_LEN;
@@ -829,12 +832,11 @@ static int ahash_update_ctx(struct ahash_request *req)
                state->buf_dma = try_buf_map_to_sec4_sg(jrdev,
                                                        edesc->sec4_sg + 1,
                                                        buf, state->buf_dma,
-                                                       *next_buflen, *buflen);
+                                                       *buflen, last_buflen);
 
                if (src_nents) {
                        src_map_to_sec4_sg(jrdev, req->src, src_nents,
-                                          edesc->sec4_sg + sec4_sg_src_index,
-                                          chained);
+                                          edesc->sec4_sg + sec4_sg_src_index);
                        if (*next_buflen)
                                scatterwalk_map_and_copy(next_buf, req->src,
                                                         to_hash - *buflen,
@@ -996,11 +998,10 @@ static int ahash_finup_ctx(struct ahash_request *req)
        int src_nents;
        int digestsize = crypto_ahash_digestsize(ahash);
        struct ahash_edesc *edesc;
-       bool chained = false;
        int ret = 0;
        int sh_len;
 
-       src_nents = __sg_count(req->src, req->nbytes, &chained);
+       src_nents = sg_nents_for_len(req->src, req->nbytes);
        sec4_sg_src_index = 1 + (buflen ? 1 : 0);
        sec4_sg_bytes = (sec4_sg_src_index + src_nents) *
                         sizeof(struct sec4_sg_entry);
@@ -1018,7 +1019,6 @@ static int ahash_finup_ctx(struct ahash_request *req)
        init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE);
 
        edesc->src_nents = src_nents;
-       edesc->chained = chained;
        edesc->sec4_sg_bytes = sec4_sg_bytes;
        edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
                         DESC_JOB_IO_LEN;
@@ -1033,7 +1033,7 @@ static int ahash_finup_ctx(struct ahash_request *req)
                                                last_buflen);
 
        src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg +
-                          sec4_sg_src_index, chained);
+                          sec4_sg_src_index);
 
        edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
                                            sec4_sg_bytes, DMA_TO_DEVICE);
@@ -1081,14 +1081,12 @@ static int ahash_digest(struct ahash_request *req)
        int src_nents, sec4_sg_bytes;
        dma_addr_t src_dma;
        struct ahash_edesc *edesc;
-       bool chained = false;
        int ret = 0;
        u32 options;
        int sh_len;
 
-       src_nents = sg_count(req->src, req->nbytes, &chained);
-       dma_map_sg_chained(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE,
-                          chained);
+       src_nents = sg_count(req->src, req->nbytes);
+       dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE);
        sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry);
 
        /* allocate space for base edesc and hw desc commands, link tables */
@@ -1102,7 +1100,6 @@ static int ahash_digest(struct ahash_request *req)
                          DESC_JOB_IO_LEN;
        edesc->sec4_sg_bytes = sec4_sg_bytes;
        edesc->src_nents = src_nents;
-       edesc->chained = chained;
 
        sh_len = desc_len(sh_desc);
        desc = edesc->hw_desc;
@@ -1228,7 +1225,6 @@ static int ahash_update_no_ctx(struct ahash_request *req)
        struct ahash_edesc *edesc;
        u32 *desc, *sh_desc = ctx->sh_desc_update_first;
        dma_addr_t ptr = ctx->sh_desc_update_first_dma;
-       bool chained = false;
        int ret = 0;
        int sh_len;
 
@@ -1236,8 +1232,8 @@ static int ahash_update_no_ctx(struct ahash_request *req)
        to_hash = in_len - *next_buflen;
 
        if (to_hash) {
-               src_nents = __sg_count(req->src, req->nbytes - (*next_buflen),
-                                      &chained);
+               src_nents = sg_nents_for_len(req->src,
+                                            req->nbytes - (*next_buflen));
                sec4_sg_bytes = (1 + src_nents) *
                                sizeof(struct sec4_sg_entry);
 
@@ -1254,7 +1250,6 @@ static int ahash_update_no_ctx(struct ahash_request *req)
                }
 
                edesc->src_nents = src_nents;
-               edesc->chained = chained;
                edesc->sec4_sg_bytes = sec4_sg_bytes;
                edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
                                 DESC_JOB_IO_LEN;
@@ -1263,7 +1258,7 @@ static int ahash_update_no_ctx(struct ahash_request *req)
                state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg,
                                                    buf, *buflen);
                src_map_to_sec4_sg(jrdev, req->src, src_nents,
-                                  edesc->sec4_sg + 1, chained);
+                                  edesc->sec4_sg + 1);
                if (*next_buflen) {
                        scatterwalk_map_and_copy(next_buf, req->src,
                                                 to_hash - *buflen,
@@ -1343,11 +1338,10 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
        int sec4_sg_bytes, sec4_sg_src_index, src_nents;
        int digestsize = crypto_ahash_digestsize(ahash);
        struct ahash_edesc *edesc;
-       bool chained = false;
        int sh_len;
        int ret = 0;
 
-       src_nents = __sg_count(req->src, req->nbytes, &chained);
+       src_nents = sg_nents_for_len(req->src, req->nbytes);
        sec4_sg_src_index = 2;
        sec4_sg_bytes = (sec4_sg_src_index + src_nents) *
                         sizeof(struct sec4_sg_entry);
@@ -1365,7 +1359,6 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
        init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE);
 
        edesc->src_nents = src_nents;
-       edesc->chained = chained;
        edesc->sec4_sg_bytes = sec4_sg_bytes;
        edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
                         DESC_JOB_IO_LEN;
@@ -1374,8 +1367,7 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
                                                state->buf_dma, buflen,
                                                last_buflen);
 
-       src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1,
-                          chained);
+       src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1);
 
        edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
                                            sec4_sg_bytes, DMA_TO_DEVICE);
@@ -1429,7 +1421,6 @@ static int ahash_update_first(struct ahash_request *req)
        dma_addr_t src_dma;
        u32 options;
        struct ahash_edesc *edesc;
-       bool chained = false;
        int ret = 0;
        int sh_len;
 
@@ -1438,10 +1429,8 @@ static int ahash_update_first(struct ahash_request *req)
        to_hash = req->nbytes - *next_buflen;
 
        if (to_hash) {
-               src_nents = sg_count(req->src, req->nbytes - (*next_buflen),
-                                    &chained);
-               dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
-                                  DMA_TO_DEVICE, chained);
+               src_nents = sg_count(req->src, req->nbytes - (*next_buflen));
+               dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE);
                sec4_sg_bytes = src_nents * sizeof(struct sec4_sg_entry);
 
                /*
@@ -1457,7 +1446,6 @@ static int ahash_update_first(struct ahash_request *req)
                }
 
                edesc->src_nents = src_nents;
-               edesc->chained = chained;
                edesc->sec4_sg_bytes = sec4_sg_bytes;
                edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
                                 DESC_JOB_IO_LEN;
@@ -1574,25 +1562,42 @@ static int ahash_final(struct ahash_request *req)
 
 static int ahash_export(struct ahash_request *req, void *out)
 {
-       struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-       struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct caam_hash_state *state = ahash_request_ctx(req);
+       struct caam_export_state *export = out;
+       int len;
+       u8 *buf;
+
+       if (state->current_buf) {
+               buf = state->buf_1;
+               len = state->buflen_1;
+       } else {
+               buf = state->buf_0;
+               len = state->buflen_1;
+       }
+
+       memcpy(export->buf, buf, len);
+       memcpy(export->caam_ctx, state->caam_ctx, sizeof(export->caam_ctx));
+       export->buflen = len;
+       export->update = state->update;
+       export->final = state->final;
+       export->finup = state->finup;
 
-       memcpy(out, ctx, sizeof(struct caam_hash_ctx));
-       memcpy(out + sizeof(struct caam_hash_ctx), state,
-              sizeof(struct caam_hash_state));
        return 0;
 }
 
 static int ahash_import(struct ahash_request *req, const void *in)
 {
-       struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-       struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct caam_hash_state *state = ahash_request_ctx(req);
+       const struct caam_export_state *export = in;
+
+       memset(state, 0, sizeof(*state));
+       memcpy(state->buf_0, export->buf, export->buflen);
+       memcpy(state->caam_ctx, export->caam_ctx, sizeof(state->caam_ctx));
+       state->buflen_0 = export->buflen;
+       state->update = export->update;
+       state->final = export->final;
+       state->finup = export->finup;
 
-       memcpy(ctx, in, sizeof(struct caam_hash_ctx));
-       memcpy(state, in + sizeof(struct caam_hash_ctx),
-              sizeof(struct caam_hash_state));
        return 0;
 }
 
@@ -1626,8 +1631,9 @@ static struct caam_hash_template driver_hash[] = {
                        .setkey = ahash_setkey,
                        .halg = {
                                .digestsize = SHA1_DIGEST_SIZE,
-                               },
+                               .statesize = sizeof(struct caam_export_state),
                        },
+               },
                .alg_type = OP_ALG_ALGSEL_SHA1,
                .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
        }, {
@@ -1647,8 +1653,9 @@ static struct caam_hash_template driver_hash[] = {
                        .setkey = ahash_setkey,
                        .halg = {
                                .digestsize = SHA224_DIGEST_SIZE,
-                               },
+                               .statesize = sizeof(struct caam_export_state),
                        },
+               },
                .alg_type = OP_ALG_ALGSEL_SHA224,
                .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
        }, {
@@ -1668,8 +1675,9 @@ static struct caam_hash_template driver_hash[] = {
                        .setkey = ahash_setkey,
                        .halg = {
                                .digestsize = SHA256_DIGEST_SIZE,
-                               },
+                               .statesize = sizeof(struct caam_export_state),
                        },
+               },
                .alg_type = OP_ALG_ALGSEL_SHA256,
                .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
        }, {
@@ -1689,8 +1697,9 @@ static struct caam_hash_template driver_hash[] = {
                        .setkey = ahash_setkey,
                        .halg = {
                                .digestsize = SHA384_DIGEST_SIZE,
-                               },
+                               .statesize = sizeof(struct caam_export_state),
                        },
+               },
                .alg_type = OP_ALG_ALGSEL_SHA384,
                .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
        }, {
@@ -1710,8 +1719,9 @@ static struct caam_hash_template driver_hash[] = {
                        .setkey = ahash_setkey,
                        .halg = {
                                .digestsize = SHA512_DIGEST_SIZE,
-                               },
+                               .statesize = sizeof(struct caam_export_state),
                        },
+               },
                .alg_type = OP_ALG_ALGSEL_SHA512,
                .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
        }, {
@@ -1731,8 +1741,9 @@ static struct caam_hash_template driver_hash[] = {
                        .setkey = ahash_setkey,
                        .halg = {
                                .digestsize = MD5_DIGEST_SIZE,
-                               },
+                               .statesize = sizeof(struct caam_export_state),
                        },
+               },
                .alg_type = OP_ALG_ALGSEL_MD5,
                .alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
        },
@@ -1952,8 +1963,9 @@ static int __init caam_algapi_hash_init(void)
 
                err = crypto_register_ahash(&t_alg->ahash_alg);
                if (err) {
-                       pr_warn("%s alg registration failed\n",
-                               t_alg->ahash_alg.halg.base.cra_driver_name);
+                       pr_warn("%s alg registration failed: %d\n",
+                               t_alg->ahash_alg.halg.base.cra_driver_name,
+                               err);
                        kfree(t_alg);
                } else
                        list_add_tail(&t_alg->entry, &hash_list);
@@ -1968,8 +1980,9 @@ static int __init caam_algapi_hash_init(void)
 
                err = crypto_register_ahash(&t_alg->ahash_alg);
                if (err) {
-                       pr_warn("%s alg registration failed\n",
-                               t_alg->ahash_alg.halg.base.cra_driver_name);
+                       pr_warn("%s alg registration failed: %d\n",
+                               t_alg->ahash_alg.halg.base.cra_driver_name,
+                               err);
                        kfree(t_alg);
                } else
                        list_add_tail(&t_alg->entry, &hash_list);