summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2001-06-22 19:02:45 +0000
committerJason Wright <jason@cvs.openbsd.org>2001-06-22 19:02:45 +0000
commit4e028f9f9dd91ab725f423af35f25e708032b4bf (patch)
tree0326d3055a6931dd3e1e9de387d4b62234fd6650
parent4678cf82951664f888df9e73815bb318828747fa (diff)
Add support for RNG on 7951; many thanks to Soren Kristensen
<soren@soekris.com> for donating the cards.
-rw-r--r--sys/dev/pci/hifn7751.c62
-rw-r--r--sys/dev/pci/hifn7751reg.h11
2 files changed, 71 insertions, 2 deletions
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c
index 8a77196fb34..2c7488028b8 100644
--- a/sys/dev/pci/hifn7751.c
+++ b/sys/dev/pci/hifn7751.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751.c,v 1.69 2001/06/14 23:55:02 deraadt Exp $ */
+/* $OpenBSD: hifn7751.c,v 1.70 2001/06/22 19:02:44 jason Exp $ */
/*
* Invertex AEON / Hi/fn 7751 driver
@@ -99,6 +99,8 @@ int hifn_writeramaddr __P((struct hifn_softc *, int, u_int8_t *, int));
int hifn_dmamap_aligned __P((bus_dmamap_t));
void hifn_dmamap_load __P((bus_dmamap_t, int *, struct hifn_desc *, int,
volatile int *));
+int hifn_init_pubrng __P((struct hifn_softc *));
+void hifn_rng __P((void *));
struct hifn_stats {
u_int64_t hst_ibytes;
@@ -302,6 +304,11 @@ hifn_attach(parent, self, aux)
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG)) {
+ if (hifn_init_pubrng(sc) == 0) {
+ }
+ }
+
return;
fail_intr:
@@ -318,6 +325,59 @@ fail_io0:
bus_space_unmap(sc->sc_st0, sc->sc_sh0, iosize0);
}
+int
+hifn_init_pubrng(sc)
+ struct hifn_softc *sc;
+{
+ int i;
+
+ WRITE_REG_1(sc, HIFN_1_PUB_RESET,
+ READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
+
+ for (i = 0; i < 100; i++) {
+ DELAY(1000);
+ if ((READ_REG_1(sc, HIFN_1_PUB_RESET) & HIFN_PUBRST_RESET)
+ == 0)
+ break;
+ }
+ if (i == 100) {
+ printf("%s: public key init failed\n", sc->sc_dv.dv_xname);
+ return (1);
+ }
+
+ /* Enable the rng, if available */
+ if (sc->sc_flags & HIFN_HAS_RNG) {
+ WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
+ READ_REG_1(sc, HIFN_1_RNG_CONFIG) | HIFN_RNGCFG_ENA);
+ sc->sc_rngfirst = 1;
+ if (hz >= 100)
+ sc->sc_rnghz = hz / 100;
+ else
+ sc->sc_rnghz = 1;
+ timeout_set(&sc->sc_rngto, hifn_rng, sc);
+ timeout_add(&sc->sc_rngto, sc->sc_rnghz);
+ }
+
+ return (0);
+}
+
+void
+hifn_rng(vsc)
+ void *vsc;
+{
+ struct hifn_softc *sc = vsc;
+ u_int32_t num;
+
+ num = READ_REG_1(sc, HIFN_1_RNG_DATA);
+
+ if (sc->sc_rngfirst)
+ sc->sc_rngfirst = 0;
+ else
+ add_true_randomness(num);
+
+ timeout_add(&sc->sc_rngto, sc->sc_rnghz);
+}
+
/*
* Resets the board. Values in the regesters are left as is
* from the reset (i.e. initial values are assigned elsewhere).
diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h
index a16b50eab06..3bec8ae4335 100644
--- a/sys/dev/pci/hifn7751reg.h
+++ b/sys/dev/pci/hifn7751reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751reg.h,v 1.19 2001/05/13 23:39:54 jason Exp $ */
+/* $OpenBSD: hifn7751reg.h,v 1.20 2001/06/22 19:02:43 jason Exp $ */
/*
* Invertex AEON / Hi/fn 7751 driver
@@ -143,6 +143,9 @@ struct hifn_softc {
int sc_flags;
#define HIFN_HAS_RNG 1
#define HIFN_HAS_PUBLIC 2
+ struct timeout sc_rngto;
+ int sc_rngfirst;
+ int sc_rnghz;
struct hifn_session sc_sessions[2048];
};
@@ -334,6 +337,12 @@ struct hifn_softc {
#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
+/* Public key reset register (HIFN_1_PUB_RESET) */
+#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
+
+/* Random number generator config register (HIFN_1_RNG_CONFIG) */
+#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
+
#define WRITE_REG_0(sc,reg,val) \
bus_space_write_4((sc)->sc_st0, (sc)->sc_sh0, reg, val)
#define READ_REG_0(sc,reg) \