// SPDX-License-Identifier: GPL-2.0
/*
 * sun8i-ce-trng.c - hardware cryptographic offloader for
 * Allwinner H3/A64/H5/H2+/H6/R40 SoC
 *
 * Copyright (C) 2015-2020 Corentin Labbe <clabbe@baylibre.com>
 *
 * This file handle the TRNG
 *
 * You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst
 */
#include "sun8i-ce.h"
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/hw_random.h>
/*
 * Note that according to the algorithm ID, 2 versions of the TRNG exists,
 * The first present in H3/H5/R40/A64 and the second present in H6.
 * This file adds support for both, but only the second is working
 * reliabily according to rngtest.
 **/

static int sun8i_ce_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
	struct sun8i_ce_dev *ce;
	dma_addr_t dma_dst;
	int err = 0;
	int flow = 3;
	unsigned int todo;
	struct sun8i_ce_flow *chan;
	struct ce_task *cet;
	u32 common;
	void *d;

	ce = container_of(rng, struct sun8i_ce_dev, trng);

	/* round the data length to a multiple of 32*/
	todo = max + 32;
	todo -= todo % 32;

	d = kzalloc(todo, GFP_KERNEL | GFP_DMA);
	if (!d)
		return -ENOMEM;

#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
	ce->hwrng_stat_req++;
	ce->hwrng_stat_bytes += todo;
#endif

	dma_dst = dma_map_single(ce->dev, d, todo, DMA_FROM_DEVICE);
	if (dma_mapping_error(ce->dev, dma_dst)) {
		dev_err(ce->dev, "Cannot DMA MAP DST\n");
		err = -EFAULT;
		goto err_dst;
	}

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

	mutex_lock(&ce->rnglock);
	chan = &ce->chanlist[flow];

	cet = &chan->tl[0];
	memset(cet, 0, sizeof(struct ce_task));

	cet->t_id = cpu_to_le32(flow);
	common = ce->variant->trng | CE_COMM_INT;
	cet->t_common_ctl = cpu_to_le32(common);

	/* recent CE (H6) need length in bytes, in word otherwise */
	if (ce->variant->trng_t_dlen_in_bytes)
		cet->t_dlen = cpu_to_le32(todo);
	else
		cet->t_dlen = cpu_to_le32(todo / 4);

	cet->t_sym_ctl = 0;
	cet->t_asym_ctl = 0;

	cet->t_dst[0].addr = cpu_to_le32(dma_dst);
	cet->t_dst[0].len = cpu_to_le32(todo / 4);
	ce->chanlist[flow].timeout = todo;

	err = sun8i_ce_run_task(ce, 3, "TRNG");
	mutex_unlock(&ce->rnglock);

	pm_runtime_put(ce->dev);

err_pm:
	dma_unmap_single(ce->dev, dma_dst, todo, DMA_FROM_DEVICE);

	if (!err) {
		memcpy(data, d, max);
		err = max;
	}
err_dst:
	kfree_sensitive(d);
	return err;
}

int sun8i_ce_hwrng_register(struct sun8i_ce_dev *ce)
{
	int ret;

	if (ce->variant->trng == CE_ID_NOTSUPP) {
		dev_info(ce->dev, "TRNG not supported\n");
		return 0;
	}
	ce->trng.name = "sun8i Crypto Engine TRNG";
	ce->trng.read = sun8i_ce_trng_read;

	ret = hwrng_register(&ce->trng);
	if (ret)
		dev_err(ce->dev, "Fail to register the TRNG\n");
	return ret;
}

void sun8i_ce_hwrng_unregister(struct sun8i_ce_dev *ce)
{
	if (ce->variant->trng == CE_ID_NOTSUPP)
		return;
	hwrng_unregister(&ce->trng);
}
