| David S. Miller | ce08715 | 2008-06-03 15:56:11 -0700 | [diff] [blame] | 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++) | 
| Sam Ravnborg | 3f4528d | 2009-01-06 13:20:38 -0800 | [diff] [blame] | 485 | dev_err(&np->op->dev, "Test buffer slot %d [0x%016llx]\n", | 
| David S. Miller | ce08715 | 2008-06-03 15:56:11 -0700 | [diff] [blame] | 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 |  | 
| David S. Miller | fd09831 | 2008-08-31 01:23:17 -0700 | [diff] [blame] | 739 | static const struct of_device_id n2rng_match[] = { | 
| David S. Miller | ce08715 | 2008-06-03 15:56:11 -0700 | [diff] [blame] | 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); |