Commit ce087150211412afd901a3fa16b1aab5b54d1bcb

Authored by David S. Miller
1 parent 432e8765f0

sparc64: Add Niagara2 RNG driver.

With feedback and suggestions from Sam Ravnborg.

Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 983 additions and 0 deletions Side-by-side Diff

drivers/char/hw_random/Kconfig
... ... @@ -59,6 +59,19 @@
59 59  
60 60 If unsure, say Y.
61 61  
  62 +config HW_RANDOM_N2RNG
  63 + tristate "Niagara2 Random Number Generator support"
  64 + depends on HW_RANDOM && SPARC64
  65 + default HW_RANDOM
  66 + ---help---
  67 + This driver provides kernel-side support for the Random Number
  68 + Generator hardware found on Niagara2 cpus.
  69 +
  70 + To compile this driver as a module, choose M here: the
  71 + module will be called n2-rng.
  72 +
  73 + If unsure, say Y.
  74 +
62 75 config HW_RANDOM_VIA
63 76 tristate "VIA HW Random Number Generator support"
64 77 depends on HW_RANDOM && X86_32
drivers/char/hw_random/Makefile
... ... @@ -7,6 +7,8 @@
7 7 obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
8 8 obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
9 9 obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
  10 +obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
  11 +n2-rng-y := n2-drv.o n2-asm.o
10 12 obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
11 13 obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
12 14 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
drivers/char/hw_random/n2-asm.S
  1 +/* n2-asm.S: Niagara2 RNG hypervisor call assembler.
  2 + *
  3 + * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
  4 + */
  5 +#include <linux/linkage.h>
  6 +#include <asm/hypervisor.h>
  7 +#include "n2rng.h"
  8 +
  9 + .text
  10 +
  11 +ENTRY(sun4v_rng_get_diag_ctl)
  12 + mov HV_FAST_RNG_GET_DIAG_CTL, %o5
  13 + ta HV_FAST_TRAP
  14 + retl
  15 + nop
  16 +ENDPROC(sun4v_rng_get_diag_ctl)
  17 +
  18 +ENTRY(sun4v_rng_ctl_read_v1)
  19 + mov %o1, %o3
  20 + mov %o2, %o4
  21 + mov HV_FAST_RNG_CTL_READ, %o5
  22 + ta HV_FAST_TRAP
  23 + stx %o1, [%o3]
  24 + retl
  25 + stx %o2, [%o4]
  26 +ENDPROC(sun4v_rng_ctl_read_v1)
  27 +
  28 +ENTRY(sun4v_rng_ctl_read_v2)
  29 + save %sp, -192, %sp
  30 + mov %i0, %o0
  31 + mov %i1, %o1
  32 + mov HV_FAST_RNG_CTL_READ, %o5
  33 + ta HV_FAST_TRAP
  34 + stx %o1, [%i2]
  35 + stx %o2, [%i3]
  36 + stx %o3, [%i4]
  37 + stx %o4, [%i5]
  38 + ret
  39 + restore %g0, %o0, %o0
  40 +ENDPROC(sun4v_rng_ctl_read_v2)
  41 +
  42 +ENTRY(sun4v_rng_ctl_write_v1)
  43 + mov %o3, %o4
  44 + mov HV_FAST_RNG_CTL_WRITE, %o5
  45 + ta HV_FAST_TRAP
  46 + retl
  47 + stx %o1, [%o4]
  48 +ENDPROC(sun4v_rng_ctl_write_v1)
  49 +
  50 +ENTRY(sun4v_rng_ctl_write_v2)
  51 + mov HV_FAST_RNG_CTL_WRITE, %o5
  52 + ta HV_FAST_TRAP
  53 + retl
  54 + nop
  55 +ENDPROC(sun4v_rng_ctl_write_v2)
  56 +
  57 +ENTRY(sun4v_rng_data_read_diag_v1)
  58 + mov %o2, %o4
  59 + mov HV_FAST_RNG_DATA_READ_DIAG, %o5
  60 + ta HV_FAST_TRAP
  61 + retl
  62 + stx %o1, [%o4]
  63 +ENDPROC(sun4v_rng_data_read_diag_v1)
  64 +
  65 +ENTRY(sun4v_rng_data_read_diag_v2)
  66 + mov %o3, %o4
  67 + mov HV_FAST_RNG_DATA_READ_DIAG, %o5
  68 + ta HV_FAST_TRAP
  69 + retl
  70 + stx %o1, [%o4]
  71 +ENDPROC(sun4v_rng_data_read_diag_v2)
  72 +
  73 +ENTRY(sun4v_rng_data_read)
  74 + mov %o1, %o4
  75 + mov HV_FAST_RNG_DATA_READ, %o5
  76 + ta HV_FAST_TRAP
  77 + retl
  78 + stx %o1, [%o4]
  79 +ENDPROC(sun4v_rng_data_read)
drivers/char/hw_random/n2-drv.c
  1 +/* n2-drv.c: Niagara-2 RNG driver.
  2 + *
  3 + * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
  4 + */
  5 +
  6 +#include <linux/kernel.h>
  7 +#include <linux/module.h>
  8 +#include <linux/types.h>
  9 +#include <linux/delay.h>
  10 +#include <linux/init.h>
  11 +#include <linux/slab.h>
  12 +#include <linux/workqueue.h>
  13 +#include <linux/preempt.h>
  14 +#include <linux/hw_random.h>
  15 +
  16 +#include <linux/of.h>
  17 +#include <linux/of_device.h>
  18 +
  19 +#include <asm/hypervisor.h>
  20 +
  21 +#include "n2rng.h"
  22 +
  23 +#define DRV_MODULE_NAME "n2rng"
  24 +#define PFX DRV_MODULE_NAME ": "
  25 +#define DRV_MODULE_VERSION "0.1"
  26 +#define DRV_MODULE_RELDATE "May 15, 2008"
  27 +
  28 +static char version[] __devinitdata =
  29 + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
  30 +
  31 +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
  32 +MODULE_DESCRIPTION("Niagara2 RNG driver");
  33 +MODULE_LICENSE("GPL");
  34 +MODULE_VERSION(DRV_MODULE_VERSION);
  35 +
  36 +/* The Niagara2 RNG provides a 64-bit read-only random number
  37 + * register, plus a control register. Access to the RNG is
  38 + * virtualized through the hypervisor so that both guests and control
  39 + * nodes can access the device.
  40 + *
  41 + * The entropy source consists of raw entropy sources, each
  42 + * constructed from a voltage controlled oscillator whose phase is
  43 + * jittered by thermal noise sources.
  44 + *
  45 + * The oscillator in each of the three raw entropy sources run at
  46 + * different frequencies. Normally, all three generator outputs are
  47 + * gathered, xored together, and fed into a CRC circuit, the output of
  48 + * which is the 64-bit read-only register.
  49 + *
  50 + * Some time is necessary for all the necessary entropy to build up
  51 + * such that a full 64-bits of entropy are available in the register.
  52 + * In normal operating mode (RNG_CTL_LFSR is set), the chip implements
  53 + * an interlock which blocks register reads until sufficient entropy
  54 + * is available.
  55 + *
  56 + * A control register is provided for adjusting various aspects of RNG
  57 + * operation, and to enable diagnostic modes. Each of the three raw
  58 + * entropy sources has an enable bit (RNG_CTL_ES{1,2,3}). Also
  59 + * provided are fields for controlling the minimum time in cycles
  60 + * between read accesses to the register (RNG_CTL_WAIT, this controls
  61 + * the interlock described in the previous paragraph).
  62 + *
  63 + * The standard setting is to have the mode bit (RNG_CTL_LFSR) set,
  64 + * all three entropy sources enabled, and the interlock time set
  65 + * appropriately.
  66 + *
  67 + * The CRC polynomial used by the chip is:
  68 + *
  69 + * P(X) = x64 + x61 + x57 + x56 + x52 + x51 + x50 + x48 + x47 + x46 +
  70 + * x43 + x42 + x41 + x39 + x38 + x37 + x35 + x32 + x28 + x25 +
  71 + * x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1
  72 + *
  73 + * The RNG_CTL_VCO value of each noise cell must be programmed
  74 + * seperately. This is why 4 control register values must be provided
  75 + * to the hypervisor. During a write, the hypervisor writes them all,
  76 + * one at a time, to the actual RNG_CTL register. The first three
  77 + * values are used to setup the desired RNG_CTL_VCO for each entropy
  78 + * source, for example:
  79 + *
  80 + * control 0: (1 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES1
  81 + * control 1: (2 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES2
  82 + * control 2: (3 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES3
  83 + *
  84 + * And then the fourth value sets the final chip state and enables
  85 + * desired.
  86 + */
  87 +
  88 +static int n2rng_hv_err_trans(unsigned long hv_err)
  89 +{
  90 + switch (hv_err) {
  91 + case HV_EOK:
  92 + return 0;
  93 + case HV_EWOULDBLOCK:
  94 + return -EAGAIN;
  95 + case HV_ENOACCESS:
  96 + return -EPERM;
  97 + case HV_EIO:
  98 + return -EIO;
  99 + case HV_EBUSY:
  100 + return -EBUSY;
  101 + case HV_EBADALIGN:
  102 + case HV_ENORADDR:
  103 + return -EFAULT;
  104 + default:
  105 + return -EINVAL;
  106 + }
  107 +}
  108 +
  109 +static unsigned long n2rng_generic_read_control_v2(unsigned long ra,
  110 + unsigned long unit)
  111 +{
  112 + unsigned long hv_err, state, ticks, watchdog_delta, watchdog_status;
  113 + int block = 0, busy = 0;
  114 +
  115 + while (1) {
  116 + hv_err = sun4v_rng_ctl_read_v2(ra, unit, &state,
  117 + &ticks,
  118 + &watchdog_delta,
  119 + &watchdog_status);
  120 + if (hv_err == HV_EOK)
  121 + break;
  122 +
  123 + if (hv_err == HV_EBUSY) {
  124 + if (++busy >= N2RNG_BUSY_LIMIT)
  125 + break;
  126 +
  127 + udelay(1);
  128 + } else if (hv_err == HV_EWOULDBLOCK) {
  129 + if (++block >= N2RNG_BLOCK_LIMIT)
  130 + break;
  131 +
  132 + __delay(ticks);
  133 + } else
  134 + break;
  135 + }
  136 +
  137 + return hv_err;
  138 +}
  139 +
  140 +/* In multi-socket situations, the hypervisor might need to
  141 + * queue up the RNG control register write if it's for a unit
  142 + * that is on a cpu socket other than the one we are executing on.
  143 + *
  144 + * We poll here waiting for a successful read of that control
  145 + * register to make sure the write has been actually performed.
  146 + */
  147 +static unsigned long n2rng_control_settle_v2(struct n2rng *np, int unit)
  148 +{
  149 + unsigned long ra = __pa(&np->scratch_control[0]);
  150 +
  151 + return n2rng_generic_read_control_v2(ra, unit);
  152 +}
  153 +
  154 +static unsigned long n2rng_write_ctl_one(struct n2rng *np, int unit,
  155 + unsigned long state,
  156 + unsigned long control_ra,
  157 + unsigned long watchdog_timeout,
  158 + unsigned long *ticks)
  159 +{
  160 + unsigned long hv_err;
  161 +
  162 + if (np->hvapi_major == 1) {
  163 + hv_err = sun4v_rng_ctl_write_v1(control_ra, state,
  164 + watchdog_timeout, ticks);
  165 + } else {
  166 + hv_err = sun4v_rng_ctl_write_v2(control_ra, state,
  167 + watchdog_timeout, unit);
  168 + if (hv_err == HV_EOK)
  169 + hv_err = n2rng_control_settle_v2(np, unit);
  170 + *ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
  171 + }
  172 +
  173 + return hv_err;
  174 +}
  175 +
  176 +static int n2rng_generic_read_data(unsigned long data_ra)
  177 +{
  178 + unsigned long ticks, hv_err;
  179 + int block = 0, hcheck = 0;
  180 +
  181 + while (1) {
  182 + hv_err = sun4v_rng_data_read(data_ra, &ticks);
  183 + if (hv_err == HV_EOK)
  184 + return 0;
  185 +
  186 + if (hv_err == HV_EWOULDBLOCK) {
  187 + if (++block >= N2RNG_BLOCK_LIMIT)
  188 + return -EWOULDBLOCK;
  189 + __delay(ticks);
  190 + } else if (hv_err == HV_ENOACCESS) {
  191 + return -EPERM;
  192 + } else if (hv_err == HV_EIO) {
  193 + if (++hcheck >= N2RNG_HCHECK_LIMIT)
  194 + return -EIO;
  195 + udelay(10000);
  196 + } else
  197 + return -ENODEV;
  198 + }
  199 +}
  200 +
  201 +static unsigned long n2rng_read_diag_data_one(struct n2rng *np,
  202 + unsigned long unit,
  203 + unsigned long data_ra,
  204 + unsigned long data_len,
  205 + unsigned long *ticks)
  206 +{
  207 + unsigned long hv_err;
  208 +
  209 + if (np->hvapi_major == 1) {
  210 + hv_err = sun4v_rng_data_read_diag_v1(data_ra, data_len, ticks);
  211 + } else {
  212 + hv_err = sun4v_rng_data_read_diag_v2(data_ra, data_len,
  213 + unit, ticks);
  214 + if (!*ticks)
  215 + *ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
  216 + }
  217 + return hv_err;
  218 +}
  219 +
  220 +static int n2rng_generic_read_diag_data(struct n2rng *np,
  221 + unsigned long unit,
  222 + unsigned long data_ra,
  223 + unsigned long data_len)
  224 +{
  225 + unsigned long ticks, hv_err;
  226 + int block = 0;
  227 +
  228 + while (1) {
  229 + hv_err = n2rng_read_diag_data_one(np, unit,
  230 + data_ra, data_len,
  231 + &ticks);
  232 + if (hv_err == HV_EOK)
  233 + return 0;
  234 +
  235 + if (hv_err == HV_EWOULDBLOCK) {
  236 + if (++block >= N2RNG_BLOCK_LIMIT)
  237 + return -EWOULDBLOCK;
  238 + __delay(ticks);
  239 + } else if (hv_err == HV_ENOACCESS) {
  240 + return -EPERM;
  241 + } else if (hv_err == HV_EIO) {
  242 + return -EIO;
  243 + } else
  244 + return -ENODEV;
  245 + }
  246 +}
  247 +
  248 +
  249 +static int n2rng_generic_write_control(struct n2rng *np,
  250 + unsigned long control_ra,
  251 + unsigned long unit,
  252 + unsigned long state)
  253 +{
  254 + unsigned long hv_err, ticks;
  255 + int block = 0, busy = 0;
  256 +
  257 + while (1) {
  258 + hv_err = n2rng_write_ctl_one(np, unit, state, control_ra,
  259 + np->wd_timeo, &ticks);
  260 + if (hv_err == HV_EOK)
  261 + return 0;
  262 +
  263 + if (hv_err == HV_EWOULDBLOCK) {
  264 + if (++block >= N2RNG_BLOCK_LIMIT)
  265 + return -EWOULDBLOCK;
  266 + __delay(ticks);
  267 + } else if (hv_err == HV_EBUSY) {
  268 + if (++busy >= N2RNG_BUSY_LIMIT)
  269 + return -EBUSY;
  270 + udelay(1);
  271 + } else
  272 + return -ENODEV;
  273 + }
  274 +}
  275 +
  276 +/* Just try to see if we can successfully access the control register
  277 + * of the RNG on the domain on which we are currently executing.
  278 + */
  279 +static int n2rng_try_read_ctl(struct n2rng *np)
  280 +{
  281 + unsigned long hv_err;
  282 + unsigned long x;
  283 +
  284 + if (np->hvapi_major == 1) {
  285 + hv_err = sun4v_rng_get_diag_ctl();
  286 + } else {
  287 + /* We purposefully give invalid arguments, HV_NOACCESS
  288 + * is higher priority than the errors we'd get from
  289 + * these other cases, and that's the error we are
  290 + * truly interested in.
  291 + */
  292 + hv_err = sun4v_rng_ctl_read_v2(0UL, ~0UL, &x, &x, &x, &x);
  293 + switch (hv_err) {
  294 + case HV_EWOULDBLOCK:
  295 + case HV_ENOACCESS:
  296 + break;
  297 + default:
  298 + hv_err = HV_EOK;
  299 + break;
  300 + }
  301 + }
  302 +
  303 + return n2rng_hv_err_trans(hv_err);
  304 +}
  305 +
  306 +#define CONTROL_DEFAULT_BASE \
  307 + ((2 << RNG_CTL_ASEL_SHIFT) | \
  308 + (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) | \
  309 + RNG_CTL_LFSR)
  310 +
  311 +#define CONTROL_DEFAULT_0 \
  312 + (CONTROL_DEFAULT_BASE | \
  313 + (1 << RNG_CTL_VCO_SHIFT) | \
  314 + RNG_CTL_ES1)
  315 +#define CONTROL_DEFAULT_1 \
  316 + (CONTROL_DEFAULT_BASE | \
  317 + (2 << RNG_CTL_VCO_SHIFT) | \
  318 + RNG_CTL_ES2)
  319 +#define CONTROL_DEFAULT_2 \
  320 + (CONTROL_DEFAULT_BASE | \
  321 + (3 << RNG_CTL_VCO_SHIFT) | \
  322 + RNG_CTL_ES3)
  323 +#define CONTROL_DEFAULT_3 \
  324 + (CONTROL_DEFAULT_BASE | \
  325 + RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3)
  326 +
  327 +static void n2rng_control_swstate_init(struct n2rng *np)
  328 +{
  329 + int i;
  330 +
  331 + np->flags |= N2RNG_FLAG_CONTROL;
  332 +
  333 + np->health_check_sec = N2RNG_HEALTH_CHECK_SEC_DEFAULT;
  334 + np->accum_cycles = N2RNG_ACCUM_CYCLES_DEFAULT;
  335 + np->wd_timeo = N2RNG_WD_TIMEO_DEFAULT;
  336 +
  337 + for (i = 0; i < np->num_units; i++) {
  338 + struct n2rng_unit *up = &np->units[i];
  339 +
  340 + up->control[0] = CONTROL_DEFAULT_0;
  341 + up->control[1] = CONTROL_DEFAULT_1;
  342 + up->control[2] = CONTROL_DEFAULT_2;
  343 + up->control[3] = CONTROL_DEFAULT_3;
  344 + }
  345 +
  346 + np->hv_state = HV_RNG_STATE_UNCONFIGURED;
  347 +}
  348 +
  349 +static int n2rng_grab_diag_control(struct n2rng *np)
  350 +{
  351 + int i, busy_count, err = -ENODEV;
  352 +
  353 + busy_count = 0;
  354 + for (i = 0; i < 100; i++) {
  355 + err = n2rng_try_read_ctl(np);
  356 + if (err != -EAGAIN)
  357 + break;
  358 +
  359 + if (++busy_count > 100) {
  360 + dev_err(&np->op->dev,
  361 + "Grab diag control timeout.\n");
  362 + return -ENODEV;
  363 + }
  364 +
  365 + udelay(1);
  366 + }
  367 +
  368 + return err;
  369 +}
  370 +
  371 +static int n2rng_init_control(struct n2rng *np)
  372 +{
  373 + int err = n2rng_grab_diag_control(np);
  374 +
  375 + /* Not in the control domain, that's OK we are only a consumer
  376 + * of the RNG data, we don't setup and program it.
  377 + */
  378 + if (err == -EPERM)
  379 + return 0;
  380 + if (err)
  381 + return err;
  382 +
  383 + n2rng_control_swstate_init(np);
  384 +
  385 + return 0;
  386 +}
  387 +
  388 +static int n2rng_data_read(struct hwrng *rng, u32 *data)
  389 +{
  390 + struct n2rng *np = (struct n2rng *) rng->priv;
  391 + unsigned long ra = __pa(&np->test_data);
  392 + int len;
  393 +
  394 + if (!(np->flags & N2RNG_FLAG_READY)) {
  395 + len = 0;
  396 + } else if (np->flags & N2RNG_FLAG_BUFFER_VALID) {
  397 + np->flags &= ~N2RNG_FLAG_BUFFER_VALID;
  398 + *data = np->buffer;
  399 + len = 4;
  400 + } else {
  401 + int err = n2rng_generic_read_data(ra);
  402 + if (!err) {
  403 + np->buffer = np->test_data >> 32;
  404 + *data = np->test_data & 0xffffffff;
  405 + len = 4;
  406 + } else {
  407 + dev_err(&np->op->dev, "RNG error, restesting\n");
  408 + np->flags &= ~N2RNG_FLAG_READY;
  409 + if (!(np->flags & N2RNG_FLAG_SHUTDOWN))
  410 + schedule_delayed_work(&np->work, 0);
  411 + len = 0;
  412 + }
  413 + }
  414 +
  415 + return len;
  416 +}
  417 +
  418 +/* On a guest node, just make sure we can read random data properly.
  419 + * If a control node reboots or reloads it's n2rng driver, this won't
  420 + * work during that time. So we have to keep probing until the device
  421 + * becomes usable.
  422 + */
  423 +static int n2rng_guest_check(struct n2rng *np)
  424 +{
  425 + unsigned long ra = __pa(&np->test_data);
  426 +
  427 + return n2rng_generic_read_data(ra);
  428 +}
  429 +
  430 +static int n2rng_entropy_diag_read(struct n2rng *np, unsigned long unit,
  431 + u64 *pre_control, u64 pre_state,
  432 + u64 *buffer, unsigned long buf_len,
  433 + u64 *post_control, u64 post_state)
  434 +{
  435 + unsigned long post_ctl_ra = __pa(post_control);
  436 + unsigned long pre_ctl_ra = __pa(pre_control);
  437 + unsigned long buffer_ra = __pa(buffer);
  438 + int err;
  439 +
  440 + err = n2rng_generic_write_control(np, pre_ctl_ra, unit, pre_state);
  441 + if (err)
  442 + return err;
  443 +
  444 + err = n2rng_generic_read_diag_data(np, unit,
  445 + buffer_ra, buf_len);
  446 +
  447 + (void) n2rng_generic_write_control(np, post_ctl_ra, unit,
  448 + post_state);
  449 +
  450 + return err;
  451 +}
  452 +
  453 +static u64 advance_polynomial(u64 poly, u64 val, int count)
  454 +{
  455 + int i;
  456 +
  457 + for (i = 0; i < count; i++) {
  458 + int highbit_set = ((s64)val < 0);
  459 +
  460 + val <<= 1;
  461 + if (highbit_set)
  462 + val ^= poly;
  463 + }
  464 +
  465 + return val;
  466 +}
  467 +
  468 +static int n2rng_test_buffer_find(struct n2rng *np, u64 val)
  469 +{
  470 + int i, count = 0;
  471 +
  472 + /* Purposefully skip over the first word. */
  473 + for (i = 1; i < SELFTEST_BUFFER_WORDS; i++) {
  474 + if (np->test_buffer[i] == val)
  475 + count++;
  476 + }
  477 + return count;
  478 +}
  479 +
  480 +static void n2rng_dump_test_buffer(struct n2rng *np)
  481 +{
  482 + int i;
  483 +
  484 + for (i = 0; i < SELFTEST_BUFFER_WORDS; i++)
  485 + dev_err(&np->op->dev, "Test buffer slot %d [0x%016lx]\n",
  486 + i, np->test_buffer[i]);
  487 +}
  488 +
  489 +static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)
  490 +{
  491 + u64 val = SELFTEST_VAL;
  492 + int err, matches, limit;
  493 +
  494 + matches = 0;
  495 + for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) {
  496 + matches += n2rng_test_buffer_find(np, val);
  497 + if (matches >= SELFTEST_MATCH_GOAL)
  498 + break;
  499 + val = advance_polynomial(SELFTEST_POLY, val, 1);
  500 + }
  501 +
  502 + err = 0;
  503 + if (limit >= SELFTEST_LOOPS_MAX) {
  504 + err = -ENODEV;
  505 + dev_err(&np->op->dev, "Selftest failed on unit %lu\n", unit);
  506 + n2rng_dump_test_buffer(np);
  507 + } else
  508 + dev_info(&np->op->dev, "Selftest passed on unit %lu\n", unit);
  509 +
  510 + return err;
  511 +}
  512 +
  513 +static int n2rng_control_selftest(struct n2rng *np, unsigned long unit)
  514 +{
  515 + int err;
  516 +
  517 + np->test_control[0] = (0x2 << RNG_CTL_ASEL_SHIFT);
  518 + np->test_control[1] = (0x2 << RNG_CTL_ASEL_SHIFT);
  519 + np->test_control[2] = (0x2 << RNG_CTL_ASEL_SHIFT);
  520 + np->test_control[3] = ((0x2 << RNG_CTL_ASEL_SHIFT) |
  521 + RNG_CTL_LFSR |
  522 + ((SELFTEST_TICKS - 2) << RNG_CTL_WAIT_SHIFT));
  523 +
  524 +
  525 + err = n2rng_entropy_diag_read(np, unit, np->test_control,
  526 + HV_RNG_STATE_HEALTHCHECK,
  527 + np->test_buffer,
  528 + sizeof(np->test_buffer),
  529 + &np->units[unit].control[0],
  530 + np->hv_state);
  531 + if (err)
  532 + return err;
  533 +
  534 + return n2rng_check_selftest_buffer(np, unit);
  535 +}
  536 +
  537 +static int n2rng_control_check(struct n2rng *np)
  538 +{
  539 + int i;
  540 +
  541 + for (i = 0; i < np->num_units; i++) {
  542 + int err = n2rng_control_selftest(np, i);
  543 + if (err)
  544 + return err;
  545 + }
  546 + return 0;
  547 +}
  548 +
  549 +/* The sanity checks passed, install the final configuration into the
  550 + * chip, it's ready to use.
  551 + */
  552 +static int n2rng_control_configure_units(struct n2rng *np)
  553 +{
  554 + int unit, err;
  555 +
  556 + err = 0;
  557 + for (unit = 0; unit < np->num_units; unit++) {
  558 + struct n2rng_unit *up = &np->units[unit];
  559 + unsigned long ctl_ra = __pa(&up->control[0]);
  560 + int esrc;
  561 + u64 base;
  562 +
  563 + base = ((np->accum_cycles << RNG_CTL_WAIT_SHIFT) |
  564 + (2 << RNG_CTL_ASEL_SHIFT) |
  565 + RNG_CTL_LFSR);
  566 +
  567 + /* XXX This isn't the best. We should fetch a bunch
  568 + * XXX of words using each entropy source combined XXX
  569 + * with each VCO setting, and see which combinations
  570 + * XXX give the best random data.
  571 + */
  572 + for (esrc = 0; esrc < 3; esrc++)
  573 + up->control[esrc] = base |
  574 + (esrc << RNG_CTL_VCO_SHIFT) |
  575 + (RNG_CTL_ES1 << esrc);
  576 +
  577 + up->control[3] = base |
  578 + (RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3);
  579 +
  580 + err = n2rng_generic_write_control(np, ctl_ra, unit,
  581 + HV_RNG_STATE_CONFIGURED);
  582 + if (err)
  583 + break;
  584 + }
  585 +
  586 + return err;
  587 +}
  588 +
  589 +static void n2rng_work(struct work_struct *work)
  590 +{
  591 + struct n2rng *np = container_of(work, struct n2rng, work.work);
  592 + int err = 0;
  593 +
  594 + if (!(np->flags & N2RNG_FLAG_CONTROL)) {
  595 + err = n2rng_guest_check(np);
  596 + } else {
  597 + preempt_disable();
  598 + err = n2rng_control_check(np);
  599 + preempt_enable();
  600 +
  601 + if (!err)
  602 + err = n2rng_control_configure_units(np);
  603 + }
  604 +
  605 + if (!err) {
  606 + np->flags |= N2RNG_FLAG_READY;
  607 + dev_info(&np->op->dev, "RNG ready\n");
  608 + }
  609 +
  610 + if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
  611 + schedule_delayed_work(&np->work, HZ * 2);
  612 +}
  613 +
  614 +static void __devinit n2rng_driver_version(void)
  615 +{
  616 + static int n2rng_version_printed;
  617 +
  618 + if (n2rng_version_printed++ == 0)
  619 + pr_info("%s", version);
  620 +}
  621 +
  622 +static int __devinit n2rng_probe(struct of_device *op,
  623 + const struct of_device_id *match)
  624 +{
  625 + int victoria_falls = (match->data != NULL);
  626 + int err = -ENOMEM;
  627 + struct n2rng *np;
  628 +
  629 + n2rng_driver_version();
  630 +
  631 + np = kzalloc(sizeof(*np), GFP_KERNEL);
  632 + if (!np)
  633 + goto out;
  634 + np->op = op;
  635 +
  636 + INIT_DELAYED_WORK(&np->work, n2rng_work);
  637 +
  638 + if (victoria_falls)
  639 + np->flags |= N2RNG_FLAG_VF;
  640 +
  641 + err = -ENODEV;
  642 + np->hvapi_major = 2;
  643 + if (sun4v_hvapi_register(HV_GRP_RNG,
  644 + np->hvapi_major,
  645 + &np->hvapi_minor)) {
  646 + np->hvapi_major = 1;
  647 + if (sun4v_hvapi_register(HV_GRP_RNG,
  648 + np->hvapi_major,
  649 + &np->hvapi_minor)) {
  650 + dev_err(&op->dev, "Cannot register suitable "
  651 + "HVAPI version.\n");
  652 + goto out_free;
  653 + }
  654 + }
  655 +
  656 + if (np->flags & N2RNG_FLAG_VF) {
  657 + if (np->hvapi_major < 2) {
  658 + dev_err(&op->dev, "VF RNG requires HVAPI major "
  659 + "version 2 or later, got %lu\n",
  660 + np->hvapi_major);
  661 + goto out_hvapi_unregister;
  662 + }
  663 + np->num_units = of_getintprop_default(op->node,
  664 + "rng-#units", 0);
  665 + if (!np->num_units) {
  666 + dev_err(&op->dev, "VF RNG lacks rng-#units property\n");
  667 + goto out_hvapi_unregister;
  668 + }
  669 + } else
  670 + np->num_units = 1;
  671 +
  672 + dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",
  673 + np->hvapi_major, np->hvapi_minor);
  674 +
  675 + np->units = kzalloc(sizeof(struct n2rng_unit) * np->num_units,
  676 + GFP_KERNEL);
  677 + err = -ENOMEM;
  678 + if (!np->units)
  679 + goto out_hvapi_unregister;
  680 +
  681 + err = n2rng_init_control(np);
  682 + if (err)
  683 + goto out_free_units;
  684 +
  685 + dev_info(&op->dev, "Found %s RNG, units: %d\n",
  686 + ((np->flags & N2RNG_FLAG_VF) ?
  687 + "Victoria Falls" : "Niagara2"),
  688 + np->num_units);
  689 +
  690 + np->hwrng.name = "n2rng";
  691 + np->hwrng.data_read = n2rng_data_read;
  692 + np->hwrng.priv = (unsigned long) np;
  693 +
  694 + err = hwrng_register(&np->hwrng);
  695 + if (err)
  696 + goto out_free_units;
  697 +
  698 + dev_set_drvdata(&op->dev, np);
  699 +
  700 + schedule_delayed_work(&np->work, 0);
  701 +
  702 + return 0;
  703 +
  704 +out_free_units:
  705 + kfree(np->units);
  706 + np->units = NULL;
  707 +
  708 +out_hvapi_unregister:
  709 + sun4v_hvapi_unregister(HV_GRP_RNG);
  710 +
  711 +out_free:
  712 + kfree(np);
  713 +out:
  714 + return err;
  715 +}
  716 +
  717 +static int __devexit n2rng_remove(struct of_device *op)
  718 +{
  719 + struct n2rng *np = dev_get_drvdata(&op->dev);
  720 +
  721 + np->flags |= N2RNG_FLAG_SHUTDOWN;
  722 +
  723 + cancel_delayed_work_sync(&np->work);
  724 +
  725 + hwrng_unregister(&np->hwrng);
  726 +
  727 + sun4v_hvapi_unregister(HV_GRP_RNG);
  728 +
  729 + kfree(np->units);
  730 + np->units = NULL;
  731 +
  732 + kfree(np);
  733 +
  734 + dev_set_drvdata(&op->dev, NULL);
  735 +
  736 + return 0;
  737 +}
  738 +
  739 +static struct of_device_id n2rng_match[] = {
  740 + {
  741 + .name = "random-number-generator",
  742 + .compatible = "SUNW,n2-rng",
  743 + },
  744 + {
  745 + .name = "random-number-generator",
  746 + .compatible = "SUNW,vf-rng",
  747 + .data = (void *) 1,
  748 + },
  749 + {},
  750 +};
  751 +MODULE_DEVICE_TABLE(of, n2rng_match);
  752 +
  753 +static struct of_platform_driver n2rng_driver = {
  754 + .name = "n2rng",
  755 + .match_table = n2rng_match,
  756 + .probe = n2rng_probe,
  757 + .remove = __devexit_p(n2rng_remove),
  758 +};
  759 +
  760 +static int __init n2rng_init(void)
  761 +{
  762 + return of_register_driver(&n2rng_driver, &of_bus_type);
  763 +}
  764 +
  765 +static void __exit n2rng_exit(void)
  766 +{
  767 + of_unregister_driver(&n2rng_driver);
  768 +}
  769 +
  770 +module_init(n2rng_init);
  771 +module_exit(n2rng_exit);
drivers/char/hw_random/n2rng.h
  1 +/* n2rng.h: Niagara2 RNG defines.
  2 + *
  3 + * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
  4 + */
  5 +
  6 +#ifndef _N2RNG_H
  7 +#define _N2RNG_H
  8 +
  9 +#define RNG_CTL_WAIT 0x0000000001fffe00ULL /* Minimum wait time */
  10 +#define RNG_CTL_WAIT_SHIFT 9
  11 +#define RNG_CTL_BYPASS 0x0000000000000100ULL /* VCO voltage source */
  12 +#define RNG_CTL_VCO 0x00000000000000c0ULL /* VCO rate control */
  13 +#define RNG_CTL_VCO_SHIFT 6
  14 +#define RNG_CTL_ASEL 0x0000000000000030ULL /* Analog MUX select */
  15 +#define RNG_CTL_ASEL_SHIFT 4
  16 +#define RNG_CTL_LFSR 0x0000000000000008ULL /* Use LFSR or plain shift */
  17 +#define RNG_CTL_ES3 0x0000000000000004ULL /* Enable entropy source 3 */
  18 +#define RNG_CTL_ES2 0x0000000000000002ULL /* Enable entropy source 2 */
  19 +#define RNG_CTL_ES1 0x0000000000000001ULL /* Enable entropy source 1 */
  20 +
  21 +#define HV_FAST_RNG_GET_DIAG_CTL 0x130
  22 +#define HV_FAST_RNG_CTL_READ 0x131
  23 +#define HV_FAST_RNG_CTL_WRITE 0x132
  24 +#define HV_FAST_RNG_DATA_READ_DIAG 0x133
  25 +#define HV_FAST_RNG_DATA_READ 0x134
  26 +
  27 +#define HV_RNG_STATE_UNCONFIGURED 0
  28 +#define HV_RNG_STATE_CONFIGURED 1
  29 +#define HV_RNG_STATE_HEALTHCHECK 2
  30 +#define HV_RNG_STATE_ERROR 3
  31 +
  32 +#define HV_RNG_NUM_CONTROL 4
  33 +
  34 +#ifndef __ASSEMBLY__
  35 +extern unsigned long sun4v_rng_get_diag_ctl(void);
  36 +extern unsigned long sun4v_rng_ctl_read_v1(unsigned long ctl_regs_ra,
  37 + unsigned long *state,
  38 + unsigned long *tick_delta);
  39 +extern unsigned long sun4v_rng_ctl_read_v2(unsigned long ctl_regs_ra,
  40 + unsigned long unit,
  41 + unsigned long *state,
  42 + unsigned long *tick_delta,
  43 + unsigned long *watchdog,
  44 + unsigned long *write_status);
  45 +extern unsigned long sun4v_rng_ctl_write_v1(unsigned long ctl_regs_ra,
  46 + unsigned long state,
  47 + unsigned long write_timeout,
  48 + unsigned long *tick_delta);
  49 +extern unsigned long sun4v_rng_ctl_write_v2(unsigned long ctl_regs_ra,
  50 + unsigned long state,
  51 + unsigned long write_timeout,
  52 + unsigned long unit);
  53 +extern unsigned long sun4v_rng_data_read_diag_v1(unsigned long data_ra,
  54 + unsigned long len,
  55 + unsigned long *tick_delta);
  56 +extern unsigned long sun4v_rng_data_read_diag_v2(unsigned long data_ra,
  57 + unsigned long len,
  58 + unsigned long unit,
  59 + unsigned long *tick_delta);
  60 +extern unsigned long sun4v_rng_data_read(unsigned long data_ra,
  61 + unsigned long *tick_delta);
  62 +
  63 +struct n2rng_unit {
  64 + u64 control[HV_RNG_NUM_CONTROL];
  65 +};
  66 +
  67 +struct n2rng {
  68 + struct of_device *op;
  69 +
  70 + unsigned long flags;
  71 +#define N2RNG_FLAG_VF 0x00000001 /* Victoria Falls RNG, else N2 */
  72 +#define N2RNG_FLAG_CONTROL 0x00000002 /* Operating in control domain */
  73 +#define N2RNG_FLAG_READY 0x00000008 /* Ready for hw-rng layer */
  74 +#define N2RNG_FLAG_SHUTDOWN 0x00000010 /* Driver unregistering */
  75 +#define N2RNG_FLAG_BUFFER_VALID 0x00000020 /* u32 buffer holds valid data */
  76 +
  77 + int num_units;
  78 + struct n2rng_unit *units;
  79 +
  80 + struct hwrng hwrng;
  81 + u32 buffer;
  82 +
  83 + /* Registered hypervisor group API major and minor version. */
  84 + unsigned long hvapi_major;
  85 + unsigned long hvapi_minor;
  86 +
  87 + struct delayed_work work;
  88 +
  89 + unsigned long hv_state; /* HV_RNG_STATE_foo */
  90 +
  91 + unsigned long health_check_sec;
  92 + unsigned long accum_cycles;
  93 + unsigned long wd_timeo;
  94 +#define N2RNG_HEALTH_CHECK_SEC_DEFAULT 0
  95 +#define N2RNG_ACCUM_CYCLES_DEFAULT 2048
  96 +#define N2RNG_WD_TIMEO_DEFAULT 0
  97 +
  98 + u64 scratch_control[HV_RNG_NUM_CONTROL];
  99 +
  100 +#define SELFTEST_TICKS 38859
  101 +#define SELFTEST_VAL ((u64)0xB8820C7BD387E32C)
  102 +#define SELFTEST_POLY ((u64)0x231DCEE91262B8A3)
  103 +#define SELFTEST_MATCH_GOAL 6
  104 +#define SELFTEST_LOOPS_MAX 40000
  105 +#define SELFTEST_BUFFER_WORDS 8
  106 +
  107 + u64 test_data;
  108 + u64 test_control[HV_RNG_NUM_CONTROL];
  109 + u64 test_buffer[SELFTEST_BUFFER_WORDS];
  110 +};
  111 +
  112 +#define N2RNG_BLOCK_LIMIT 60000
  113 +#define N2RNG_BUSY_LIMIT 100
  114 +#define N2RNG_HCHECK_LIMIT 100
  115 +
  116 +#endif /* !(__ASSEMBLY__) */
  117 +
  118 +#endif /* _N2RNG_H */