Lines Matching +full:sl3516 +full:- +full:crypto
1 // SPDX-License-Identifier: GPL-2.0
3 * sl3516-ce-core.c - hardware cryptographic offloader for Storlink SL3516 SoC
7 * Core file which registers crypto algorithms supported by the CryptoEngine
10 #include <linux/crypto.h>
13 #include <linux/dma-mapping.h>
23 #include <crypto/internal/rng.h>
24 #include <crypto/internal/skcipher.h>
26 #include "sl3516-ce.h"
33 ce->tx = dma_alloc_coherent(ce->dev, sz, &ce->dtx, GFP_KERNEL); in sl3516_ce_desc_init()
34 if (!ce->tx) in sl3516_ce_desc_init()
35 return -ENOMEM; in sl3516_ce_desc_init()
36 ce->rx = dma_alloc_coherent(ce->dev, sz, &ce->drx, GFP_KERNEL); in sl3516_ce_desc_init()
37 if (!ce->rx) in sl3516_ce_desc_init()
41 ce->tx[i].frame_ctrl.bits.own = CE_CPU; in sl3516_ce_desc_init()
42 ce->tx[i].next_desc.next_descriptor = ce->dtx + (i + 1) * sizeof(struct descriptor); in sl3516_ce_desc_init()
44 ce->tx[MAXDESC - 1].next_desc.next_descriptor = ce->dtx; in sl3516_ce_desc_init()
47 ce->rx[i].frame_ctrl.bits.own = CE_CPU; in sl3516_ce_desc_init()
48 ce->rx[i].next_desc.next_descriptor = ce->drx + (i + 1) * sizeof(struct descriptor); in sl3516_ce_desc_init()
50 ce->rx[MAXDESC - 1].next_desc.next_descriptor = ce->drx; in sl3516_ce_desc_init()
52 ce->pctrl = dma_alloc_coherent(ce->dev, sizeof(struct pkt_control_ecb), in sl3516_ce_desc_init()
53 &ce->dctrl, GFP_KERNEL); in sl3516_ce_desc_init()
54 if (!ce->pctrl) in sl3516_ce_desc_init()
59 dma_free_coherent(ce->dev, sz, ce->rx, ce->drx); in sl3516_ce_desc_init()
61 dma_free_coherent(ce->dev, sz, ce->tx, ce->dtx); in sl3516_ce_desc_init()
62 return -ENOMEM; in sl3516_ce_desc_init()
69 dma_free_coherent(ce->dev, sz, ce->tx, ce->dtx); in sl3516_ce_free_descs()
70 dma_free_coherent(ce->dev, sz, ce->rx, ce->drx); in sl3516_ce_free_descs()
71 dma_free_coherent(ce->dev, sizeof(struct pkt_control_ecb), ce->pctrl, in sl3516_ce_free_descs()
72 ce->dctrl); in sl3516_ce_free_descs()
82 writel(v, ce->base + IPSEC_TXDMA_CTRL); in start_dma_tx()
94 writel(v, ce->base + IPSEC_RXDMA_CTRL); in start_dma_rx()
101 dd = &ce->tx[ce->ctx]; in get_desc_tx()
102 ce->ctx++; in get_desc_tx()
103 if (ce->ctx >= MAXDESC) in get_desc_tx()
104 ce->ctx = 0; in get_desc_tx()
112 rdd = &ce->rx[ce->crx]; in get_desc_rx()
113 ce->crx++; in get_desc_rx()
114 if (ce->crx >= MAXDESC) in get_desc_rx()
115 ce->crx = 0; in get_desc_rx()
126 ce->stat_req++; in sl3516_ce_run_task()
128 reinit_completion(&ce->complete); in sl3516_ce_run_task()
129 ce->status = 0; in sl3516_ce_run_task()
131 for (i = 0; i < rctx->nr_sgd; i++) { in sl3516_ce_run_task()
132 dev_dbg(ce->dev, "%s handle DST SG %d/%d len=%d\n", __func__, in sl3516_ce_run_task()
133 i, rctx->nr_sgd, rctx->t_dst[i].len); in sl3516_ce_run_task()
135 rdd->buf_adr = rctx->t_dst[i].addr; in sl3516_ce_run_task()
136 rdd->frame_ctrl.bits.buffer_size = rctx->t_dst[i].len; in sl3516_ce_run_task()
137 rdd->frame_ctrl.bits.own = CE_DMA; in sl3516_ce_run_task()
139 rdd->next_desc.bits.eofie = 1; in sl3516_ce_run_task()
141 for (i = 0; i < rctx->nr_sgs; i++) { in sl3516_ce_run_task()
142 dev_dbg(ce->dev, "%s handle SRC SG %d/%d len=%d\n", __func__, in sl3516_ce_run_task()
143 i, rctx->nr_sgs, rctx->t_src[i].len); in sl3516_ce_run_task()
144 rctx->h->algorithm_len = rctx->t_src[i].len; in sl3516_ce_run_task()
147 dd->frame_ctrl.raw = 0; in sl3516_ce_run_task()
148 dd->flag_status.raw = 0; in sl3516_ce_run_task()
149 dd->frame_ctrl.bits.buffer_size = rctx->pctrllen; in sl3516_ce_run_task()
150 dd->buf_adr = ce->dctrl; in sl3516_ce_run_task()
151 dd->flag_status.tx_flag.tqflag = rctx->tqflag; in sl3516_ce_run_task()
152 dd->next_desc.bits.eofie = 0; in sl3516_ce_run_task()
153 dd->next_desc.bits.dec = 0; in sl3516_ce_run_task()
154 dd->next_desc.bits.sof_eof = DESC_FIRST | DESC_LAST; in sl3516_ce_run_task()
155 dd->frame_ctrl.bits.own = CE_DMA; in sl3516_ce_run_task()
158 dd->frame_ctrl.raw = 0; in sl3516_ce_run_task()
159 dd->flag_status.raw = 0; in sl3516_ce_run_task()
160 dd->frame_ctrl.bits.buffer_size = rctx->t_src[i].len; in sl3516_ce_run_task()
161 dd->buf_adr = rctx->t_src[i].addr; in sl3516_ce_run_task()
162 dd->flag_status.tx_flag.tqflag = 0; in sl3516_ce_run_task()
163 dd->next_desc.bits.eofie = 0; in sl3516_ce_run_task()
164 dd->next_desc.bits.dec = 0; in sl3516_ce_run_task()
165 dd->next_desc.bits.sof_eof = DESC_FIRST | DESC_LAST; in sl3516_ce_run_task()
166 dd->frame_ctrl.bits.own = CE_DMA; in sl3516_ce_run_task()
170 wait_for_completion_interruptible_timeout(&ce->complete, in sl3516_ce_run_task()
172 if (ce->status == 0) { in sl3516_ce_run_task()
173 dev_err(ce->dev, "DMA timeout for %s\n", name); in sl3516_ce_run_task()
174 err = -EFAULT; in sl3516_ce_run_task()
176 v = readl(ce->base + IPSEC_STATUS_REG); in sl3516_ce_run_task()
178 dev_err(ce->dev, "IPSEC_STATUS_REG %x\n", v); in sl3516_ce_run_task()
179 err = -EFAULT; in sl3516_ce_run_task()
190 ce->stat_irq++; in ce_irq_handler()
192 v = readl(ce->base + IPSEC_DMA_STATUS); in ce_irq_handler()
193 writel(v, ce->base + IPSEC_DMA_STATUS); in ce_irq_handler()
196 dev_err(ce->dev, "AHB bus Error While Tx !!!\n"); in ce_irq_handler()
198 dev_err(ce->dev, "Tx Descriptor Protocol Error !!!\n"); in ce_irq_handler()
200 dev_err(ce->dev, "AHB bus Error While Rx !!!\n"); in ce_irq_handler()
202 dev_err(ce->dev, "Rx Descriptor Protocol Error !!!\n"); in ce_irq_handler()
205 ce->stat_irq_tx++; in ce_irq_handler()
207 ce->status = 1; in ce_irq_handler()
208 complete(&ce->complete); in ce_irq_handler()
209 ce->stat_irq_rx++; in ce_irq_handler()
223 .cra_driver_name = "ecb-aes-sl3516",
246 struct sl3516_ce_dev *ce = seq->private; in sl3516_ce_debugfs_show()
250 ce->hwrng_stat_req, ce->hwrng_stat_bytes); in sl3516_ce_debugfs_show()
251 seq_printf(seq, "IRQ %lu\n", ce->stat_irq); in sl3516_ce_debugfs_show()
252 seq_printf(seq, "IRQ TX %lu\n", ce->stat_irq_tx); in sl3516_ce_debugfs_show()
253 seq_printf(seq, "IRQ RX %lu\n", ce->stat_irq_rx); in sl3516_ce_debugfs_show()
254 seq_printf(seq, "nreq %lu\n", ce->stat_req); in sl3516_ce_debugfs_show()
255 seq_printf(seq, "fallback SG count TX %lu\n", ce->fallback_sg_count_tx); in sl3516_ce_debugfs_show()
256 seq_printf(seq, "fallback SG count RX %lu\n", ce->fallback_sg_count_rx); in sl3516_ce_debugfs_show()
257 seq_printf(seq, "fallback modulo16 %lu\n", ce->fallback_mod16); in sl3516_ce_debugfs_show()
258 seq_printf(seq, "fallback align16 %lu\n", ce->fallback_align16); in sl3516_ce_debugfs_show()
259 seq_printf(seq, "fallback not same len %lu\n", ce->fallback_not_same_len); in sl3516_ce_debugfs_show()
288 dev_info(ce->dev, "DEBUG: Register %s\n", in sl3516_ce_register_algs()
292 dev_err(ce->dev, "Fail to register %s\n", in sl3516_ce_register_algs()
300 dev_err(ce->dev, "ERROR: tried to register an unknown algo\n"); in sl3516_ce_register_algs()
315 dev_info(ce->dev, "Unregister %d %s\n", i, in sl3516_ce_unregister_algs()
325 ce->ctx = 0; in sl3516_ce_start()
326 ce->crx = 0; in sl3516_ce_start()
327 writel(ce->dtx, ce->base + IPSEC_TXDMA_CURR_DESC); in sl3516_ce_start()
328 writel(ce->drx, ce->base + IPSEC_RXDMA_CURR_DESC); in sl3516_ce_start()
329 writel(0, ce->base + IPSEC_DMA_STATUS); in sl3516_ce_start()
340 reset_control_assert(ce->reset); in sl3516_ce_pm_suspend()
341 clk_disable_unprepare(ce->clks); in sl3516_ce_pm_suspend()
350 err = clk_prepare_enable(ce->clks); in sl3516_ce_pm_resume()
352 dev_err(ce->dev, "Cannot prepare_enable\n"); in sl3516_ce_pm_resume()
355 err = reset_control_deassert(ce->reset); in sl3516_ce_pm_resume()
357 dev_err(ce->dev, "Cannot deassert reset control\n"); in sl3516_ce_pm_resume()
377 pm_runtime_use_autosuspend(ce->dev); in sl3516_ce_pm_init()
378 pm_runtime_set_autosuspend_delay(ce->dev, 2000); in sl3516_ce_pm_init()
380 err = pm_runtime_set_suspended(ce->dev); in sl3516_ce_pm_init()
383 pm_runtime_enable(ce->dev); in sl3516_ce_pm_init()
389 pm_runtime_disable(ce->dev); in sl3516_ce_pm_exit()
398 ce = devm_kzalloc(&pdev->dev, sizeof(*ce), GFP_KERNEL); in sl3516_ce_probe()
400 return -ENOMEM; in sl3516_ce_probe()
402 ce->dev = &pdev->dev; in sl3516_ce_probe()
405 ce->base = devm_platform_ioremap_resource(pdev, 0); in sl3516_ce_probe()
406 if (IS_ERR(ce->base)) in sl3516_ce_probe()
407 return PTR_ERR(ce->base); in sl3516_ce_probe()
413 err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0, "crypto", ce); in sl3516_ce_probe()
415 dev_err(ce->dev, "Cannot request Crypto Engine IRQ (err=%d)\n", err); in sl3516_ce_probe()
419 ce->reset = devm_reset_control_get(&pdev->dev, NULL); in sl3516_ce_probe()
420 if (IS_ERR(ce->reset)) in sl3516_ce_probe()
421 return dev_err_probe(&pdev->dev, PTR_ERR(ce->reset), in sl3516_ce_probe()
423 ce->clks = devm_clk_get(ce->dev, NULL); in sl3516_ce_probe()
424 if (IS_ERR(ce->clks)) { in sl3516_ce_probe()
425 err = PTR_ERR(ce->clks); in sl3516_ce_probe()
426 dev_err(ce->dev, "Cannot get clock err=%d\n", err); in sl3516_ce_probe()
438 init_completion(&ce->complete); in sl3516_ce_probe()
440 ce->engine = crypto_engine_alloc_init(ce->dev, true); in sl3516_ce_probe()
441 if (!ce->engine) { in sl3516_ce_probe()
442 dev_err(ce->dev, "Cannot allocate engine\n"); in sl3516_ce_probe()
443 err = -ENOMEM; in sl3516_ce_probe()
447 err = crypto_engine_start(ce->engine); in sl3516_ce_probe()
449 dev_err(ce->dev, "Cannot start engine\n"); in sl3516_ce_probe()
461 err = pm_runtime_resume_and_get(ce->dev); in sl3516_ce_probe()
465 v = readl(ce->base + IPSEC_ID); in sl3516_ce_probe()
466 dev_info(ce->dev, "SL3516 dev %lx rev %lx\n", in sl3516_ce_probe()
469 v = readl(ce->base + IPSEC_DMA_DEVICE_ID); in sl3516_ce_probe()
470 dev_info(ce->dev, "SL3516 DMA dev %lx rev %lx\n", in sl3516_ce_probe()
474 pm_runtime_put_sync(ce->dev); in sl3516_ce_probe()
478 ce->dbgfs_dir = debugfs_create_dir("sl3516", NULL); in sl3516_ce_probe()
479 ce->dbgfs_stats = debugfs_create_file("stats", 0444, in sl3516_ce_probe()
480 ce->dbgfs_dir, ce, in sl3516_ce_probe()
490 crypto_engine_exit(ce->engine); in sl3516_ce_probe()
504 crypto_engine_exit(ce->engine); in sl3516_ce_remove()
509 debugfs_remove_recursive(ce->dbgfs_dir); in sl3516_ce_remove()
516 { .compatible = "cortina,sl3516-crypto"},
525 .name = "sl3516-crypto",
533 MODULE_DESCRIPTION("SL3516 cryptographic offloader");