Lines Matching full:ss

3  * sun8i-ss-core.c - hardware cryptographic offloader for
28 #include "sun8i-ss.h"
60 int sun8i_ss_get_engine_number(struct sun8i_ss_dev *ss) in sun8i_ss_get_engine_number() argument
62 return atomic_inc_return(&ss->flow) % MAXFLOW; in sun8i_ss_get_engine_number()
65 int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx, in sun8i_ss_run_task() argument
74 ss->flows[flow].stat_req++; in sun8i_ss_run_task()
105 mutex_lock(&ss->mlock); in sun8i_ss_run_task()
106 writel(rctx->p_key, ss->base + SS_KEY_ADR_REG); in sun8i_ss_run_task()
111 writel(rctx->p_iv[0], ss->base + SS_IV_ADR_REG); in sun8i_ss_run_task()
113 writel(rctx->t_dst[i - 1].addr + rctx->t_dst[i - 1].len * 4 - ivlen, ss->base + SS_IV_ADR_REG); in sun8i_ss_run_task()
115 writel(rctx->p_iv[i], ss->base + SS_IV_ADR_REG); in sun8i_ss_run_task()
119 dev_dbg(ss->dev, in sun8i_ss_run_task()
126 writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG); in sun8i_ss_run_task()
127 writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG); in sun8i_ss_run_task()
128 writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG); in sun8i_ss_run_task()
130 reinit_completion(&ss->flows[flow].complete); in sun8i_ss_run_task()
131 ss->flows[flow].status = 0; in sun8i_ss_run_task()
134 writel(v, ss->base + SS_CTL_REG); in sun8i_ss_run_task()
135 mutex_unlock(&ss->mlock); in sun8i_ss_run_task()
136 wait_for_completion_interruptible_timeout(&ss->flows[flow].complete, in sun8i_ss_run_task()
138 if (ss->flows[flow].status == 0) { in sun8i_ss_run_task()
139 dev_err(ss->dev, "DMA timeout for %s\n", name); in sun8i_ss_run_task()
149 struct sun8i_ss_dev *ss = (struct sun8i_ss_dev *)data; in ss_irq_handler() local
153 p = readl(ss->base + SS_INT_STA_REG); in ss_irq_handler()
156 writel(BIT(flow), ss->base + SS_INT_STA_REG); in ss_irq_handler()
157 ss->flows[flow].status = 1; in ss_irq_handler()
158 complete(&ss->flows[flow].complete); in ss_irq_handler()
173 .cra_driver_name = "cbc-aes-sun8i-ss",
200 .cra_driver_name = "ecb-aes-sun8i-ss",
226 .cra_driver_name = "cbc-des3-sun8i-ss",
253 .cra_driver_name = "ecb-des3-sun8i-ss",
278 .cra_driver_name = "sun8i-ss-prng",
307 .cra_driver_name = "md5-sun8i-ss",
337 .cra_driver_name = "sha1-sun8i-ss",
367 .cra_driver_name = "sha224-sun8i-ss",
397 .cra_driver_name = "sha256-sun8i-ss",
428 .cra_driver_name = "hmac-sha1-sun8i-ss",
449 struct sun8i_ss_dev *ss = seq->private; in sun8i_ss_debugfs_show() local
453 seq_printf(seq, "Channel %d: nreq %lu\n", i, ss->flows[i].stat_req); in sun8i_ss_debugfs_show()
456 if (!ss_algs[i].ss) in sun8i_ss_debugfs_show()
506 static void sun8i_ss_free_flows(struct sun8i_ss_dev *ss, int i) in sun8i_ss_free_flows() argument
509 crypto_engine_exit(ss->flows[i].engine); in sun8i_ss_free_flows()
517 static int allocate_flows(struct sun8i_ss_dev *ss) in allocate_flows() argument
521 ss->flows = devm_kcalloc(ss->dev, MAXFLOW, sizeof(struct sun8i_ss_flow), in allocate_flows()
523 if (!ss->flows) in allocate_flows()
527 init_completion(&ss->flows[i].complete); in allocate_flows()
529 ss->flows[i].biv = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, in allocate_flows()
531 if (!ss->flows[i].biv) { in allocate_flows()
537 ss->flows[i].iv[j] = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, in allocate_flows()
539 if (!ss->flows[i].iv[j]) { in allocate_flows()
546 ss->flows[i].pad = devm_kmalloc(ss->dev, MAX_PAD_SIZE, in allocate_flows()
548 if (!ss->flows[i].pad) { in allocate_flows()
552 ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE, in allocate_flows()
554 if (!ss->flows[i].result) { in allocate_flows()
559 ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true); in allocate_flows()
560 if (!ss->flows[i].engine) { in allocate_flows()
561 dev_err(ss->dev, "Cannot allocate engine\n"); in allocate_flows()
566 err = crypto_engine_start(ss->flows[i].engine); in allocate_flows()
568 dev_err(ss->dev, "Cannot start engine\n"); in allocate_flows()
574 sun8i_ss_free_flows(ss, i); in allocate_flows()
584 struct sun8i_ss_dev *ss = dev_get_drvdata(dev); in sun8i_ss_pm_suspend() local
587 reset_control_assert(ss->reset); in sun8i_ss_pm_suspend()
589 clk_disable_unprepare(ss->ssclks[i]); in sun8i_ss_pm_suspend()
595 struct sun8i_ss_dev *ss = dev_get_drvdata(dev); in sun8i_ss_pm_resume() local
599 if (!ss->variant->ss_clks[i].name) in sun8i_ss_pm_resume()
601 err = clk_prepare_enable(ss->ssclks[i]); in sun8i_ss_pm_resume()
603 dev_err(ss->dev, "Cannot prepare_enable %s\n", in sun8i_ss_pm_resume()
604 ss->variant->ss_clks[i].name); in sun8i_ss_pm_resume()
608 err = reset_control_deassert(ss->reset); in sun8i_ss_pm_resume()
610 dev_err(ss->dev, "Cannot deassert reset control\n"); in sun8i_ss_pm_resume()
614 writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG); in sun8i_ss_pm_resume()
626 static int sun8i_ss_pm_init(struct sun8i_ss_dev *ss) in sun8i_ss_pm_init() argument
630 pm_runtime_use_autosuspend(ss->dev); in sun8i_ss_pm_init()
631 pm_runtime_set_autosuspend_delay(ss->dev, 2000); in sun8i_ss_pm_init()
633 err = pm_runtime_set_suspended(ss->dev); in sun8i_ss_pm_init()
636 pm_runtime_enable(ss->dev); in sun8i_ss_pm_init()
640 static void sun8i_ss_pm_exit(struct sun8i_ss_dev *ss) in sun8i_ss_pm_exit() argument
642 pm_runtime_disable(ss->dev); in sun8i_ss_pm_exit()
645 static int sun8i_ss_register_algs(struct sun8i_ss_dev *ss) in sun8i_ss_register_algs() argument
651 ss_algs[i].ss = ss; in sun8i_ss_register_algs()
655 ss_method = ss->variant->alg_cipher[id]; in sun8i_ss_register_algs()
657 dev_info(ss->dev, in sun8i_ss_register_algs()
660 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
664 ss_method = ss->variant->op_mode[id]; in sun8i_ss_register_algs()
666 dev_info(ss->dev, "DEBUG: Blockmode of %s not supported\n", in sun8i_ss_register_algs()
668 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
671 dev_info(ss->dev, "DEBUG: Register %s\n", in sun8i_ss_register_algs()
675 dev_err(ss->dev, "Fail to register %s\n", in sun8i_ss_register_algs()
677 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
684 dev_err(ss->dev, "Fail to register %s\n", in sun8i_ss_register_algs()
686 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
691 ss_method = ss->variant->alg_hash[id]; in sun8i_ss_register_algs()
693 dev_info(ss->dev, in sun8i_ss_register_algs()
696 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
699 dev_info(ss->dev, "Register %s\n", in sun8i_ss_register_algs()
703 dev_err(ss->dev, "ERROR: Fail to register %s\n", in sun8i_ss_register_algs()
705 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
710 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
711 dev_err(ss->dev, "ERROR: tried to register an unknown algo\n"); in sun8i_ss_register_algs()
717 static void sun8i_ss_unregister_algs(struct sun8i_ss_dev *ss) in sun8i_ss_unregister_algs() argument
722 if (!ss_algs[i].ss) in sun8i_ss_unregister_algs()
726 dev_info(ss->dev, "Unregister %d %s\n", i, in sun8i_ss_unregister_algs()
731 dev_info(ss->dev, "Unregister %d %s\n", i, in sun8i_ss_unregister_algs()
736 dev_info(ss->dev, "Unregister %d %s\n", i, in sun8i_ss_unregister_algs()
744 static int sun8i_ss_get_clks(struct sun8i_ss_dev *ss) in sun8i_ss_get_clks() argument
750 if (!ss->variant->ss_clks[i].name) in sun8i_ss_get_clks()
752 ss->ssclks[i] = devm_clk_get(ss->dev, ss->variant->ss_clks[i].name); in sun8i_ss_get_clks()
753 if (IS_ERR(ss->ssclks[i])) { in sun8i_ss_get_clks()
754 err = PTR_ERR(ss->ssclks[i]); in sun8i_ss_get_clks()
755 dev_err(ss->dev, "Cannot get %s SS clock err=%d\n", in sun8i_ss_get_clks()
756 ss->variant->ss_clks[i].name, err); in sun8i_ss_get_clks()
759 cr = clk_get_rate(ss->ssclks[i]); in sun8i_ss_get_clks()
762 if (ss->variant->ss_clks[i].freq > 0 && in sun8i_ss_get_clks()
763 cr != ss->variant->ss_clks[i].freq) { in sun8i_ss_get_clks()
764 dev_info(ss->dev, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n", in sun8i_ss_get_clks()
765 ss->variant->ss_clks[i].name, in sun8i_ss_get_clks()
766 ss->variant->ss_clks[i].freq, in sun8i_ss_get_clks()
767 ss->variant->ss_clks[i].freq / 1000000, in sun8i_ss_get_clks()
769 err = clk_set_rate(ss->ssclks[i], ss->variant->ss_clks[i].freq); in sun8i_ss_get_clks()
771 dev_err(ss->dev, "Fail to set %s clk speed to %lu hz\n", in sun8i_ss_get_clks()
772 ss->variant->ss_clks[i].name, in sun8i_ss_get_clks()
773 ss->variant->ss_clks[i].freq); in sun8i_ss_get_clks()
775 if (ss->variant->ss_clks[i].max_freq > 0 && in sun8i_ss_get_clks()
776 cr > ss->variant->ss_clks[i].max_freq) in sun8i_ss_get_clks()
777 dev_warn(ss->dev, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)", in sun8i_ss_get_clks()
778 ss->variant->ss_clks[i].name, cr, in sun8i_ss_get_clks()
779 ss->variant->ss_clks[i].max_freq); in sun8i_ss_get_clks()
786 struct sun8i_ss_dev *ss; in sun8i_ss_probe() local
790 ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL); in sun8i_ss_probe()
791 if (!ss) in sun8i_ss_probe()
794 ss->dev = &pdev->dev; in sun8i_ss_probe()
795 platform_set_drvdata(pdev, ss); in sun8i_ss_probe()
797 ss->variant = of_device_get_match_data(&pdev->dev); in sun8i_ss_probe()
798 if (!ss->variant) { in sun8i_ss_probe()
803 ss->base = devm_platform_ioremap_resource(pdev, 0); in sun8i_ss_probe()
804 if (IS_ERR(ss->base)) in sun8i_ss_probe()
805 return PTR_ERR(ss->base); in sun8i_ss_probe()
807 err = sun8i_ss_get_clks(ss); in sun8i_ss_probe()
815 ss->reset = devm_reset_control_get(&pdev->dev, NULL); in sun8i_ss_probe()
816 if (IS_ERR(ss->reset)) in sun8i_ss_probe()
817 return dev_err_probe(&pdev->dev, PTR_ERR(ss->reset), in sun8i_ss_probe()
820 mutex_init(&ss->mlock); in sun8i_ss_probe()
822 err = allocate_flows(ss); in sun8i_ss_probe()
826 err = sun8i_ss_pm_init(ss); in sun8i_ss_probe()
830 err = devm_request_irq(&pdev->dev, irq, ss_irq_handler, 0, "sun8i-ss", ss); in sun8i_ss_probe()
832 dev_err(ss->dev, "Cannot request SecuritySystem IRQ (err=%d)\n", err); in sun8i_ss_probe()
836 err = sun8i_ss_register_algs(ss); in sun8i_ss_probe()
840 err = pm_runtime_resume_and_get(ss->dev); in sun8i_ss_probe()
844 v = readl(ss->base + SS_CTL_REG); in sun8i_ss_probe()
849 pm_runtime_put_sync(ss->dev); in sun8i_ss_probe()
853 ss->dbgfs_dir = debugfs_create_dir("sun8i-ss", NULL); in sun8i_ss_probe()
854 ss->dbgfs_stats = debugfs_create_file("stats", 0444, in sun8i_ss_probe()
855 ss->dbgfs_dir, ss, in sun8i_ss_probe()
861 sun8i_ss_unregister_algs(ss); in sun8i_ss_probe()
863 sun8i_ss_pm_exit(ss); in sun8i_ss_probe()
865 sun8i_ss_free_flows(ss, MAXFLOW - 1); in sun8i_ss_probe()
871 struct sun8i_ss_dev *ss = platform_get_drvdata(pdev); in sun8i_ss_remove() local
873 sun8i_ss_unregister_algs(ss); in sun8i_ss_remove()
876 debugfs_remove_recursive(ss->dbgfs_dir); in sun8i_ss_remove()
879 sun8i_ss_free_flows(ss, MAXFLOW - 1); in sun8i_ss_remove()
881 sun8i_ss_pm_exit(ss); in sun8i_ss_remove()
899 .name = "sun8i-ss",