// SPDX-License-Identifier: GPL-2.0
/*
 * sl3516-ce-core.c - hardware cryptographic offloader for Storlink SL3516 SoC
 *
 * Copyright (C) 2021 Corentin Labbe <clabbe@baylibre.com>
 *
 * Core file which registers crypto algorithms supported by the CryptoEngine
 */
#include <linux/clk.h>
#include <linux/crypto.h>
#include <linux/debugfs.h>
#include <linux/dev_printk.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <crypto/internal/rng.h>
#include <crypto/internal/skcipher.h>

#include "sl3516-ce.h"

static int sl3516_ce_desc_init(struct sl3516_ce_dev *ce)
{
	const size_t sz = sizeof(struct descriptor) * MAXDESC;
	int i;

	ce->tx = dma_alloc_coherent(ce->dev, sz, &ce->dtx, GFP_KERNEL);
	if (!ce->tx)
		return -ENOMEM;
	ce->rx = dma_alloc_coherent(ce->dev, sz, &ce->drx, GFP_KERNEL);
	if (!ce->rx)
		goto err_rx;

	for (i = 0; i < MAXDESC; i++) {
		ce->tx[i].frame_ctrl.bits.own = CE_CPU;
		ce->tx[i].next_desc.next_descriptor = ce->dtx + (i + 1) * sizeof(struct descriptor);
	}
	ce->tx[MAXDESC - 1].next_desc.next_descriptor = ce->dtx;

	for (i = 0; i < MAXDESC; i++) {
		ce->rx[i].frame_ctrl.bits.own = CE_CPU;
		ce->rx[i].next_desc.next_descriptor = ce->drx + (i + 1) * sizeof(struct descriptor);
	}
	ce->rx[MAXDESC - 1].next_desc.next_descriptor = ce->drx;

	ce->pctrl = dma_alloc_coherent(ce->dev, sizeof(struct pkt_control_ecb),
				       &ce->dctrl, GFP_KERNEL);
	if (!ce->pctrl)
		goto err_pctrl;

	return 0;
err_pctrl:
	dma_free_coherent(ce->dev, sz, ce->rx, ce->drx);
err_rx:
	dma_free_coherent(ce->dev, sz, ce->tx, ce->dtx);
	return -ENOMEM;
}

static void sl3516_ce_free_descs(struct sl3516_ce_dev *ce)
{
	const size_t sz = sizeof(struct descriptor) * MAXDESC;

	dma_free_coherent(ce->dev, sz, ce->tx, ce->dtx);
	dma_free_coherent(ce->dev, sz, ce->rx, ce->drx);
	dma_free_coherent(ce->dev, sizeof(struct pkt_control_ecb), ce->pctrl,
			  ce->dctrl);
}

static void start_dma_tx(struct sl3516_ce_dev *ce)
{
	u32 v;

	v = TXDMA_CTRL_START | TXDMA_CTRL_CHAIN_MODE | TXDMA_CTRL_CONTINUE | \
		TXDMA_CTRL_INT_FAIL | TXDMA_CTRL_INT_PERR | TXDMA_CTRL_BURST_UNK;

	writel(v, ce->base + IPSEC_TXDMA_CTRL);
}

static void start_dma_rx(struct sl3516_ce_dev *ce)
{
	u32 v;

	v = RXDMA_CTRL_START | RXDMA_CTRL_CHAIN_MODE | RXDMA_CTRL_CONTINUE | \
		RXDMA_CTRL_BURST_UNK | RXDMA_CTRL_INT_FINISH | \
		RXDMA_CTRL_INT_FAIL | RXDMA_CTRL_INT_PERR | \
		RXDMA_CTRL_INT_EOD | RXDMA_CTRL_INT_EOF;

	writel(v, ce->base + IPSEC_RXDMA_CTRL);
}

static struct descriptor *get_desc_tx(struct sl3516_ce_dev *ce)
{
	struct descriptor *dd;

	dd = &ce->tx[ce->ctx];
	ce->ctx++;
	if (ce->ctx >= MAXDESC)
		ce->ctx = 0;
	return dd;
}

static struct descriptor *get_desc_rx(struct sl3516_ce_dev *ce)
{
	struct descriptor *rdd;

	rdd = &ce->rx[ce->crx];
	ce->crx++;
	if (ce->crx >= MAXDESC)
		ce->crx = 0;
	return rdd;
}

int sl3516_ce_run_task(struct sl3516_ce_dev *ce, struct sl3516_ce_cipher_req_ctx *rctx,
		       const char *name)
{
	struct descriptor *dd, *rdd = NULL;
	u32 v;
	int i, err = 0;

	ce->stat_req++;

	reinit_completion(&ce->complete);
	ce->status = 0;

	for (i = 0; i < rctx->nr_sgd; i++) {
		dev_dbg(ce->dev, "%s handle DST SG %d/%d len=%d\n", __func__,
			i, rctx->nr_sgd, rctx->t_dst[i].len);
		rdd = get_desc_rx(ce);
		rdd->buf_adr = rctx->t_dst[i].addr;
		rdd->frame_ctrl.bits.buffer_size = rctx->t_dst[i].len;
		rdd->frame_ctrl.bits.own = CE_DMA;
	}
	rdd->next_desc.bits.eofie = 1;

	for (i = 0; i < rctx->nr_sgs; i++) {
		dev_dbg(ce->dev, "%s handle SRC SG %d/%d len=%d\n", __func__,
			i, rctx->nr_sgs, rctx->t_src[i].len);
		rctx->h->algorithm_len = rctx->t_src[i].len;

		dd = get_desc_tx(ce);
		dd->frame_ctrl.raw = 0;
		dd->flag_status.raw = 0;
		dd->frame_ctrl.bits.buffer_size = rctx->pctrllen;
		dd->buf_adr = ce->dctrl;
		dd->flag_status.tx_flag.tqflag = rctx->tqflag;
		dd->next_desc.bits.eofie = 0;
		dd->next_desc.bits.dec = 0;
		dd->next_desc.bits.sof_eof = DESC_FIRST | DESC_LAST;
		dd->frame_ctrl.bits.own = CE_DMA;

		dd = get_desc_tx(ce);
		dd->frame_ctrl.raw = 0;
		dd->flag_status.raw = 0;
		dd->frame_ctrl.bits.buffer_size = rctx->t_src[i].len;
		dd->buf_adr = rctx->t_src[i].addr;
		dd->flag_status.tx_flag.tqflag = 0;
		dd->next_desc.bits.eofie = 0;
		dd->next_desc.bits.dec = 0;
		dd->next_desc.bits.sof_eof = DESC_FIRST | DESC_LAST;
		dd->frame_ctrl.bits.own = CE_DMA;
		start_dma_tx(ce);
		start_dma_rx(ce);
	}
	wait_for_completion_interruptible_timeout(&ce->complete,
						  msecs_to_jiffies(5000));
	if (ce->status == 0) {
		dev_err(ce->dev, "DMA timeout for %s\n", name);
		err = -EFAULT;
	}
	v = readl(ce->base + IPSEC_STATUS_REG);
	if (v & 0xFFF) {
		dev_err(ce->dev, "IPSEC_STATUS_REG %x\n", v);
		err = -EFAULT;
	}

	return err;
}

static irqreturn_t ce_irq_handler(int irq, void *data)
{
	struct sl3516_ce_dev *ce = (struct sl3516_ce_dev *)data;
	u32 v;

	ce->stat_irq++;

	v = readl(ce->base + IPSEC_DMA_STATUS);
	writel(v, ce->base + IPSEC_DMA_STATUS);

	if (v & DMA_STATUS_TS_DERR)
		dev_err(ce->dev, "AHB bus Error While Tx !!!\n");
	if (v & DMA_STATUS_TS_PERR)
		dev_err(ce->dev, "Tx Descriptor Protocol Error !!!\n");
	if (v & DMA_STATUS_RS_DERR)
		dev_err(ce->dev, "AHB bus Error While Rx !!!\n");
	if (v & DMA_STATUS_RS_PERR)
		dev_err(ce->dev, "Rx Descriptor Protocol Error !!!\n");

	if (v & DMA_STATUS_TS_EOFI)
		ce->stat_irq_tx++;
	if (v & DMA_STATUS_RS_EOFI) {
		ce->status = 1;
		complete(&ce->complete);
		ce->stat_irq_rx++;
		return IRQ_HANDLED;
	}

	return IRQ_HANDLED;
}

static struct sl3516_ce_alg_template ce_algs[] = {
{
	.type = CRYPTO_ALG_TYPE_SKCIPHER,
	.mode = ECB_AES,
	.alg.skcipher = {
		.base = {
			.cra_name = "ecb(aes)",
			.cra_driver_name = "ecb-aes-sl3516",
			.cra_priority = 400,
			.cra_blocksize = AES_BLOCK_SIZE,
			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
			.cra_ctxsize = sizeof(struct sl3516_ce_cipher_tfm_ctx),
			.cra_module = THIS_MODULE,
			.cra_alignmask = 0xf,
			.cra_init = sl3516_ce_cipher_init,
			.cra_exit = sl3516_ce_cipher_exit,
		},
		.min_keysize	= AES_MIN_KEY_SIZE,
		.max_keysize	= AES_MAX_KEY_SIZE,
		.setkey		= sl3516_ce_aes_setkey,
		.encrypt	= sl3516_ce_skencrypt,
		.decrypt	= sl3516_ce_skdecrypt,
	}
},
};

#ifdef CONFIG_CRYPTO_DEV_SL3516_DEBUG
static int sl3516_ce_debugfs_show(struct seq_file *seq, void *v)
{
	struct sl3516_ce_dev *ce = seq->private;
	unsigned int i;

	seq_printf(seq, "HWRNG %lu %lu\n",
		   ce->hwrng_stat_req, ce->hwrng_stat_bytes);
	seq_printf(seq, "IRQ %lu\n", ce->stat_irq);
	seq_printf(seq, "IRQ TX %lu\n", ce->stat_irq_tx);
	seq_printf(seq, "IRQ RX %lu\n", ce->stat_irq_rx);
	seq_printf(seq, "nreq %lu\n", ce->stat_req);
	seq_printf(seq, "fallback SG count TX %lu\n", ce->fallback_sg_count_tx);
	seq_printf(seq, "fallback SG count RX %lu\n", ce->fallback_sg_count_rx);
	seq_printf(seq, "fallback modulo16 %lu\n", ce->fallback_mod16);
	seq_printf(seq, "fallback align16 %lu\n", ce->fallback_align16);
	seq_printf(seq, "fallback not same len %lu\n", ce->fallback_not_same_len);

	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
		if (!ce_algs[i].ce)
			continue;
		switch (ce_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
				   ce_algs[i].alg.skcipher.base.cra_driver_name,
				   ce_algs[i].alg.skcipher.base.cra_name,
				   ce_algs[i].stat_req, ce_algs[i].stat_fb);
			break;
		}
	}
	return 0;
}

DEFINE_SHOW_ATTRIBUTE(sl3516_ce_debugfs);
#endif

static int sl3516_ce_register_algs(struct sl3516_ce_dev *ce)
{
	int err;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
		ce_algs[i].ce = ce;
		switch (ce_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			dev_info(ce->dev, "DEBUG: Register %s\n",
				 ce_algs[i].alg.skcipher.base.cra_name);
			err = crypto_register_skcipher(&ce_algs[i].alg.skcipher);
			if (err) {
				dev_err(ce->dev, "Fail to register %s\n",
					ce_algs[i].alg.skcipher.base.cra_name);
				ce_algs[i].ce = NULL;
				return err;
			}
			break;
		default:
			ce_algs[i].ce = NULL;
			dev_err(ce->dev, "ERROR: tried to register an unknown algo\n");
		}
	}
	return 0;
}

static void sl3516_ce_unregister_algs(struct sl3516_ce_dev *ce)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
		if (!ce_algs[i].ce)
			continue;
		switch (ce_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			dev_info(ce->dev, "Unregister %d %s\n", i,
				 ce_algs[i].alg.skcipher.base.cra_name);
			crypto_unregister_skcipher(&ce_algs[i].alg.skcipher);
			break;
		}
	}
}

static void sl3516_ce_start(struct sl3516_ce_dev *ce)
{
	ce->ctx = 0;
	ce->crx = 0;
	writel(ce->dtx, ce->base + IPSEC_TXDMA_CURR_DESC);
	writel(ce->drx, ce->base + IPSEC_RXDMA_CURR_DESC);
	writel(0, ce->base + IPSEC_DMA_STATUS);
}

/*
 * Power management strategy: The device is suspended unless a TFM exists for
 * one of the algorithms proposed by this driver.
 */
static int sl3516_ce_pm_suspend(struct device *dev)
{
	struct sl3516_ce_dev *ce = dev_get_drvdata(dev);

	reset_control_assert(ce->reset);
	clk_disable_unprepare(ce->clks);
	return 0;
}

static int sl3516_ce_pm_resume(struct device *dev)
{
	struct sl3516_ce_dev *ce = dev_get_drvdata(dev);
	int err;

	err = clk_prepare_enable(ce->clks);
	if (err) {
		dev_err(ce->dev, "Cannot prepare_enable\n");
		goto error;
	}
	err = reset_control_deassert(ce->reset);
	if (err) {
		dev_err(ce->dev, "Cannot deassert reset control\n");
		goto error;
	}

	sl3516_ce_start(ce);

	return 0;
error:
	sl3516_ce_pm_suspend(dev);
	return err;
}

static const struct dev_pm_ops sl3516_ce_pm_ops = {
	SET_RUNTIME_PM_OPS(sl3516_ce_pm_suspend, sl3516_ce_pm_resume, NULL)
};

static int sl3516_ce_pm_init(struct sl3516_ce_dev *ce)
{
	int err;

	pm_runtime_use_autosuspend(ce->dev);
	pm_runtime_set_autosuspend_delay(ce->dev, 2000);

	err = pm_runtime_set_suspended(ce->dev);
	if (err)
		return err;
	pm_runtime_enable(ce->dev);
	return err;
}

static void sl3516_ce_pm_exit(struct sl3516_ce_dev *ce)
{
	pm_runtime_disable(ce->dev);
}

static int sl3516_ce_probe(struct platform_device *pdev)
{
	struct sl3516_ce_dev *ce;
	int err, irq;
	u32 v;

	ce = devm_kzalloc(&pdev->dev, sizeof(*ce), GFP_KERNEL);
	if (!ce)
		return -ENOMEM;

	ce->dev = &pdev->dev;
	platform_set_drvdata(pdev, ce);

	ce->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(ce->base))
		return PTR_ERR(ce->base);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0, "crypto", ce);
	if (err) {
		dev_err(ce->dev, "Cannot request Crypto Engine IRQ (err=%d)\n", err);
		return err;
	}

	ce->reset = devm_reset_control_get(&pdev->dev, NULL);
	if (IS_ERR(ce->reset))
		return dev_err_probe(&pdev->dev, PTR_ERR(ce->reset),
				     "No reset control found\n");
	ce->clks = devm_clk_get(ce->dev, NULL);
	if (IS_ERR(ce->clks)) {
		err = PTR_ERR(ce->clks);
		dev_err(ce->dev, "Cannot get clock err=%d\n", err);
		return err;
	}

	err = sl3516_ce_desc_init(ce);
	if (err)
		return err;

	err = sl3516_ce_pm_init(ce);
	if (err)
		goto error_pm;

	init_completion(&ce->complete);

	ce->engine = crypto_engine_alloc_init(ce->dev, true);
	if (!ce->engine) {
		dev_err(ce->dev, "Cannot allocate engine\n");
		err = -ENOMEM;
		goto error_engine;
	}

	err = crypto_engine_start(ce->engine);
	if (err) {
		dev_err(ce->dev, "Cannot start engine\n");
		goto error_engine;
	}

	err = sl3516_ce_register_algs(ce);
	if (err)
		goto error_alg;

	err = sl3516_ce_rng_register(ce);
	if (err)
		goto error_rng;

	err = pm_runtime_resume_and_get(ce->dev);
	if (err < 0)
		goto error_pmuse;

	v = readl(ce->base + IPSEC_ID);
	dev_info(ce->dev, "SL3516 dev %lx rev %lx\n",
		 v & GENMASK(31, 4),
		 v & GENMASK(3, 0));
	v = readl(ce->base + IPSEC_DMA_DEVICE_ID);
	dev_info(ce->dev, "SL3516 DMA dev %lx rev %lx\n",
		 v & GENMASK(15, 4),
		 v & GENMASK(3, 0));

	pm_runtime_put_sync(ce->dev);

#ifdef CONFIG_CRYPTO_DEV_SL3516_DEBUG
	/* Ignore error of debugfs */
	ce->dbgfs_dir = debugfs_create_dir("sl3516", NULL);
	ce->dbgfs_stats = debugfs_create_file("stats", 0444,
					      ce->dbgfs_dir, ce,
					      &sl3516_ce_debugfs_fops);
#endif

	return 0;
error_pmuse:
	sl3516_ce_rng_unregister(ce);
error_rng:
	sl3516_ce_unregister_algs(ce);
error_alg:
	crypto_engine_exit(ce->engine);
error_engine:
	sl3516_ce_pm_exit(ce);
error_pm:
	sl3516_ce_free_descs(ce);
	return err;
}

static int sl3516_ce_remove(struct platform_device *pdev)
{
	struct sl3516_ce_dev *ce = platform_get_drvdata(pdev);

	sl3516_ce_rng_unregister(ce);
	sl3516_ce_unregister_algs(ce);
	crypto_engine_exit(ce->engine);
	sl3516_ce_pm_exit(ce);
	sl3516_ce_free_descs(ce);

#ifdef CONFIG_CRYPTO_DEV_SL3516_DEBUG
	debugfs_remove_recursive(ce->dbgfs_dir);
#endif

	return 0;
}

static const struct of_device_id sl3516_ce_crypto_of_match_table[] = {
	{ .compatible = "cortina,sl3516-crypto"},
	{}
};
MODULE_DEVICE_TABLE(of, sl3516_ce_crypto_of_match_table);

static struct platform_driver sl3516_ce_driver = {
	.probe		 = sl3516_ce_probe,
	.remove		 = sl3516_ce_remove,
	.driver		 = {
		.name		= "sl3516-crypto",
		.pm		= &sl3516_ce_pm_ops,
		.of_match_table	= sl3516_ce_crypto_of_match_table,
	},
};

module_platform_driver(sl3516_ce_driver);

MODULE_DESCRIPTION("SL3516 cryptographic offloader");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Corentin Labbe <clabbe@baylibre.com>");
