[PATCH v3 4/4] crypto: starfive - Add hash and HMAC support
Hillf Danton
hdanton at sina.com
Mon Mar 13 17:17:44 PDT 2023
On 13 Mar 2023 21:56:46 +0800 Jia Jie Ho <jiajie.ho at starfivetech.com>
> +static int starfive_hash_xmit_dma(struct starfive_cryp_ctx *ctx)
> +{
> + struct starfive_cryp_request_ctx *rctx = ctx->rctx;
> + struct starfive_cryp_dev *cryp = ctx->cryp;
> + struct dma_async_tx_descriptor *in_desc;
> + dma_cookie_t cookie;
> + union starfive_alg_cr alg_cr;
> + int total_len;
> + int ret;
> +
> + if (!rctx->total)
> + return 0;
> +
> + writel(rctx->total, cryp->base + STARFIVE_DMA_IN_LEN_OFFSET);
> +
> + total_len = rctx->total;
> + total_len = (total_len & 0x3) ? (((total_len >> 2) + 1) << 2) : total_len;
> + sg_dma_len(rctx->in_sg) = total_len;
> +
> + alg_cr.v = 0;
> + alg_cr.start = 1;
> + alg_cr.hash_dma_en = 1;
> +
> + writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET);
> +
> + ret = dma_map_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE);
> + if (!ret)
> + return dev_err_probe(cryp->dev, -EINVAL, "dma_map_sg() error\n");
> +
> + cryp->cfg_in.direction = DMA_MEM_TO_DEV;
> + cryp->cfg_in.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> + cryp->cfg_in.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> + cryp->cfg_in.src_maxburst = cryp->dma_maxburst;
> + cryp->cfg_in.dst_maxburst = cryp->dma_maxburst;
> + cryp->cfg_in.dst_addr = cryp->phys_base + STARFIVE_ALG_FIFO_OFFSET;
> +
> + dmaengine_slave_config(cryp->tx, &cryp->cfg_in);
> +
> + in_desc = dmaengine_prep_slave_sg(cryp->tx, rctx->in_sg,
> + rctx->in_sg_len, DMA_MEM_TO_DEV,
> + DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +
> + if (!in_desc)
> + return -EINVAL;
> +
> + reinit_completion(&cryp->tx_comp);
What breaks without reinit?
> +
> + in_desc->callback = starfive_hash_dma_callback;
> + in_desc->callback_param = cryp;
> +
> + cookie = dmaengine_submit(in_desc);
> + dma_async_issue_pending(cryp->tx);
> +
> + if (!wait_for_completion_timeout(&cryp->tx_comp,
> + msecs_to_jiffies(10000))) {
> + dev_err(cryp->dev, "wait_for_completion_timeout error, cookie = %x\n",
> + dma_async_is_tx_complete(cryp->rx, cookie,
> + NULL, NULL));
What prevents wakeup from coming in case of timeout?
> + }
> +
> + dma_unmap_sg(cryp->dev, rctx->in_sg, rctx->in_sg_len, DMA_TO_DEVICE);
> +
> + alg_cr.v = 0;
> + alg_cr.clear = 1;
> +
> + writel(alg_cr.v, cryp->base + STARFIVE_ALG_CR_OFFSET);
> +
> + return 0;
> +}
More information about the linux-riscv
mailing list