/* n2-drv.c: Niagara-2 RNG driver.
 *
 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/preempt.h>
#include <linux/hw_random.h>

#include <linux/of.h>
#include <linux/of_device.h>

#include <asm/hypervisor.h>

#include "n2rng.h"

#define DRV_MODULE_NAME		"n2rng"
#define PFX DRV_MODULE_NAME	": "
#define DRV_MODULE_VERSION	"0.1"
#define DRV_MODULE_RELDATE	"May 15, 2008"

static char version[] __devinitdata =
	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";

MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_DESCRIPTION("Niagara2 RNG driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);

/* The Niagara2 RNG provides a 64-bit read-only random number
 * register, plus a control register.  Access to the RNG is
 * virtualized through the hypervisor so that both guests and control
 * nodes can access the device.
 *
 * The entropy source consists of raw entropy sources, each
 * constructed from a voltage controlled oscillator whose phase is
 * jittered by thermal noise sources.
 *
 * The oscillator in each of the three raw entropy sources run at
 * different frequencies.  Normally, all three generator outputs are
 * gathered, xored together, and fed into a CRC circuit, the output of
 * which is the 64-bit read-only register.
 *
 * Some time is necessary for all the necessary entropy to build up
 * such that a full 64-bits of entropy are available in the register.
 * In normal operating mode (RNG_CTL_LFSR is set), the chip implements
 * an interlock which blocks register reads until sufficient entropy
 * is available.
 *
 * A control register is provided for adjusting various aspects of RNG
 * operation, and to enable diagnostic modes.  Each of the three raw
 * entropy sources has an enable bit (RNG_CTL_ES{1,2,3}).  Also
 * provided are fields for controlling the minimum time in cycles
 * between read accesses to the register (RNG_CTL_WAIT, this controls
 * the interlock described in the previous paragraph).
 *
 * The standard setting is to have the mode bit (RNG_CTL_LFSR) set,
 * all three entropy sources enabled, and the interlock time set
 * appropriately.
 *
 * The CRC polynomial used by the chip is:
 *
 * P(X) = x64 + x61 + x57 + x56 + x52 + x51 + x50 + x48 + x47 + x46 +
 *        x43 + x42 + x41 + x39 + x38 + x37 + x35 + x32 + x28 + x25 +
 *        x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1
 *
 * The RNG_CTL_VCO value of each noise cell must be programmed
 * separately.  This is why 4 control register values must be provided
 * to the hypervisor.  During a write, the hypervisor writes them all,
 * one at a time, to the actual RNG_CTL register.  The first three
 * values are used to setup the desired RNG_CTL_VCO for each entropy
 * source, for example:
 *
 *	control 0: (1 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES1
 *	control 1: (2 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES2
 *	control 2: (3 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES3
 *
 * And then the fourth value sets the final chip state and enables
 * desired.
 */

static int n2rng_hv_err_trans(unsigned long hv_err)
{
	switch (hv_err) {
	case HV_EOK:
		return 0;
	case HV_EWOULDBLOCK:
		return -EAGAIN;
	case HV_ENOACCESS:
		return -EPERM;
	case HV_EIO:
		return -EIO;
	case HV_EBUSY:
		return -EBUSY;
	case HV_EBADALIGN:
	case HV_ENORADDR:
		return -EFAULT;
	default:
		return -EINVAL;
	}
}

static unsigned long n2rng_generic_read_control_v2(unsigned long ra,
						   unsigned long unit)
{
	unsigned long hv_err, state, ticks, watchdog_delta, watchdog_status;
	int block = 0, busy = 0;

	while (1) {
		hv_err = sun4v_rng_ctl_read_v2(ra, unit, &state,
					       &ticks,
					       &watchdog_delta,
					       &watchdog_status);
		if (hv_err == HV_EOK)
			break;

		if (hv_err == HV_EBUSY) {
			if (++busy >= N2RNG_BUSY_LIMIT)
				break;

			udelay(1);
		} else if (hv_err == HV_EWOULDBLOCK) {
			if (++block >= N2RNG_BLOCK_LIMIT)
				break;

			__delay(ticks);
		} else
			break;
	}

	return hv_err;
}

/* In multi-socket situations, the hypervisor might need to
 * queue up the RNG control register write if it's for a unit
 * that is on a cpu socket other than the one we are executing on.
 *
 * We poll here waiting for a successful read of that control
 * register to make sure the write has been actually performed.
 */
static unsigned long n2rng_control_settle_v2(struct n2rng *np, int unit)
{
	unsigned long ra = __pa(&np->scratch_control[0]);

	return n2rng_generic_read_control_v2(ra, unit);
}

static unsigned long n2rng_write_ctl_one(struct n2rng *np, int unit,
					 unsigned long state,
					 unsigned long control_ra,
					 unsigned long watchdog_timeout,
					 unsigned long *ticks)
{
	unsigned long hv_err;

	if (np->hvapi_major == 1) {
		hv_err = sun4v_rng_ctl_write_v1(control_ra, state,
						watchdog_timeout, ticks);
	} else {
		hv_err = sun4v_rng_ctl_write_v2(control_ra, state,
						watchdog_timeout, unit);
		if (hv_err == HV_EOK)
			hv_err = n2rng_control_settle_v2(np, unit);
		*ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
	}

	return hv_err;
}

static int n2rng_generic_read_data(unsigned long data_ra)
{
	unsigned long ticks, hv_err;
	int block = 0, hcheck = 0;

	while (1) {
		hv_err = sun4v_rng_data_read(data_ra, &ticks);
		if (hv_err == HV_EOK)
			return 0;

		if (hv_err == HV_EWOULDBLOCK) {
			if (++block >= N2RNG_BLOCK_LIMIT)
				return -EWOULDBLOCK;
			__delay(ticks);
		} else if (hv_err == HV_ENOACCESS) {
			return -EPERM;
		} else if (hv_err == HV_EIO) {
			if (++hcheck >= N2RNG_HCHECK_LIMIT)
				return -EIO;
			udelay(10000);
		} else
			return -ENODEV;
	}
}

static unsigned long n2rng_read_diag_data_one(struct n2rng *np,
					      unsigned long unit,
					      unsigned long data_ra,
					      unsigned long data_len,
					      unsigned long *ticks)
{
	unsigned long hv_err;

	if (np->hvapi_major == 1) {
		hv_err = sun4v_rng_data_read_diag_v1(data_ra, data_len, ticks);
	} else {
		hv_err = sun4v_rng_data_read_diag_v2(data_ra, data_len,
						     unit, ticks);
		if (!*ticks)
			*ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
	}
	return hv_err;
}

static int n2rng_generic_read_diag_data(struct n2rng *np,
					unsigned long unit,
					unsigned long data_ra,
					unsigned long data_len)
{
	unsigned long ticks, hv_err;
	int block = 0;

	while (1) {
		hv_err = n2rng_read_diag_data_one(np, unit,
						  data_ra, data_len,
						  &ticks);
		if (hv_err == HV_EOK)
			return 0;

		if (hv_err == HV_EWOULDBLOCK) {
			if (++block >= N2RNG_BLOCK_LIMIT)
				return -EWOULDBLOCK;
			__delay(ticks);
		} else if (hv_err == HV_ENOACCESS) {
			return -EPERM;
		} else if (hv_err == HV_EIO) {
			return -EIO;
		} else
			return -ENODEV;
	}
}


static int n2rng_generic_write_control(struct n2rng *np,
				       unsigned long control_ra,
				       unsigned long unit,
				       unsigned long state)
{
	unsigned long hv_err, ticks;
	int block = 0, busy = 0;

	while (1) {
		hv_err = n2rng_write_ctl_one(np, unit, state, control_ra,
					     np->wd_timeo, &ticks);
		if (hv_err == HV_EOK)
			return 0;

		if (hv_err == HV_EWOULDBLOCK) {
			if (++block >= N2RNG_BLOCK_LIMIT)
				return -EWOULDBLOCK;
			__delay(ticks);
		} else if (hv_err == HV_EBUSY) {
			if (++busy >= N2RNG_BUSY_LIMIT)
				return -EBUSY;
			udelay(1);
		} else
			return -ENODEV;
	}
}

/* Just try to see if we can successfully access the control register
 * of the RNG on the domain on which we are currently executing.
 */
static int n2rng_try_read_ctl(struct n2rng *np)
{
	unsigned long hv_err;
	unsigned long x;

	if (np->hvapi_major == 1) {
		hv_err = sun4v_rng_get_diag_ctl();
	} else {
		/* We purposefully give invalid arguments, HV_NOACCESS
		 * is higher priority than the errors we'd get from
		 * these other cases, and that's the error we are
		 * truly interested in.
		 */
		hv_err = sun4v_rng_ctl_read_v2(0UL, ~0UL, &x, &x, &x, &x);
		switch (hv_err) {
		case HV_EWOULDBLOCK:
		case HV_ENOACCESS:
			break;
		default:
			hv_err = HV_EOK;
			break;
		}
	}

	return n2rng_hv_err_trans(hv_err);
}

#define CONTROL_DEFAULT_BASE		\
	((2 << RNG_CTL_ASEL_SHIFT) |	\
	 (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) |	\
	 RNG_CTL_LFSR)

#define CONTROL_DEFAULT_0		\
	(CONTROL_DEFAULT_BASE |		\
	 (1 << RNG_CTL_VCO_SHIFT) |	\
	 RNG_CTL_ES1)
#define CONTROL_DEFAULT_1		\
	(CONTROL_DEFAULT_BASE |		\
	 (2 << RNG_CTL_VCO_SHIFT) |	\
	 RNG_CTL_ES2)
#define CONTROL_DEFAULT_2		\
	(CONTROL_DEFAULT_BASE |		\
	 (3 << RNG_CTL_VCO_SHIFT) |	\
	 RNG_CTL_ES3)
#define CONTROL_DEFAULT_3		\
	(CONTROL_DEFAULT_BASE |		\
	 RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3)

static void n2rng_control_swstate_init(struct n2rng *np)
{
	int i;

	np->flags |= N2RNG_FLAG_CONTROL;

	np->health_check_sec = N2RNG_HEALTH_CHECK_SEC_DEFAULT;
	np->accum_cycles = N2RNG_ACCUM_CYCLES_DEFAULT;
	np->wd_timeo = N2RNG_WD_TIMEO_DEFAULT;

	for (i = 0; i < np->num_units; i++) {
		struct n2rng_unit *up = &np->units[i];

		up->control[0] = CONTROL_DEFAULT_0;
		up->control[1] = CONTROL_DEFAULT_1;
		up->control[2] = CONTROL_DEFAULT_2;
		up->control[3] = CONTROL_DEFAULT_3;
	}

	np->hv_state = HV_RNG_STATE_UNCONFIGURED;
}

static int n2rng_grab_diag_control(struct n2rng *np)
{
	int i, busy_count, err = -ENODEV;

	busy_count = 0;
	for (i = 0; i < 100; i++) {
		err = n2rng_try_read_ctl(np);
		if (err != -EAGAIN)
			break;

		if (++busy_count > 100) {
			dev_err(&np->op->dev,
				"Grab diag control timeout.\n");
			return -ENODEV;
		}

		udelay(1);
	}

	return err;
}

static int n2rng_init_control(struct n2rng *np)
{
	int err = n2rng_grab_diag_control(np);

	/* Not in the control domain, that's OK we are only a consumer
	 * of the RNG data, we don't setup and program it.
	 */
	if (err == -EPERM)
		return 0;
	if (err)
		return err;

	n2rng_control_swstate_init(np);

	return 0;
}

static int n2rng_data_read(struct hwrng *rng, u32 *data)
{
	struct n2rng *np = rng->priv;
	unsigned long ra = __pa(&np->test_data);
	int len;

	if (!(np->flags & N2RNG_FLAG_READY)) {
		len = 0;
	} else if (np->flags & N2RNG_FLAG_BUFFER_VALID) {
		np->flags &= ~N2RNG_FLAG_BUFFER_VALID;
		*data = np->buffer;
		len = 4;
	} else {
		int err = n2rng_generic_read_data(ra);
		if (!err) {
			np->buffer = np->test_data >> 32;
			*data = np->test_data & 0xffffffff;
			len = 4;
		} else {
			dev_err(&np->op->dev, "RNG error, restesting\n");
			np->flags &= ~N2RNG_FLAG_READY;
			if (!(np->flags & N2RNG_FLAG_SHUTDOWN))
				schedule_delayed_work(&np->work, 0);
			len = 0;
		}
	}

	return len;
}

/* On a guest node, just make sure we can read random data properly.
 * If a control node reboots or reloads it's n2rng driver, this won't
 * work during that time.  So we have to keep probing until the device
 * becomes usable.
 */
static int n2rng_guest_check(struct n2rng *np)
{
	unsigned long ra = __pa(&np->test_data);

	return n2rng_generic_read_data(ra);
}

static int n2rng_entropy_diag_read(struct n2rng *np, unsigned long unit,
				   u64 *pre_control, u64 pre_state,
				   u64 *buffer, unsigned long buf_len,
				   u64 *post_control, u64 post_state)
{
	unsigned long post_ctl_ra = __pa(post_control);
	unsigned long pre_ctl_ra = __pa(pre_control);
	unsigned long buffer_ra = __pa(buffer);
	int err;

	err = n2rng_generic_write_control(np, pre_ctl_ra, unit, pre_state);
	if (err)
		return err;

	err = n2rng_generic_read_diag_data(np, unit,
					   buffer_ra, buf_len);

	(void) n2rng_generic_write_control(np, post_ctl_ra, unit,
					   post_state);

	return err;
}

static u64 advance_polynomial(u64 poly, u64 val, int count)
{
	int i;

	for (i = 0; i < count; i++) {
		int highbit_set = ((s64)val < 0);

		val <<= 1;
		if (highbit_set)
			val ^= poly;
	}

	return val;
}

static int n2rng_test_buffer_find(struct n2rng *np, u64 val)
{
	int i, count = 0;

	/* Purposefully skip over the first word.  */
	for (i = 1; i < SELFTEST_BUFFER_WORDS; i++) {
		if (np->test_buffer[i] == val)
			count++;
	}
	return count;
}

static void n2rng_dump_test_buffer(struct n2rng *np)
{
	int i;

	for (i = 0; i < SELFTEST_BUFFER_WORDS; i++)
		dev_err(&np->op->dev, "Test buffer slot %d [0x%016llx]\n",
			i, np->test_buffer[i]);
}

static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)
{
	u64 val = SELFTEST_VAL;
	int err, matches, limit;

	matches = 0;
	for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) {
		matches += n2rng_test_buffer_find(np, val);
		if (matches >= SELFTEST_MATCH_GOAL)
			break;
		val = advance_polynomial(SELFTEST_POLY, val, 1);
	}

	err = 0;
	if (limit >= SELFTEST_LOOPS_MAX) {
		err = -ENODEV;
		dev_err(&np->op->dev, "Selftest failed on unit %lu\n", unit);
		n2rng_dump_test_buffer(np);
	} else
		dev_info(&np->op->dev, "Selftest passed on unit %lu\n", unit);

	return err;
}

static int n2rng_control_selftest(struct n2rng *np, unsigned long unit)
{
	int err;

	np->test_control[0] = (0x2 << RNG_CTL_ASEL_SHIFT);
	np->test_control[1] = (0x2 << RNG_CTL_ASEL_SHIFT);
	np->test_control[2] = (0x2 << RNG_CTL_ASEL_SHIFT);
	np->test_control[3] = ((0x2 << RNG_CTL_ASEL_SHIFT) |
			       RNG_CTL_LFSR |
			       ((SELFTEST_TICKS - 2) << RNG_CTL_WAIT_SHIFT));


	err = n2rng_entropy_diag_read(np, unit, np->test_control,
				      HV_RNG_STATE_HEALTHCHECK,
				      np->test_buffer,
				      sizeof(np->test_buffer),
				      &np->units[unit].control[0],
				      np->hv_state);
	if (err)
		return err;

	return n2rng_check_selftest_buffer(np, unit);
}

static int n2rng_control_check(struct n2rng *np)
{
	int i;

	for (i = 0; i < np->num_units; i++) {
		int err = n2rng_control_selftest(np, i);
		if (err)
			return err;
	}
	return 0;
}

/* The sanity checks passed, install the final configuration into the
 * chip, it's ready to use.
 */
static int n2rng_control_configure_units(struct n2rng *np)
{
	int unit, err;

	err = 0;
	for (unit = 0; unit < np->num_units; unit++) {
		struct n2rng_unit *up = &np->units[unit];
		unsigned long ctl_ra = __pa(&up->control[0]);
		int esrc;
		u64 base;

		base = ((np->accum_cycles << RNG_CTL_WAIT_SHIFT) |
			(2 << RNG_CTL_ASEL_SHIFT) |
			RNG_CTL_LFSR);

		/* XXX This isn't the best.  We should fetch a bunch
		 * XXX of words using each entropy source combined XXX
		 * with each VCO setting, and see which combinations
		 * XXX give the best random data.
		 */
		for (esrc = 0; esrc < 3; esrc++)
			up->control[esrc] = base |
				(esrc << RNG_CTL_VCO_SHIFT) |
				(RNG_CTL_ES1 << esrc);

		up->control[3] = base |
			(RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3);

		err = n2rng_generic_write_control(np, ctl_ra, unit,
						  HV_RNG_STATE_CONFIGURED);
		if (err)
			break;
	}

	return err;
}

static void n2rng_work(struct work_struct *work)
{
	struct n2rng *np = container_of(work, struct n2rng, work.work);
	int err = 0;

	if (!(np->flags & N2RNG_FLAG_CONTROL)) {
		err = n2rng_guest_check(np);
	} else {
		preempt_disable();
		err = n2rng_control_check(np);
		preempt_enable();

		if (!err)
			err = n2rng_control_configure_units(np);
	}

	if (!err) {
		np->flags |= N2RNG_FLAG_READY;
		dev_info(&np->op->dev, "RNG ready\n");
	}

	if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
		schedule_delayed_work(&np->work, HZ * 2);
}

static void __devinit n2rng_driver_version(void)
{
	static int n2rng_version_printed;

	if (n2rng_version_printed++ == 0)
		pr_info("%s", version);
}

static int __devinit n2rng_probe(struct platform_device *op,
				 const struct of_device_id *match)
{
	int victoria_falls = (match->data != NULL);
	int err = -ENOMEM;
	struct n2rng *np;

	n2rng_driver_version();

	np = kzalloc(sizeof(*np), GFP_KERNEL);
	if (!np)
		goto out;
	np->op = op;

	INIT_DELAYED_WORK(&np->work, n2rng_work);

	if (victoria_falls)
		np->flags |= N2RNG_FLAG_VF;

	err = -ENODEV;
	np->hvapi_major = 2;
	if (sun4v_hvapi_register(HV_GRP_RNG,
				 np->hvapi_major,
				 &np->hvapi_minor)) {
		np->hvapi_major = 1;
		if (sun4v_hvapi_register(HV_GRP_RNG,
					 np->hvapi_major,
					 &np->hvapi_minor)) {
			dev_err(&op->dev, "Cannot register suitable "
				"HVAPI version.\n");
			goto out_free;
		}
	}

	if (np->flags & N2RNG_FLAG_VF) {
		if (np->hvapi_major < 2) {
			dev_err(&op->dev, "VF RNG requires HVAPI major "
				"version 2 or later, got %lu\n",
				np->hvapi_major);
			goto out_hvapi_unregister;
		}
		np->num_units = of_getintprop_default(op->dev.of_node,
						      "rng-#units", 0);
		if (!np->num_units) {
			dev_err(&op->dev, "VF RNG lacks rng-#units property\n");
			goto out_hvapi_unregister;
		}
	} else
		np->num_units = 1;

	dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",
		 np->hvapi_major, np->hvapi_minor);

	np->units = kzalloc(sizeof(struct n2rng_unit) * np->num_units,
			    GFP_KERNEL);
	err = -ENOMEM;
	if (!np->units)
		goto out_hvapi_unregister;

	err = n2rng_init_control(np);
	if (err)
		goto out_free_units;

	dev_info(&op->dev, "Found %s RNG, units: %d\n",
		 ((np->flags & N2RNG_FLAG_VF) ?
		  "Victoria Falls" : "Niagara2"),
		 np->num_units);

	np->hwrng.name = "n2rng";
	np->hwrng.data_read = n2rng_data_read;
	np->hwrng.priv = (unsigned long) np;

	err = hwrng_register(&np->hwrng);
	if (err)
		goto out_free_units;

	dev_set_drvdata(&op->dev, np);

	schedule_delayed_work(&np->work, 0);

	return 0;

out_free_units:
	kfree(np->units);
	np->units = NULL;

out_hvapi_unregister:
	sun4v_hvapi_unregister(HV_GRP_RNG);

out_free:
	kfree(np);
out:
	return err;
}

static int __devexit n2rng_remove(struct platform_device *op)
{
	struct n2rng *np = dev_get_drvdata(&op->dev);

	np->flags |= N2RNG_FLAG_SHUTDOWN;

	cancel_delayed_work_sync(&np->work);

	hwrng_unregister(&np->hwrng);

	sun4v_hvapi_unregister(HV_GRP_RNG);

	kfree(np->units);
	np->units = NULL;

	kfree(np);

	dev_set_drvdata(&op->dev, NULL);

	return 0;
}

static const struct of_device_id n2rng_match[] = {
	{
		.name		= "random-number-generator",
		.compatible	= "SUNW,n2-rng",
	},
	{
		.name		= "random-number-generator",
		.compatible	= "SUNW,vf-rng",
		.data		= (void *) 1,
	},
	{},
};
MODULE_DEVICE_TABLE(of, n2rng_match);

static struct of_platform_driver n2rng_driver = {
	.driver = {
		.name = "n2rng",
		.owner = THIS_MODULE,
		.of_match_table = n2rng_match,
	},
	.probe		= n2rng_probe,
	.remove		= __devexit_p(n2rng_remove),
};

static int __init n2rng_init(void)
{
	return of_register_platform_driver(&n2rng_driver);
}

static void __exit n2rng_exit(void)
{
	of_unregister_platform_driver(&n2rng_driver);
}

module_init(n2rng_init);
module_exit(n2rng_exit);
