···59596060 If unsure, say Y.61616262+config HW_RANDOM_N2RNG6363+ tristate "Niagara2 Random Number Generator support"6464+ depends on HW_RANDOM && SPARC646565+ default HW_RANDOM6666+ ---help---6767+ This driver provides kernel-side support for the Random Number6868+ Generator hardware found on Niagara2 cpus.6969+7070+ To compile this driver as a module, choose M here: the7171+ module will be called n2-rng.7272+7373+ If unsure, say Y.7474+6275config HW_RANDOM_VIA6376 tristate "VIA HW Random Number Generator support"6477 depends on HW_RANDOM && X86_32
···11+/* n2-drv.c: Niagara-2 RNG driver.22+ *33+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>44+ */55+66+#include <linux/kernel.h>77+#include <linux/module.h>88+#include <linux/types.h>99+#include <linux/delay.h>1010+#include <linux/init.h>1111+#include <linux/slab.h>1212+#include <linux/workqueue.h>1313+#include <linux/preempt.h>1414+#include <linux/hw_random.h>1515+1616+#include <linux/of.h>1717+#include <linux/of_device.h>1818+1919+#include <asm/hypervisor.h>2020+2121+#include "n2rng.h"2222+2323+#define DRV_MODULE_NAME "n2rng"2424+#define PFX DRV_MODULE_NAME ": "2525+#define DRV_MODULE_VERSION "0.1"2626+#define DRV_MODULE_RELDATE "May 15, 2008"2727+2828+static char version[] __devinitdata =2929+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";3030+3131+MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");3232+MODULE_DESCRIPTION("Niagara2 RNG driver");3333+MODULE_LICENSE("GPL");3434+MODULE_VERSION(DRV_MODULE_VERSION);3535+3636+/* The Niagara2 RNG provides a 64-bit read-only random number3737+ * register, plus a control register. Access to the RNG is3838+ * virtualized through the hypervisor so that both guests and control3939+ * nodes can access the device.4040+ *4141+ * The entropy source consists of raw entropy sources, each4242+ * constructed from a voltage controlled oscillator whose phase is4343+ * jittered by thermal noise sources.4444+ *4545+ * The oscillator in each of the three raw entropy sources run at4646+ * different frequencies. Normally, all three generator outputs are4747+ * gathered, xored together, and fed into a CRC circuit, the output of4848+ * which is the 64-bit read-only register.4949+ *5050+ * Some time is necessary for all the necessary entropy to build up5151+ * such that a full 64-bits of entropy are available in the register.5252+ * In normal operating mode (RNG_CTL_LFSR is set), the chip implements5353+ * an interlock which blocks register reads until sufficient entropy5454+ * is available.5555+ *5656+ * A control register is provided for adjusting various aspects of RNG5757+ * operation, and to enable diagnostic modes. Each of the three raw5858+ * entropy sources has an enable bit (RNG_CTL_ES{1,2,3}). Also5959+ * provided are fields for controlling the minimum time in cycles6060+ * between read accesses to the register (RNG_CTL_WAIT, this controls6161+ * the interlock described in the previous paragraph).6262+ *6363+ * The standard setting is to have the mode bit (RNG_CTL_LFSR) set,6464+ * all three entropy sources enabled, and the interlock time set6565+ * appropriately.6666+ *6767+ * The CRC polynomial used by the chip is:6868+ *6969+ * P(X) = x64 + x61 + x57 + x56 + x52 + x51 + x50 + x48 + x47 + x46 +7070+ * x43 + x42 + x41 + x39 + x38 + x37 + x35 + x32 + x28 + x25 +7171+ * x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 17272+ *7373+ * The RNG_CTL_VCO value of each noise cell must be programmed7474+ * seperately. This is why 4 control register values must be provided7575+ * to the hypervisor. During a write, the hypervisor writes them all,7676+ * one at a time, to the actual RNG_CTL register. The first three7777+ * values are used to setup the desired RNG_CTL_VCO for each entropy7878+ * source, for example:7979+ *8080+ * control 0: (1 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES18181+ * control 1: (2 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES28282+ * control 2: (3 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES38383+ *8484+ * And then the fourth value sets the final chip state and enables8585+ * desired.8686+ */8787+8888+static int n2rng_hv_err_trans(unsigned long hv_err)8989+{9090+ switch (hv_err) {9191+ case HV_EOK:9292+ return 0;9393+ case HV_EWOULDBLOCK:9494+ return -EAGAIN;9595+ case HV_ENOACCESS:9696+ return -EPERM;9797+ case HV_EIO:9898+ return -EIO;9999+ case HV_EBUSY:100100+ return -EBUSY;101101+ case HV_EBADALIGN:102102+ case HV_ENORADDR:103103+ return -EFAULT;104104+ default:105105+ return -EINVAL;106106+ }107107+}108108+109109+static unsigned long n2rng_generic_read_control_v2(unsigned long ra,110110+ unsigned long unit)111111+{112112+ unsigned long hv_err, state, ticks, watchdog_delta, watchdog_status;113113+ int block = 0, busy = 0;114114+115115+ while (1) {116116+ hv_err = sun4v_rng_ctl_read_v2(ra, unit, &state,117117+ &ticks,118118+ &watchdog_delta,119119+ &watchdog_status);120120+ if (hv_err == HV_EOK)121121+ break;122122+123123+ if (hv_err == HV_EBUSY) {124124+ if (++busy >= N2RNG_BUSY_LIMIT)125125+ break;126126+127127+ udelay(1);128128+ } else if (hv_err == HV_EWOULDBLOCK) {129129+ if (++block >= N2RNG_BLOCK_LIMIT)130130+ break;131131+132132+ __delay(ticks);133133+ } else134134+ break;135135+ }136136+137137+ return hv_err;138138+}139139+140140+/* In multi-socket situations, the hypervisor might need to141141+ * queue up the RNG control register write if it's for a unit142142+ * that is on a cpu socket other than the one we are executing on.143143+ *144144+ * We poll here waiting for a successful read of that control145145+ * register to make sure the write has been actually performed.146146+ */147147+static unsigned long n2rng_control_settle_v2(struct n2rng *np, int unit)148148+{149149+ unsigned long ra = __pa(&np->scratch_control[0]);150150+151151+ return n2rng_generic_read_control_v2(ra, unit);152152+}153153+154154+static unsigned long n2rng_write_ctl_one(struct n2rng *np, int unit,155155+ unsigned long state,156156+ unsigned long control_ra,157157+ unsigned long watchdog_timeout,158158+ unsigned long *ticks)159159+{160160+ unsigned long hv_err;161161+162162+ if (np->hvapi_major == 1) {163163+ hv_err = sun4v_rng_ctl_write_v1(control_ra, state,164164+ watchdog_timeout, ticks);165165+ } else {166166+ hv_err = sun4v_rng_ctl_write_v2(control_ra, state,167167+ watchdog_timeout, unit);168168+ if (hv_err == HV_EOK)169169+ hv_err = n2rng_control_settle_v2(np, unit);170170+ *ticks = N2RNG_ACCUM_CYCLES_DEFAULT;171171+ }172172+173173+ return hv_err;174174+}175175+176176+static int n2rng_generic_read_data(unsigned long data_ra)177177+{178178+ unsigned long ticks, hv_err;179179+ int block = 0, hcheck = 0;180180+181181+ while (1) {182182+ hv_err = sun4v_rng_data_read(data_ra, &ticks);183183+ if (hv_err == HV_EOK)184184+ return 0;185185+186186+ if (hv_err == HV_EWOULDBLOCK) {187187+ if (++block >= N2RNG_BLOCK_LIMIT)188188+ return -EWOULDBLOCK;189189+ __delay(ticks);190190+ } else if (hv_err == HV_ENOACCESS) {191191+ return -EPERM;192192+ } else if (hv_err == HV_EIO) {193193+ if (++hcheck >= N2RNG_HCHECK_LIMIT)194194+ return -EIO;195195+ udelay(10000);196196+ } else197197+ return -ENODEV;198198+ }199199+}200200+201201+static unsigned long n2rng_read_diag_data_one(struct n2rng *np,202202+ unsigned long unit,203203+ unsigned long data_ra,204204+ unsigned long data_len,205205+ unsigned long *ticks)206206+{207207+ unsigned long hv_err;208208+209209+ if (np->hvapi_major == 1) {210210+ hv_err = sun4v_rng_data_read_diag_v1(data_ra, data_len, ticks);211211+ } else {212212+ hv_err = sun4v_rng_data_read_diag_v2(data_ra, data_len,213213+ unit, ticks);214214+ if (!*ticks)215215+ *ticks = N2RNG_ACCUM_CYCLES_DEFAULT;216216+ }217217+ return hv_err;218218+}219219+220220+static int n2rng_generic_read_diag_data(struct n2rng *np,221221+ unsigned long unit,222222+ unsigned long data_ra,223223+ unsigned long data_len)224224+{225225+ unsigned long ticks, hv_err;226226+ int block = 0;227227+228228+ while (1) {229229+ hv_err = n2rng_read_diag_data_one(np, unit,230230+ data_ra, data_len,231231+ &ticks);232232+ if (hv_err == HV_EOK)233233+ return 0;234234+235235+ if (hv_err == HV_EWOULDBLOCK) {236236+ if (++block >= N2RNG_BLOCK_LIMIT)237237+ return -EWOULDBLOCK;238238+ __delay(ticks);239239+ } else if (hv_err == HV_ENOACCESS) {240240+ return -EPERM;241241+ } else if (hv_err == HV_EIO) {242242+ return -EIO;243243+ } else244244+ return -ENODEV;245245+ }246246+}247247+248248+249249+static int n2rng_generic_write_control(struct n2rng *np,250250+ unsigned long control_ra,251251+ unsigned long unit,252252+ unsigned long state)253253+{254254+ unsigned long hv_err, ticks;255255+ int block = 0, busy = 0;256256+257257+ while (1) {258258+ hv_err = n2rng_write_ctl_one(np, unit, state, control_ra,259259+ np->wd_timeo, &ticks);260260+ if (hv_err == HV_EOK)261261+ return 0;262262+263263+ if (hv_err == HV_EWOULDBLOCK) {264264+ if (++block >= N2RNG_BLOCK_LIMIT)265265+ return -EWOULDBLOCK;266266+ __delay(ticks);267267+ } else if (hv_err == HV_EBUSY) {268268+ if (++busy >= N2RNG_BUSY_LIMIT)269269+ return -EBUSY;270270+ udelay(1);271271+ } else272272+ return -ENODEV;273273+ }274274+}275275+276276+/* Just try to see if we can successfully access the control register277277+ * of the RNG on the domain on which we are currently executing.278278+ */279279+static int n2rng_try_read_ctl(struct n2rng *np)280280+{281281+ unsigned long hv_err;282282+ unsigned long x;283283+284284+ if (np->hvapi_major == 1) {285285+ hv_err = sun4v_rng_get_diag_ctl();286286+ } else {287287+ /* We purposefully give invalid arguments, HV_NOACCESS288288+ * is higher priority than the errors we'd get from289289+ * these other cases, and that's the error we are290290+ * truly interested in.291291+ */292292+ hv_err = sun4v_rng_ctl_read_v2(0UL, ~0UL, &x, &x, &x, &x);293293+ switch (hv_err) {294294+ case HV_EWOULDBLOCK:295295+ case HV_ENOACCESS:296296+ break;297297+ default:298298+ hv_err = HV_EOK;299299+ break;300300+ }301301+ }302302+303303+ return n2rng_hv_err_trans(hv_err);304304+}305305+306306+#define CONTROL_DEFAULT_BASE \307307+ ((2 << RNG_CTL_ASEL_SHIFT) | \308308+ (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) | \309309+ RNG_CTL_LFSR)310310+311311+#define CONTROL_DEFAULT_0 \312312+ (CONTROL_DEFAULT_BASE | \313313+ (1 << RNG_CTL_VCO_SHIFT) | \314314+ RNG_CTL_ES1)315315+#define CONTROL_DEFAULT_1 \316316+ (CONTROL_DEFAULT_BASE | \317317+ (2 << RNG_CTL_VCO_SHIFT) | \318318+ RNG_CTL_ES2)319319+#define CONTROL_DEFAULT_2 \320320+ (CONTROL_DEFAULT_BASE | \321321+ (3 << RNG_CTL_VCO_SHIFT) | \322322+ RNG_CTL_ES3)323323+#define CONTROL_DEFAULT_3 \324324+ (CONTROL_DEFAULT_BASE | \325325+ RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3)326326+327327+static void n2rng_control_swstate_init(struct n2rng *np)328328+{329329+ int i;330330+331331+ np->flags |= N2RNG_FLAG_CONTROL;332332+333333+ np->health_check_sec = N2RNG_HEALTH_CHECK_SEC_DEFAULT;334334+ np->accum_cycles = N2RNG_ACCUM_CYCLES_DEFAULT;335335+ np->wd_timeo = N2RNG_WD_TIMEO_DEFAULT;336336+337337+ for (i = 0; i < np->num_units; i++) {338338+ struct n2rng_unit *up = &np->units[i];339339+340340+ up->control[0] = CONTROL_DEFAULT_0;341341+ up->control[1] = CONTROL_DEFAULT_1;342342+ up->control[2] = CONTROL_DEFAULT_2;343343+ up->control[3] = CONTROL_DEFAULT_3;344344+ }345345+346346+ np->hv_state = HV_RNG_STATE_UNCONFIGURED;347347+}348348+349349+static int n2rng_grab_diag_control(struct n2rng *np)350350+{351351+ int i, busy_count, err = -ENODEV;352352+353353+ busy_count = 0;354354+ for (i = 0; i < 100; i++) {355355+ err = n2rng_try_read_ctl(np);356356+ if (err != -EAGAIN)357357+ break;358358+359359+ if (++busy_count > 100) {360360+ dev_err(&np->op->dev,361361+ "Grab diag control timeout.\n");362362+ return -ENODEV;363363+ }364364+365365+ udelay(1);366366+ }367367+368368+ return err;369369+}370370+371371+static int n2rng_init_control(struct n2rng *np)372372+{373373+ int err = n2rng_grab_diag_control(np);374374+375375+ /* Not in the control domain, that's OK we are only a consumer376376+ * of the RNG data, we don't setup and program it.377377+ */378378+ if (err == -EPERM)379379+ return 0;380380+ if (err)381381+ return err;382382+383383+ n2rng_control_swstate_init(np);384384+385385+ return 0;386386+}387387+388388+static int n2rng_data_read(struct hwrng *rng, u32 *data)389389+{390390+ struct n2rng *np = (struct n2rng *) rng->priv;391391+ unsigned long ra = __pa(&np->test_data);392392+ int len;393393+394394+ if (!(np->flags & N2RNG_FLAG_READY)) {395395+ len = 0;396396+ } else if (np->flags & N2RNG_FLAG_BUFFER_VALID) {397397+ np->flags &= ~N2RNG_FLAG_BUFFER_VALID;398398+ *data = np->buffer;399399+ len = 4;400400+ } else {401401+ int err = n2rng_generic_read_data(ra);402402+ if (!err) {403403+ np->buffer = np->test_data >> 32;404404+ *data = np->test_data & 0xffffffff;405405+ len = 4;406406+ } else {407407+ dev_err(&np->op->dev, "RNG error, restesting\n");408408+ np->flags &= ~N2RNG_FLAG_READY;409409+ if (!(np->flags & N2RNG_FLAG_SHUTDOWN))410410+ schedule_delayed_work(&np->work, 0);411411+ len = 0;412412+ }413413+ }414414+415415+ return len;416416+}417417+418418+/* On a guest node, just make sure we can read random data properly.419419+ * If a control node reboots or reloads it's n2rng driver, this won't420420+ * work during that time. So we have to keep probing until the device421421+ * becomes usable.422422+ */423423+static int n2rng_guest_check(struct n2rng *np)424424+{425425+ unsigned long ra = __pa(&np->test_data);426426+427427+ return n2rng_generic_read_data(ra);428428+}429429+430430+static int n2rng_entropy_diag_read(struct n2rng *np, unsigned long unit,431431+ u64 *pre_control, u64 pre_state,432432+ u64 *buffer, unsigned long buf_len,433433+ u64 *post_control, u64 post_state)434434+{435435+ unsigned long post_ctl_ra = __pa(post_control);436436+ unsigned long pre_ctl_ra = __pa(pre_control);437437+ unsigned long buffer_ra = __pa(buffer);438438+ int err;439439+440440+ err = n2rng_generic_write_control(np, pre_ctl_ra, unit, pre_state);441441+ if (err)442442+ return err;443443+444444+ err = n2rng_generic_read_diag_data(np, unit,445445+ buffer_ra, buf_len);446446+447447+ (void) n2rng_generic_write_control(np, post_ctl_ra, unit,448448+ post_state);449449+450450+ return err;451451+}452452+453453+static u64 advance_polynomial(u64 poly, u64 val, int count)454454+{455455+ int i;456456+457457+ for (i = 0; i < count; i++) {458458+ int highbit_set = ((s64)val < 0);459459+460460+ val <<= 1;461461+ if (highbit_set)462462+ val ^= poly;463463+ }464464+465465+ return val;466466+}467467+468468+static int n2rng_test_buffer_find(struct n2rng *np, u64 val)469469+{470470+ int i, count = 0;471471+472472+ /* Purposefully skip over the first word. */473473+ for (i = 1; i < SELFTEST_BUFFER_WORDS; i++) {474474+ if (np->test_buffer[i] == val)475475+ count++;476476+ }477477+ return count;478478+}479479+480480+static void n2rng_dump_test_buffer(struct n2rng *np)481481+{482482+ int i;483483+484484+ for (i = 0; i < SELFTEST_BUFFER_WORDS; i++)485485+ dev_err(&np->op->dev, "Test buffer slot %d [0x%016lx]\n",486486+ i, np->test_buffer[i]);487487+}488488+489489+static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)490490+{491491+ u64 val = SELFTEST_VAL;492492+ int err, matches, limit;493493+494494+ matches = 0;495495+ for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) {496496+ matches += n2rng_test_buffer_find(np, val);497497+ if (matches >= SELFTEST_MATCH_GOAL)498498+ break;499499+ val = advance_polynomial(SELFTEST_POLY, val, 1);500500+ }501501+502502+ err = 0;503503+ if (limit >= SELFTEST_LOOPS_MAX) {504504+ err = -ENODEV;505505+ dev_err(&np->op->dev, "Selftest failed on unit %lu\n", unit);506506+ n2rng_dump_test_buffer(np);507507+ } else508508+ dev_info(&np->op->dev, "Selftest passed on unit %lu\n", unit);509509+510510+ return err;511511+}512512+513513+static int n2rng_control_selftest(struct n2rng *np, unsigned long unit)514514+{515515+ int err;516516+517517+ np->test_control[0] = (0x2 << RNG_CTL_ASEL_SHIFT);518518+ np->test_control[1] = (0x2 << RNG_CTL_ASEL_SHIFT);519519+ np->test_control[2] = (0x2 << RNG_CTL_ASEL_SHIFT);520520+ np->test_control[3] = ((0x2 << RNG_CTL_ASEL_SHIFT) |521521+ RNG_CTL_LFSR |522522+ ((SELFTEST_TICKS - 2) << RNG_CTL_WAIT_SHIFT));523523+524524+525525+ err = n2rng_entropy_diag_read(np, unit, np->test_control,526526+ HV_RNG_STATE_HEALTHCHECK,527527+ np->test_buffer,528528+ sizeof(np->test_buffer),529529+ &np->units[unit].control[0],530530+ np->hv_state);531531+ if (err)532532+ return err;533533+534534+ return n2rng_check_selftest_buffer(np, unit);535535+}536536+537537+static int n2rng_control_check(struct n2rng *np)538538+{539539+ int i;540540+541541+ for (i = 0; i < np->num_units; i++) {542542+ int err = n2rng_control_selftest(np, i);543543+ if (err)544544+ return err;545545+ }546546+ return 0;547547+}548548+549549+/* The sanity checks passed, install the final configuration into the550550+ * chip, it's ready to use.551551+ */552552+static int n2rng_control_configure_units(struct n2rng *np)553553+{554554+ int unit, err;555555+556556+ err = 0;557557+ for (unit = 0; unit < np->num_units; unit++) {558558+ struct n2rng_unit *up = &np->units[unit];559559+ unsigned long ctl_ra = __pa(&up->control[0]);560560+ int esrc;561561+ u64 base;562562+563563+ base = ((np->accum_cycles << RNG_CTL_WAIT_SHIFT) |564564+ (2 << RNG_CTL_ASEL_SHIFT) |565565+ RNG_CTL_LFSR);566566+567567+ /* XXX This isn't the best. We should fetch a bunch568568+ * XXX of words using each entropy source combined XXX569569+ * with each VCO setting, and see which combinations570570+ * XXX give the best random data.571571+ */572572+ for (esrc = 0; esrc < 3; esrc++)573573+ up->control[esrc] = base |574574+ (esrc << RNG_CTL_VCO_SHIFT) |575575+ (RNG_CTL_ES1 << esrc);576576+577577+ up->control[3] = base |578578+ (RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3);579579+580580+ err = n2rng_generic_write_control(np, ctl_ra, unit,581581+ HV_RNG_STATE_CONFIGURED);582582+ if (err)583583+ break;584584+ }585585+586586+ return err;587587+}588588+589589+static void n2rng_work(struct work_struct *work)590590+{591591+ struct n2rng *np = container_of(work, struct n2rng, work.work);592592+ int err = 0;593593+594594+ if (!(np->flags & N2RNG_FLAG_CONTROL)) {595595+ err = n2rng_guest_check(np);596596+ } else {597597+ preempt_disable();598598+ err = n2rng_control_check(np);599599+ preempt_enable();600600+601601+ if (!err)602602+ err = n2rng_control_configure_units(np);603603+ }604604+605605+ if (!err) {606606+ np->flags |= N2RNG_FLAG_READY;607607+ dev_info(&np->op->dev, "RNG ready\n");608608+ }609609+610610+ if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))611611+ schedule_delayed_work(&np->work, HZ * 2);612612+}613613+614614+static void __devinit n2rng_driver_version(void)615615+{616616+ static int n2rng_version_printed;617617+618618+ if (n2rng_version_printed++ == 0)619619+ pr_info("%s", version);620620+}621621+622622+static int __devinit n2rng_probe(struct of_device *op,623623+ const struct of_device_id *match)624624+{625625+ int victoria_falls = (match->data != NULL);626626+ int err = -ENOMEM;627627+ struct n2rng *np;628628+629629+ n2rng_driver_version();630630+631631+ np = kzalloc(sizeof(*np), GFP_KERNEL);632632+ if (!np)633633+ goto out;634634+ np->op = op;635635+636636+ INIT_DELAYED_WORK(&np->work, n2rng_work);637637+638638+ if (victoria_falls)639639+ np->flags |= N2RNG_FLAG_VF;640640+641641+ err = -ENODEV;642642+ np->hvapi_major = 2;643643+ if (sun4v_hvapi_register(HV_GRP_RNG,644644+ np->hvapi_major,645645+ &np->hvapi_minor)) {646646+ np->hvapi_major = 1;647647+ if (sun4v_hvapi_register(HV_GRP_RNG,648648+ np->hvapi_major,649649+ &np->hvapi_minor)) {650650+ dev_err(&op->dev, "Cannot register suitable "651651+ "HVAPI version.\n");652652+ goto out_free;653653+ }654654+ }655655+656656+ if (np->flags & N2RNG_FLAG_VF) {657657+ if (np->hvapi_major < 2) {658658+ dev_err(&op->dev, "VF RNG requires HVAPI major "659659+ "version 2 or later, got %lu\n",660660+ np->hvapi_major);661661+ goto out_hvapi_unregister;662662+ }663663+ np->num_units = of_getintprop_default(op->node,664664+ "rng-#units", 0);665665+ if (!np->num_units) {666666+ dev_err(&op->dev, "VF RNG lacks rng-#units property\n");667667+ goto out_hvapi_unregister;668668+ }669669+ } else670670+ np->num_units = 1;671671+672672+ dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",673673+ np->hvapi_major, np->hvapi_minor);674674+675675+ np->units = kzalloc(sizeof(struct n2rng_unit) * np->num_units,676676+ GFP_KERNEL);677677+ err = -ENOMEM;678678+ if (!np->units)679679+ goto out_hvapi_unregister;680680+681681+ err = n2rng_init_control(np);682682+ if (err)683683+ goto out_free_units;684684+685685+ dev_info(&op->dev, "Found %s RNG, units: %d\n",686686+ ((np->flags & N2RNG_FLAG_VF) ?687687+ "Victoria Falls" : "Niagara2"),688688+ np->num_units);689689+690690+ np->hwrng.name = "n2rng";691691+ np->hwrng.data_read = n2rng_data_read;692692+ np->hwrng.priv = (unsigned long) np;693693+694694+ err = hwrng_register(&np->hwrng);695695+ if (err)696696+ goto out_free_units;697697+698698+ dev_set_drvdata(&op->dev, np);699699+700700+ schedule_delayed_work(&np->work, 0);701701+702702+ return 0;703703+704704+out_free_units:705705+ kfree(np->units);706706+ np->units = NULL;707707+708708+out_hvapi_unregister:709709+ sun4v_hvapi_unregister(HV_GRP_RNG);710710+711711+out_free:712712+ kfree(np);713713+out:714714+ return err;715715+}716716+717717+static int __devexit n2rng_remove(struct of_device *op)718718+{719719+ struct n2rng *np = dev_get_drvdata(&op->dev);720720+721721+ np->flags |= N2RNG_FLAG_SHUTDOWN;722722+723723+ cancel_delayed_work_sync(&np->work);724724+725725+ hwrng_unregister(&np->hwrng);726726+727727+ sun4v_hvapi_unregister(HV_GRP_RNG);728728+729729+ kfree(np->units);730730+ np->units = NULL;731731+732732+ kfree(np);733733+734734+ dev_set_drvdata(&op->dev, NULL);735735+736736+ return 0;737737+}738738+739739+static struct of_device_id n2rng_match[] = {740740+ {741741+ .name = "random-number-generator",742742+ .compatible = "SUNW,n2-rng",743743+ },744744+ {745745+ .name = "random-number-generator",746746+ .compatible = "SUNW,vf-rng",747747+ .data = (void *) 1,748748+ },749749+ {},750750+};751751+MODULE_DEVICE_TABLE(of, n2rng_match);752752+753753+static struct of_platform_driver n2rng_driver = {754754+ .name = "n2rng",755755+ .match_table = n2rng_match,756756+ .probe = n2rng_probe,757757+ .remove = __devexit_p(n2rng_remove),758758+};759759+760760+static int __init n2rng_init(void)761761+{762762+ return of_register_driver(&n2rng_driver, &of_bus_type);763763+}764764+765765+static void __exit n2rng_exit(void)766766+{767767+ of_unregister_driver(&n2rng_driver);768768+}769769+770770+module_init(n2rng_init);771771+module_exit(n2rng_exit);
+118
drivers/char/hw_random/n2rng.h
···11+/* n2rng.h: Niagara2 RNG defines.22+ *33+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>44+ */55+66+#ifndef _N2RNG_H77+#define _N2RNG_H88+99+#define RNG_CTL_WAIT 0x0000000001fffe00ULL /* Minimum wait time */1010+#define RNG_CTL_WAIT_SHIFT 91111+#define RNG_CTL_BYPASS 0x0000000000000100ULL /* VCO voltage source */1212+#define RNG_CTL_VCO 0x00000000000000c0ULL /* VCO rate control */1313+#define RNG_CTL_VCO_SHIFT 61414+#define RNG_CTL_ASEL 0x0000000000000030ULL /* Analog MUX select */1515+#define RNG_CTL_ASEL_SHIFT 41616+#define RNG_CTL_LFSR 0x0000000000000008ULL /* Use LFSR or plain shift */1717+#define RNG_CTL_ES3 0x0000000000000004ULL /* Enable entropy source 3 */1818+#define RNG_CTL_ES2 0x0000000000000002ULL /* Enable entropy source 2 */1919+#define RNG_CTL_ES1 0x0000000000000001ULL /* Enable entropy source 1 */2020+2121+#define HV_FAST_RNG_GET_DIAG_CTL 0x1302222+#define HV_FAST_RNG_CTL_READ 0x1312323+#define HV_FAST_RNG_CTL_WRITE 0x1322424+#define HV_FAST_RNG_DATA_READ_DIAG 0x1332525+#define HV_FAST_RNG_DATA_READ 0x1342626+2727+#define HV_RNG_STATE_UNCONFIGURED 02828+#define HV_RNG_STATE_CONFIGURED 12929+#define HV_RNG_STATE_HEALTHCHECK 23030+#define HV_RNG_STATE_ERROR 33131+3232+#define HV_RNG_NUM_CONTROL 43333+3434+#ifndef __ASSEMBLY__3535+extern unsigned long sun4v_rng_get_diag_ctl(void);3636+extern unsigned long sun4v_rng_ctl_read_v1(unsigned long ctl_regs_ra,3737+ unsigned long *state,3838+ unsigned long *tick_delta);3939+extern unsigned long sun4v_rng_ctl_read_v2(unsigned long ctl_regs_ra,4040+ unsigned long unit,4141+ unsigned long *state,4242+ unsigned long *tick_delta,4343+ unsigned long *watchdog,4444+ unsigned long *write_status);4545+extern unsigned long sun4v_rng_ctl_write_v1(unsigned long ctl_regs_ra,4646+ unsigned long state,4747+ unsigned long write_timeout,4848+ unsigned long *tick_delta);4949+extern unsigned long sun4v_rng_ctl_write_v2(unsigned long ctl_regs_ra,5050+ unsigned long state,5151+ unsigned long write_timeout,5252+ unsigned long unit);5353+extern unsigned long sun4v_rng_data_read_diag_v1(unsigned long data_ra,5454+ unsigned long len,5555+ unsigned long *tick_delta);5656+extern unsigned long sun4v_rng_data_read_diag_v2(unsigned long data_ra,5757+ unsigned long len,5858+ unsigned long unit,5959+ unsigned long *tick_delta);6060+extern unsigned long sun4v_rng_data_read(unsigned long data_ra,6161+ unsigned long *tick_delta);6262+6363+struct n2rng_unit {6464+ u64 control[HV_RNG_NUM_CONTROL];6565+};6666+6767+struct n2rng {6868+ struct of_device *op;6969+7070+ unsigned long flags;7171+#define N2RNG_FLAG_VF 0x00000001 /* Victoria Falls RNG, else N2 */7272+#define N2RNG_FLAG_CONTROL 0x00000002 /* Operating in control domain */7373+#define N2RNG_FLAG_READY 0x00000008 /* Ready for hw-rng layer */7474+#define N2RNG_FLAG_SHUTDOWN 0x00000010 /* Driver unregistering */7575+#define N2RNG_FLAG_BUFFER_VALID 0x00000020 /* u32 buffer holds valid data */7676+7777+ int num_units;7878+ struct n2rng_unit *units;7979+8080+ struct hwrng hwrng;8181+ u32 buffer;8282+8383+ /* Registered hypervisor group API major and minor version. */8484+ unsigned long hvapi_major;8585+ unsigned long hvapi_minor;8686+8787+ struct delayed_work work;8888+8989+ unsigned long hv_state; /* HV_RNG_STATE_foo */9090+9191+ unsigned long health_check_sec;9292+ unsigned long accum_cycles;9393+ unsigned long wd_timeo;9494+#define N2RNG_HEALTH_CHECK_SEC_DEFAULT 09595+#define N2RNG_ACCUM_CYCLES_DEFAULT 20489696+#define N2RNG_WD_TIMEO_DEFAULT 09797+9898+ u64 scratch_control[HV_RNG_NUM_CONTROL];9999+100100+#define SELFTEST_TICKS 38859101101+#define SELFTEST_VAL ((u64)0xB8820C7BD387E32C)102102+#define SELFTEST_POLY ((u64)0x231DCEE91262B8A3)103103+#define SELFTEST_MATCH_GOAL 6104104+#define SELFTEST_LOOPS_MAX 40000105105+#define SELFTEST_BUFFER_WORDS 8106106+107107+ u64 test_data;108108+ u64 test_control[HV_RNG_NUM_CONTROL];109109+ u64 test_buffer[SELFTEST_BUFFER_WORDS];110110+};111111+112112+#define N2RNG_BLOCK_LIMIT 60000113113+#define N2RNG_BUSY_LIMIT 100114114+#define N2RNG_HCHECK_LIMIT 100115115+116116+#endif /* !(__ASSEMBLY__) */117117+118118+#endif /* _N2RNG_H */