|
@@ -16,6 +16,47 @@
|
|
|
|
|
|
#include "cesa.h"
|
|
|
|
|
|
+struct mv_cesa_ahash_dma_iter {
|
|
|
+ struct mv_cesa_dma_iter base;
|
|
|
+ struct mv_cesa_sg_dma_iter src;
|
|
|
+};
|
|
|
+
|
|
|
+static inline void
|
|
|
+mv_cesa_ahash_req_iter_init(struct mv_cesa_ahash_dma_iter *iter,
|
|
|
+ struct ahash_request *req)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+ unsigned int len = req->nbytes;
|
|
|
+
|
|
|
+ if (!creq->last_req)
|
|
|
+ len = (len + creq->cache_ptr) & ~CESA_HASH_BLOCK_SIZE_MSK;
|
|
|
+
|
|
|
+ mv_cesa_req_dma_iter_init(&iter->base, len);
|
|
|
+ mv_cesa_sg_dma_iter_init(&iter->src, req->src, DMA_TO_DEVICE);
|
|
|
+ iter->src.op_offset = creq->cache_ptr;
|
|
|
+}
|
|
|
+
|
|
|
+static inline bool
|
|
|
+mv_cesa_ahash_req_iter_next_op(struct mv_cesa_ahash_dma_iter *iter)
|
|
|
+{
|
|
|
+ iter->src.op_offset = 0;
|
|
|
+
|
|
|
+ return mv_cesa_req_dma_iter_next_op(&iter->base);
|
|
|
+}
|
|
|
+
|
|
|
+static inline int mv_cesa_ahash_dma_alloc_cache(struct mv_cesa_ahash_req *creq,
|
|
|
+ gfp_t flags)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_dma_req *dreq = &creq->req.dma;
|
|
|
+
|
|
|
+ creq->cache = dma_pool_alloc(cesa_dev->dma->cache_pool, flags,
|
|
|
+ &dreq->cache_dma);
|
|
|
+ if (!creq->cache)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static inline int mv_cesa_ahash_std_alloc_cache(struct mv_cesa_ahash_req *creq,
|
|
|
gfp_t flags)
|
|
|
{
|
|
@@ -31,11 +72,23 @@ static int mv_cesa_ahash_alloc_cache(struct ahash_request *req)
|
|
|
struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
|
|
|
GFP_KERNEL : GFP_ATOMIC;
|
|
|
+ int ret;
|
|
|
|
|
|
if (creq->cache)
|
|
|
return 0;
|
|
|
|
|
|
- return mv_cesa_ahash_std_alloc_cache(creq, flags);
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ ret = mv_cesa_ahash_dma_alloc_cache(creq, flags);
|
|
|
+ else
|
|
|
+ ret = mv_cesa_ahash_std_alloc_cache(creq, flags);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void mv_cesa_ahash_dma_free_cache(struct mv_cesa_ahash_req *creq)
|
|
|
+{
|
|
|
+ dma_pool_free(cesa_dev->dma->cache_pool, creq->cache,
|
|
|
+ creq->req.dma.cache_dma);
|
|
|
}
|
|
|
|
|
|
static inline void mv_cesa_ahash_std_free_cache(struct mv_cesa_ahash_req *creq)
|
|
@@ -48,16 +101,69 @@ static void mv_cesa_ahash_free_cache(struct mv_cesa_ahash_req *creq)
|
|
|
if (!creq->cache)
|
|
|
return;
|
|
|
|
|
|
- mv_cesa_ahash_std_free_cache(creq);
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ mv_cesa_ahash_dma_free_cache(creq);
|
|
|
+ else
|
|
|
+ mv_cesa_ahash_std_free_cache(creq);
|
|
|
|
|
|
creq->cache = NULL;
|
|
|
}
|
|
|
|
|
|
+static int mv_cesa_ahash_dma_alloc_padding(struct mv_cesa_ahash_dma_req *req,
|
|
|
+ gfp_t flags)
|
|
|
+{
|
|
|
+ if (req->padding)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ req->padding = dma_pool_alloc(cesa_dev->dma->padding_pool, flags,
|
|
|
+ &req->padding_dma);
|
|
|
+ if (!req->padding)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void mv_cesa_ahash_dma_free_padding(struct mv_cesa_ahash_dma_req *req)
|
|
|
+{
|
|
|
+ if (!req->padding)
|
|
|
+ return;
|
|
|
+
|
|
|
+ dma_pool_free(cesa_dev->dma->padding_pool, req->padding,
|
|
|
+ req->padding_dma);
|
|
|
+ req->padding = NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void mv_cesa_ahash_dma_last_cleanup(struct ahash_request *req)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ mv_cesa_ahash_dma_free_padding(&creq->req.dma);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void mv_cesa_ahash_dma_cleanup(struct ahash_request *req)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, DMA_TO_DEVICE);
|
|
|
+ mv_cesa_dma_cleanup(&creq->req.dma.base);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void mv_cesa_ahash_cleanup(struct ahash_request *req)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ mv_cesa_ahash_dma_cleanup(req);
|
|
|
+}
|
|
|
+
|
|
|
static void mv_cesa_ahash_last_cleanup(struct ahash_request *req)
|
|
|
{
|
|
|
struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
|
|
|
mv_cesa_ahash_free_cache(creq);
|
|
|
+
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ mv_cesa_ahash_dma_last_cleanup(req);
|
|
|
}
|
|
|
|
|
|
static int mv_cesa_ahash_pad_len(struct mv_cesa_ahash_req *creq)
|
|
@@ -183,6 +289,14 @@ static int mv_cesa_ahash_std_process(struct ahash_request *req, u32 status)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static inline void mv_cesa_ahash_dma_prepare(struct ahash_request *req)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+ struct mv_cesa_tdma_req *dreq = &creq->req.dma.base;
|
|
|
+
|
|
|
+ mv_cesa_dma_prepare(dreq, dreq->base.engine);
|
|
|
+}
|
|
|
+
|
|
|
static void mv_cesa_ahash_std_prepare(struct ahash_request *req)
|
|
|
{
|
|
|
struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
@@ -197,8 +311,12 @@ static void mv_cesa_ahash_std_prepare(struct ahash_request *req)
|
|
|
static void mv_cesa_ahash_step(struct crypto_async_request *req)
|
|
|
{
|
|
|
struct ahash_request *ahashreq = ahash_request_cast(req);
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
|
|
|
|
|
|
- mv_cesa_ahash_std_step(ahashreq);
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ mv_cesa_dma_step(&creq->req.dma.base);
|
|
|
+ else
|
|
|
+ mv_cesa_ahash_std_step(ahashreq);
|
|
|
}
|
|
|
|
|
|
static int mv_cesa_ahash_process(struct crypto_async_request *req, u32 status)
|
|
@@ -209,7 +327,11 @@ static int mv_cesa_ahash_process(struct crypto_async_request *req, u32 status)
|
|
|
unsigned int digsize;
|
|
|
int ret, i;
|
|
|
|
|
|
- ret = mv_cesa_ahash_std_process(ahashreq, status);
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ ret = mv_cesa_dma_process(&creq->req.dma.base, status);
|
|
|
+ else
|
|
|
+ ret = mv_cesa_ahash_std_process(ahashreq, status);
|
|
|
+
|
|
|
if (ret == -EINPROGRESS)
|
|
|
return ret;
|
|
|
|
|
@@ -243,7 +365,10 @@ static void mv_cesa_ahash_prepare(struct crypto_async_request *req,
|
|
|
|
|
|
creq->req.base.engine = engine;
|
|
|
|
|
|
- mv_cesa_ahash_std_prepare(ahashreq);
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ mv_cesa_ahash_dma_prepare(ahashreq);
|
|
|
+ else
|
|
|
+ mv_cesa_ahash_std_prepare(ahashreq);
|
|
|
|
|
|
digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(ahashreq));
|
|
|
for (i = 0; i < digsize / 4; i++)
|
|
@@ -258,6 +383,8 @@ static void mv_cesa_ahash_req_cleanup(struct crypto_async_request *req)
|
|
|
|
|
|
if (creq->last_req)
|
|
|
mv_cesa_ahash_last_cleanup(ahashreq);
|
|
|
+
|
|
|
+ mv_cesa_ahash_cleanup(ahashreq);
|
|
|
}
|
|
|
|
|
|
static const struct mv_cesa_req_ops mv_cesa_ahash_req_ops = {
|
|
@@ -325,14 +452,267 @@ static int mv_cesa_ahash_cache_req(struct ahash_request *req, bool *cached)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static struct mv_cesa_op_ctx *
|
|
|
+mv_cesa_ahash_dma_add_cache(struct mv_cesa_tdma_chain *chain,
|
|
|
+ struct mv_cesa_ahash_dma_iter *dma_iter,
|
|
|
+ struct mv_cesa_ahash_req *creq,
|
|
|
+ gfp_t flags)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma;
|
|
|
+ struct mv_cesa_op_ctx *op = NULL;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!creq->cache_ptr)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ ret = mv_cesa_dma_add_data_transfer(chain,
|
|
|
+ CESA_SA_DATA_SRAM_OFFSET,
|
|
|
+ ahashdreq->cache_dma,
|
|
|
+ creq->cache_ptr,
|
|
|
+ CESA_TDMA_DST_IN_SRAM,
|
|
|
+ flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ if (!dma_iter->base.op_len) {
|
|
|
+ op = mv_cesa_dma_add_op(chain, &creq->op_tmpl, false, flags);
|
|
|
+ if (IS_ERR(op))
|
|
|
+ return op;
|
|
|
+
|
|
|
+ mv_cesa_set_mac_op_frag_len(op, creq->cache_ptr);
|
|
|
+
|
|
|
+ /* Add dummy desc to launch crypto operation */
|
|
|
+ ret = mv_cesa_dma_add_dummy_launch(chain, flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ return op;
|
|
|
+}
|
|
|
+
|
|
|
+static struct mv_cesa_op_ctx *
|
|
|
+mv_cesa_ahash_dma_add_data(struct mv_cesa_tdma_chain *chain,
|
|
|
+ struct mv_cesa_ahash_dma_iter *dma_iter,
|
|
|
+ struct mv_cesa_ahash_req *creq,
|
|
|
+ gfp_t flags)
|
|
|
+{
|
|
|
+ struct mv_cesa_op_ctx *op;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ op = mv_cesa_dma_add_op(chain, &creq->op_tmpl, false, flags);
|
|
|
+ if (IS_ERR(op))
|
|
|
+ return op;
|
|
|
+
|
|
|
+ mv_cesa_set_mac_op_frag_len(op, dma_iter->base.op_len);
|
|
|
+
|
|
|
+ if ((mv_cesa_get_op_cfg(&creq->op_tmpl) & CESA_SA_DESC_CFG_FRAG_MSK) ==
|
|
|
+ CESA_SA_DESC_CFG_FIRST_FRAG)
|
|
|
+ mv_cesa_update_op_cfg(&creq->op_tmpl,
|
|
|
+ CESA_SA_DESC_CFG_MID_FRAG,
|
|
|
+ CESA_SA_DESC_CFG_FRAG_MSK);
|
|
|
+
|
|
|
+ /* Add input transfers */
|
|
|
+ ret = mv_cesa_dma_add_op_transfers(chain, &dma_iter->base,
|
|
|
+ &dma_iter->src, flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ /* Add dummy desc to launch crypto operation */
|
|
|
+ ret = mv_cesa_dma_add_dummy_launch(chain, flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ return op;
|
|
|
+}
|
|
|
+
|
|
|
+static struct mv_cesa_op_ctx *
|
|
|
+mv_cesa_ahash_dma_last_req(struct mv_cesa_tdma_chain *chain,
|
|
|
+ struct mv_cesa_ahash_dma_iter *dma_iter,
|
|
|
+ struct mv_cesa_ahash_req *creq,
|
|
|
+ struct mv_cesa_op_ctx *op,
|
|
|
+ gfp_t flags)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma;
|
|
|
+ unsigned int len, trailerlen, padoff = 0;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!creq->last_req)
|
|
|
+ return op;
|
|
|
+
|
|
|
+ if (op && creq->len <= CESA_SA_DESC_MAC_SRC_TOTAL_LEN_MAX) {
|
|
|
+ u32 frag = CESA_SA_DESC_CFG_NOT_FRAG;
|
|
|
+
|
|
|
+ if ((mv_cesa_get_op_cfg(op) & CESA_SA_DESC_CFG_FRAG_MSK) !=
|
|
|
+ CESA_SA_DESC_CFG_FIRST_FRAG)
|
|
|
+ frag = CESA_SA_DESC_CFG_LAST_FRAG;
|
|
|
+
|
|
|
+ mv_cesa_update_op_cfg(op, frag, CESA_SA_DESC_CFG_FRAG_MSK);
|
|
|
+
|
|
|
+ return op;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = mv_cesa_ahash_dma_alloc_padding(ahashdreq, flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ trailerlen = mv_cesa_ahash_pad_req(creq, ahashdreq->padding);
|
|
|
+
|
|
|
+ if (op) {
|
|
|
+ len = min(CESA_SA_SRAM_PAYLOAD_SIZE - dma_iter->base.op_len,
|
|
|
+ trailerlen);
|
|
|
+ if (len) {
|
|
|
+ ret = mv_cesa_dma_add_data_transfer(chain,
|
|
|
+ CESA_SA_DATA_SRAM_OFFSET +
|
|
|
+ dma_iter->base.op_len,
|
|
|
+ ahashdreq->padding_dma,
|
|
|
+ len, CESA_TDMA_DST_IN_SRAM,
|
|
|
+ flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ mv_cesa_update_op_cfg(op, CESA_SA_DESC_CFG_MID_FRAG,
|
|
|
+ CESA_SA_DESC_CFG_FRAG_MSK);
|
|
|
+ mv_cesa_set_mac_op_frag_len(op,
|
|
|
+ dma_iter->base.op_len + len);
|
|
|
+ padoff += len;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (padoff >= trailerlen)
|
|
|
+ return op;
|
|
|
+
|
|
|
+ if ((mv_cesa_get_op_cfg(&creq->op_tmpl) & CESA_SA_DESC_CFG_FRAG_MSK) !=
|
|
|
+ CESA_SA_DESC_CFG_FIRST_FRAG)
|
|
|
+ mv_cesa_update_op_cfg(&creq->op_tmpl,
|
|
|
+ CESA_SA_DESC_CFG_MID_FRAG,
|
|
|
+ CESA_SA_DESC_CFG_FRAG_MSK);
|
|
|
+
|
|
|
+ op = mv_cesa_dma_add_op(chain, &creq->op_tmpl, false, flags);
|
|
|
+ if (IS_ERR(op))
|
|
|
+ return op;
|
|
|
+
|
|
|
+ mv_cesa_set_mac_op_frag_len(op, trailerlen - padoff);
|
|
|
+
|
|
|
+ ret = mv_cesa_dma_add_data_transfer(chain,
|
|
|
+ CESA_SA_DATA_SRAM_OFFSET,
|
|
|
+ ahashdreq->padding_dma +
|
|
|
+ padoff,
|
|
|
+ trailerlen - padoff,
|
|
|
+ CESA_TDMA_DST_IN_SRAM,
|
|
|
+ flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ /* Add dummy desc to launch crypto operation */
|
|
|
+ ret = mv_cesa_dma_add_dummy_launch(chain, flags);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ return op;
|
|
|
+}
|
|
|
+
|
|
|
+static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
|
|
|
+{
|
|
|
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+ gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
|
|
|
+ GFP_KERNEL : GFP_ATOMIC;
|
|
|
+ struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma;
|
|
|
+ struct mv_cesa_tdma_req *dreq = &ahashdreq->base;
|
|
|
+ struct mv_cesa_tdma_chain chain;
|
|
|
+ struct mv_cesa_ahash_dma_iter iter;
|
|
|
+ struct mv_cesa_op_ctx *op = NULL;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ dreq->chain.first = NULL;
|
|
|
+ dreq->chain.last = NULL;
|
|
|
+
|
|
|
+ if (creq->src_nents) {
|
|
|
+ ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
|
|
|
+ DMA_TO_DEVICE);
|
|
|
+ if (!ret) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mv_cesa_tdma_desc_iter_init(&chain);
|
|
|
+ mv_cesa_ahash_req_iter_init(&iter, req);
|
|
|
+
|
|
|
+ op = mv_cesa_ahash_dma_add_cache(&chain, &iter,
|
|
|
+ creq, flags);
|
|
|
+ if (IS_ERR(op)) {
|
|
|
+ ret = PTR_ERR(op);
|
|
|
+ goto err_free_tdma;
|
|
|
+ }
|
|
|
+
|
|
|
+ do {
|
|
|
+ if (!iter.base.op_len)
|
|
|
+ break;
|
|
|
+
|
|
|
+ op = mv_cesa_ahash_dma_add_data(&chain, &iter,
|
|
|
+ creq, flags);
|
|
|
+ if (IS_ERR(op)) {
|
|
|
+ ret = PTR_ERR(op);
|
|
|
+ goto err_free_tdma;
|
|
|
+ }
|
|
|
+ } while (mv_cesa_ahash_req_iter_next_op(&iter));
|
|
|
+
|
|
|
+ op = mv_cesa_ahash_dma_last_req(&chain, &iter, creq, op, flags);
|
|
|
+ if (IS_ERR(op)) {
|
|
|
+ ret = PTR_ERR(op);
|
|
|
+ goto err_free_tdma;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (op) {
|
|
|
+ /* Add dummy desc to wait for crypto operation end */
|
|
|
+ ret = mv_cesa_dma_add_dummy_end(&chain, flags);
|
|
|
+ if (ret)
|
|
|
+ goto err_free_tdma;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!creq->last_req)
|
|
|
+ creq->cache_ptr = req->nbytes + creq->cache_ptr -
|
|
|
+ iter.base.len;
|
|
|
+ else
|
|
|
+ creq->cache_ptr = 0;
|
|
|
+
|
|
|
+ dreq->chain = chain;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_free_tdma:
|
|
|
+ mv_cesa_dma_cleanup(dreq);
|
|
|
+ dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, DMA_TO_DEVICE);
|
|
|
+
|
|
|
+err:
|
|
|
+ mv_cesa_ahash_last_cleanup(req);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static int mv_cesa_ahash_req_init(struct ahash_request *req, bool *cached)
|
|
|
{
|
|
|
struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (cesa_dev->caps->has_tdma)
|
|
|
+ creq->req.base.type = CESA_DMA_REQ;
|
|
|
+ else
|
|
|
+ creq->req.base.type = CESA_STD_REQ;
|
|
|
|
|
|
- creq->req.base.type = CESA_STD_REQ;
|
|
|
creq->src_nents = sg_nents_for_len(req->src, req->nbytes);
|
|
|
|
|
|
- return mv_cesa_ahash_cache_req(req, cached);
|
|
|
+ ret = mv_cesa_ahash_cache_req(req, cached);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (*cached)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (creq->req.base.type == CESA_DMA_REQ)
|
|
|
+ ret = mv_cesa_ahash_dma_req_init(req);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int mv_cesa_ahash_update(struct ahash_request *req)
|
|
@@ -349,7 +729,13 @@ static int mv_cesa_ahash_update(struct ahash_request *req)
|
|
|
if (cached)
|
|
|
return 0;
|
|
|
|
|
|
- return mv_cesa_queue_req(&req->base);
|
|
|
+ ret = mv_cesa_queue_req(&req->base);
|
|
|
+ if (ret && ret != -EINPROGRESS) {
|
|
|
+ mv_cesa_ahash_cleanup(req);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int mv_cesa_ahash_final(struct ahash_request *req)
|
|
@@ -370,7 +756,11 @@ static int mv_cesa_ahash_final(struct ahash_request *req)
|
|
|
if (cached)
|
|
|
return 0;
|
|
|
|
|
|
- return mv_cesa_queue_req(&req->base);
|
|
|
+ ret = mv_cesa_queue_req(&req->base);
|
|
|
+ if (ret && ret != -EINPROGRESS)
|
|
|
+ mv_cesa_ahash_cleanup(req);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int mv_cesa_ahash_finup(struct ahash_request *req)
|
|
@@ -391,7 +781,11 @@ static int mv_cesa_ahash_finup(struct ahash_request *req)
|
|
|
if (cached)
|
|
|
return 0;
|
|
|
|
|
|
- return mv_cesa_queue_req(&req->base);
|
|
|
+ ret = mv_cesa_queue_req(&req->base);
|
|
|
+ if (ret && ret != -EINPROGRESS)
|
|
|
+ mv_cesa_ahash_cleanup(req);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int mv_cesa_sha1_init(struct ahash_request *req)
|