summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorHakan Olsson <ho@cvs.openbsd.org>2001-01-29 08:45:59 +0000
committerHakan Olsson <ho@cvs.openbsd.org>2001-01-29 08:45:59 +0000
commit003c873954c56a73b4954c316e1450ace0986f95 (patch)
tree8f7874e41210642eb155a86bf2891d0dc3e144c5 /sys/dev
parent966b0d65a6b481ceff231bada6ca1999337ddd02 (diff)
Driver for the Pijnenburg PCC-ISES crypto chip. For now, it only generates
random data for the system entropy pool. No crypto yet.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/files.pci7
-rw-r--r--sys/dev/pci/ises.c1366
-rw-r--r--sys/dev/pci/isesreg.h645
-rw-r--r--sys/dev/pci/isesvar.h83
4 files changed, 2100 insertions, 1 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 7b630a71b71..635bb29c246 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.91 2001/01/23 04:19:42 krw Exp $
+# $OpenBSD: files.pci,v 1.92 2001/01/29 08:45:58 ho Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -254,6 +254,11 @@ device ubsec: crypto
attach ubsec at pci
file dev/pci/ubsec.c ubsec
+# Pijnenburg PCC-ISES
+device ises: crypto
+attach ises at pci
+file dev/pci/ises.c ises
+
# Winbond W89C840F ethernet
device wb: ether, ifnet, mii, ifmedia, mii_phy
attach wb at pci
diff --git a/sys/dev/pci/ises.c b/sys/dev/pci/ises.c
new file mode 100644
index 00000000000..ad0a4f3c638
--- /dev/null
+++ b/sys/dev/pci/ises.c
@@ -0,0 +1,1366 @@
+/* $OpenBSD: ises.c,v 1.1 2001/01/29 08:45:58 ho Exp $ */
+
+/*
+ * Copyright (c) 2000 Håkan Olsson (ho@crt.se)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * PCC-ISES hardware crypto accelerator
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/timeout.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+
+#include <crypto/crypto.h>
+#include <crypto/cryptosoft.h>
+#include <dev/rndvar.h>
+#include <sys/md5k.h>
+#include <crypto/sha1.h>
+#include <crypto/rmd160.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/pci/isesreg.h>
+#include <dev/pci/isesvar.h>
+
+/*
+ * Prototypes and count for the pci_device structure
+ */
+int ises_match __P((struct device *, void *, void *));
+void ises_attach __P((struct device *, struct device *, void *));
+
+void ises_initstate __P((void *));
+void ises_hrng_init __P((struct ises_softc *));
+void ises_hrng __P((void *));
+void ises_process_oqueue __P((struct ises_softc *));
+int ises_queue_cmd __P((struct ises_softc *, u_int32_t, u_int32_t *));
+u_int32_t ises_get_fwversion __P((struct ises_softc *));
+int ises_assert_cmd_mode __P((struct ises_softc *));
+
+int ises_intr __P((void *));
+int ises_newsession __P((u_int32_t *, struct cryptoini *));
+int ises_freesession __P((u_int64_t));
+int ises_process __P((struct cryptop *));
+void ises_callback __P((struct ises_q *));
+int ises_feed __P((struct ises_softc *));
+
+/* XXX for now... */
+void ubsec_mcopy __P((struct mbuf *, struct mbuf *, int, int));
+
+#define READ_REG(sc,r) \
+ bus_space_read_4((sc)->sc_memt, (sc)->sc_memh,r)
+
+#define WRITE_REG(sc,reg,val) \
+ bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, reg, val)
+
+#define SWAP32(x) ((x) = swap32((x)))
+
+#ifdef ISESDEBUG
+# define DPRINTF(x) printf x
+#else
+# define DPRINTF(x)
+#endif
+
+/* For HRNG entropy collection, these values gather 5KB/s */
+#ifndef ISESRNGBITS
+#define ISESRNGBITS 4096 /* Bits per iteration */
+#define ISESRNGIPS 10 /* Iterations per second */
+#endif
+
+struct cfattach ises_ca = {
+ sizeof (struct ises_softc), ises_match, ises_attach,
+};
+
+struct cfdriver ises_cd = {
+ 0, "ises", DV_DULL
+};
+
+int
+ises_match(struct device *parent, void *match, void *aux)
+{
+ struct pci_attach_args *pa = (struct pci_attach_args *) aux;
+
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_PIJNENBURG &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_PIJNENBURG_PCC_ISES)
+ return (1);
+
+ return (0);
+}
+
+void
+ises_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct ises_softc *sc = (struct ises_softc *)self;
+ struct pci_attach_args *pa = aux;
+ pci_chipset_tag_t pc = pa->pa_pc;
+ pci_intr_handle_t ih;
+ const char *intrstr = NULL;
+ bus_addr_t membase;
+ bus_size_t memsize;
+ u_int32_t cmd;
+
+ bus_dma_segment_t seg;
+ int nsegs, error, state;
+
+ SIMPLEQ_INIT(&sc->sc_queue);
+ SIMPLEQ_INIT(&sc->sc_qchip);
+ state = 0;
+
+ /* Verify PCI space */
+ cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ cmd |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
+ pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, cmd);
+ cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+
+ if (!(cmd & PCI_COMMAND_MEM_ENABLE)) {
+ printf(": failed to enable memory mapping\n");
+ return;
+ }
+
+ if (!(cmd & PCI_COMMAND_MASTER_ENABLE)) {
+ printf(": failed to enable bus mastering\n");
+ return;
+ }
+
+ /* Map control/status registers. */
+ if (pci_mapreg_map (pa, PCI_MAPREG_START,
+ PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
+ 0, &sc->sc_memt, &sc->sc_memh, &membase,
+ &memsize)) {
+ printf(": can't find mem space\n");
+ return;
+ }
+ state++;
+
+ /* Map interrupt. */
+ if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, pa->pa_intrline,
+ &ih)) {
+ printf(": couldn't map interrupt\n");
+ goto fail;
+ }
+ state++;
+
+ intrstr = pci_intr_string(pc, ih);
+ sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ises_intr, sc,
+ self->dv_xname);
+ if (sc->sc_ih == NULL) {
+ printf(": couldn't establish interrupt\n");
+ if (intrstr != NULL)
+ printf(" at %s", intrstr);
+ printf("\n");
+ goto fail;
+ }
+
+ /* Initialize DMA map */
+ sc->sc_dmat = pa->pa_dmat;
+ error = bus_dmamap_create (sc->sc_dmat, 1 << PGSHIFT, 1, 1 << PGSHIFT,
+ 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
+ &sc->sc_dmamap_xfer);
+ if (error) {
+ printf (": cannot create dma map (%d)\n", error);
+ goto fail;
+ }
+ state++;
+
+ /* Allocate in DMAable memory. */
+ if (bus_dmamem_alloc (sc->sc_dmat, sizeof sc->sc_dmamap, 1, 0, &seg,
+ 1, &nsegs, BUS_DMA_NOWAIT)) {
+ printf (": can't alloc dma buffer space\n");
+ goto fail;
+ }
+ state++;
+
+ sc->sc_dmamap_phys = seg.ds_addr;
+ if (bus_dmamem_map (sc->sc_dmat, &seg, nsegs, sizeof sc->sc_dmamap,
+ (caddr_t *)&sc->sc_dmamap, 0)) {
+ printf (": can't map dma buffer space\n");
+ goto fail;
+ }
+ state++;
+
+ printf(": %s\n", intrstr);
+
+ sc->sc_cid = crypto_get_driverid();
+
+ if (sc->sc_cid < 0)
+ goto fail;
+
+ /*
+ * Since none of the initialization steps generate interrupts
+ * for example, the hardware reset, we use a number of timeouts
+ * (or init states) to do the rest of the chip initialization.
+ */
+
+ sc->sc_initstate = 0;
+ timeout_set (&sc->sc_timeout, ises_initstate, sc);
+ ises_initstate (sc);
+
+ return;
+
+ fail:
+ switch (state) /* Always fallthrough here. */
+ {
+ case 4:
+ bus_dmamem_unmap(sc->sc_dmat, (caddr_t)&sc->sc_dmamap,
+ sizeof sc->sc_dmamap);
+ case 3:
+ bus_dmamem_free(sc->sc_dmat, &seg, nsegs);
+ case 2:
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_xfer);
+ case 1:
+ pci_intr_disestablish(pc, sc->sc_ih);
+ default: /* 0 */
+ bus_space_unmap(sc->sc_memt, sc->sc_memh, memsize);
+ }
+ return;
+}
+
+void
+ises_initstate (void *v)
+{
+ /*
+ * Step through chip initialization.
+ * sc->sc_initstate tells us what to do.
+ */
+ extern int hz;
+ struct ises_softc *sc = v;
+ char *dv = sc->sc_dv.dv_xname;
+ u_int32_t stat;
+ int p, ticks;
+
+ ticks = hz;
+
+#if 0 /* Too noisy */
+ DPRINTF (("%s: entered initstate %d\n", dv, sc->sc_initstate));
+#endif
+
+ switch (sc->sc_initstate)
+ {
+ case 0:
+ /* Power up the chip (clear powerdown bit) */
+ stat = READ_REG(sc, ISES_BO_STAT);
+ if (stat & ISES_BO_STAT_POWERDOWN) {
+ stat &= ~ISES_BO_STAT_POWERDOWN;
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+ /* Selftests will take 1 second. */
+ break;
+ }
+ /* FALLTHROUGH (chip is already powered up) */
+ sc->sc_initstate++;
+
+ case 1:
+ /* Perform a hardware reset */
+ stat = 0;
+
+ printf ("%s: initializing...\n", dv);
+
+ /* Clear all possible bypass bits. */
+ for (p = 0; p < 128; p++)
+ WRITE_REG(sc, ISES_B_BDATAOUT, 0L);
+
+ stat |= ISES_BO_STAT_HWRESET;
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+ stat &= ~ISES_BO_STAT_HWRESET;
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+ /* Again, selftests will take 1 second. */
+ break;
+
+ case 2:
+ /* Set AConf to zero, i.e 32-bits access to A-int. */
+ stat = READ_REG(sc, ISES_BO_STAT);
+ stat &= ~ISES_BO_STAT_ACONF;
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+
+ /* Is the firmware already loaded? */
+ if (READ_REG(sc, ISES_A_STAT) & ISES_STAT_HW_DA) {
+ /* Yes it is, jump ahead a bit */
+ ticks = 1;
+ sc->sc_initstate += 4; /* Next step --> 7 */
+ break;
+ }
+
+ /*
+ * Download the Basic Functionality firmware.
+ * Prior to downloading we need to reset the NSRAM.
+ * Setting the tamper bit will erase the contents
+ * in 1 microsecond.
+ */
+ stat = READ_REG(sc, ISES_BO_STAT);
+ stat |= ISES_BO_STAT_TAMPER;
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+ ticks = 1;
+ break;
+
+ case 3:
+ /* After tamper bit has been set, powerdown chip. */
+ stat = READ_REG(sc, ISES_BO_STAT);
+ stat |= ISES_BO_STAT_POWERDOWN;
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+ /* Wait one second for power to dissipate. */
+ break;
+
+ case 4:
+ /* Clear tamper and powerdown bits. */
+ stat = READ_REG(sc, ISES_BO_STAT);
+ stat &= ~(ISES_BO_STAT_TAMPER |
+ ISES_BO_STAT_POWERDOWN);
+ WRITE_REG(sc, ISES_BO_STAT, stat);
+ /* Again, wait one second for selftests. */
+ break;
+
+ case 5:
+ /*
+ * We'll need some space in the input queue (IQF)
+ * and we need to be in the 'waiting for program
+ * length' IDP state (0x4).
+ */
+ p = ISES_STAT_IDP_STATE(READ_REG(sc, ISES_A_STAT));
+ if (READ_REG(sc, ISES_A_IQF) < 4 || p != 0x4) {
+ printf("%s: cannot download firmware, "
+ "IDP state is \"%s\"\n", dv,
+ ises_idp_state[p]);
+ return;
+ }
+
+ /* Write firmware length */
+ WRITE_REG(sc, ISES_A_IQD, ISES_BF_IDPLEN);
+
+ /* Write firmware code */
+ for (p = 0; p < sizeof (ises_bf_fw)/sizeof (u_int32_t);
+ p++) {
+ WRITE_REG(sc, ISES_A_IQD, ises_bf_fw[p]);
+ if (READ_REG(sc, ISES_A_IQF) < 4)
+ DELAY(10);
+ }
+
+ /* Write firmware CRC */
+ WRITE_REG(sc, ISES_A_IQD, ISES_BF_IDPCRC);
+
+ /* Wait 1s while chip resets and runs selftests */
+ break;
+
+ case 6:
+ /* Did the download succed? */
+ if (READ_REG(sc, ISES_A_STAT) & ISES_STAT_HW_DA) {
+ ticks = 1;
+ break;
+ }
+
+ /* We failed. We cannot do anything else. */
+ printf ("%s: firmware download failed\n", dv);
+ return;
+
+ case 7:
+ if (ises_assert_cmd_mode(sc) < 0)
+ goto fail;
+
+ /*
+ * Now that the basic functionality firmware should be
+ * up and running, try to get the firmware version.
+ */
+
+ stat = ises_get_fwversion(sc);
+ if (stat == 0)
+ goto fail;
+
+ printf("%s: firmware v%d.%d loaded (%d bytes)", dv,
+ stat & 0xffff, (stat >> 16) & 0xffff,
+ ISES_BF_IDPLEN << 2);
+
+ /* We can use firmware version 1.x & 2.x */
+ switch (stat & 0xffff) {
+ case 0:
+ printf (" diagnostic, %s disabled\n", dv);
+ goto fail;
+ case 1: /* Basic Func "base" firmware */
+ case 2: /* Basic Func "ipsec" firmware, no ADP code */
+ break;
+ default:
+ printf(" unknown, %s disabled\n", dv);
+ goto fail;
+ }
+
+ stat = READ_REG(sc, ISES_A_STAT);
+ DPRINTF((", mode %s",
+ ises_sw_mode[ISES_STAT_SW_MODE(stat)]));
+
+ /* Reuse the timeout for HRNG entropy collection. */
+ timeout_del (&sc->sc_timeout);
+ ises_hrng_init (sc);
+
+ /* Set the interrupt mask */
+ sc->sc_intrmask =
+ ISES_STAT_BCHU_OAF | ISES_STAT_BCHU_ERR |
+ ISES_STAT_BCHU_OFHF | ISES_STAT_SW_OQSINC;
+#if 0
+ ISES_STAT_BCHU_ERR | ISES_STAT_BCHU_OAF |
+ ISES_STAT_BCHU_IFE | ISES_STAT_BCHU_IFHE |
+ ISES_STAT_BCHU_OFHF | ISES_STAT_BCHU_OFF;
+#endif
+
+ WRITE_REG(sc, ISES_A_INTE, sc->sc_intrmask);
+
+ /* We're done. */
+ printf("\n");
+
+ /* Register ourselves with crypto framework. */
+#ifdef notyet
+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC,
+ ises_newsession, ises_freesession,
+ ises_process);
+ crypto_register(sc->sc_cid, CRYPTO_DES_CBC,
+ NULL, NULL, NULL);
+ crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC,
+ NULL, NULL, NULL);
+ crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC,
+ NULL, NULL, NULL);
+ crypto_register(sc->sc_cid, CRYPTO_RIPEMD160_HMAC,
+ NULL, NULL, NULL);
+#endif
+
+ return;
+
+ default:
+ printf ("%s: entered unknown initstate %d\n", dv,
+ sc->sc_initstate);
+ goto fail;
+ }
+
+ /* Increment state counter and schedule next step in 'ticks' ticks. */
+ sc->sc_initstate++;
+ timeout_add (&sc->sc_timeout, ticks);
+ return;
+
+ fail:
+ printf ("%s: firmware failure\n", dv);
+ timeout_del (&sc->sc_timeout);
+ return;
+}
+
+/* Put a command on the A-interface queue. */
+int
+ises_queue_cmd(struct ises_softc *sc, u_int32_t cmd, u_int32_t *data)
+{
+ int p, len, s;
+
+ len = cmd >> 24;
+
+ s = splimp();
+
+ if (len > READ_REG(sc, ISES_A_IQF)) {
+ splx(s);
+ return (EAGAIN); /* XXX ENOMEM ? */
+ }
+
+ WRITE_REG(sc, ISES_A_IQD, cmd);
+
+ for (p = 0; p < len; p++)
+ WRITE_REG(sc, ISES_A_IQD, *(data + p));
+
+ WRITE_REG(sc, ISES_A_IQS, 0);
+
+ splx(s);
+ return (0);
+}
+
+/* Process all completed responses in the output queue. */
+void
+ises_process_oqueue(struct ises_softc *sc)
+{
+#ifdef ISESDEBUG
+ char *dv = sc->sc_dv.dv_xname;
+#endif
+ u_int32_t oqs, r, d;
+ int cmd, len;
+
+ /* OQS gives us the number of responses we have to process. */
+ while ((oqs = READ_REG(sc, ISES_A_OQS)) > 0) {
+ /* Read command response. [ len(8) | cmd(8) | rc(16) ] */
+ r = READ_REG(sc, ISES_A_OQD);
+ len = (r >> 24);
+ cmd = (r >> 16) & 0xff;
+ r = r & 0xffff;
+
+ if (r) {
+ /* This command generated an error */
+ DPRINTF(("%s: cmd %d error %d\n", dv, cmd,
+ (r & ISES_RC_MASK)));
+ } else
+ switch (cmd) {
+ case ISES_CMD_HBITS:
+ /* XXX How about increasing the pool size? */
+ /* XXX Use add_entropy_words instead? */
+ /* XXX ... at proper spl */
+ /* Cmd generated by ises_rng() via timeouts */
+ while (len--) {
+ d = READ_REG(sc, ISES_A_OQD);
+ add_true_randomness(d);
+ }
+ break;
+
+ case ISES_CMD_BR_OMR:
+ sc->sc_omr = READ_REG(sc, ISES_A_OQD);
+ DPRINTF(("%s: read sc->sc_omr [%08x]\n", dv,
+ sc->sc_omr));
+ break;
+
+ default:
+ /* All other are ok (no response data) */
+ }
+
+ /* This will drain any remaining data and ACK this reponse. */
+ while (len-- > 0)
+ d = READ_REG(sc, ISES_A_OQD);
+ WRITE_REG(sc, ISES_A_OQS, 0);
+ if (oqs > 1)
+ DELAY(1); /* Wait for firmware to decrement OQS (8 clocks) */
+ }
+}
+
+int
+ises_intr(void *arg)
+{
+ struct ises_softc *sc = arg;
+ volatile u_int32_t ints;
+
+ ints = READ_REG(sc, ISES_A_INTS);
+ if (!(ints & sc->sc_intrmask))
+ return (0); /* Not our interrupt. */
+
+ WRITE_REG(sc, ISES_A_INTS, ints); /* Clear all set intr bits. */
+
+#if 0
+ /* Check it we've got room for more data. */
+ if (READ_REG(sc, ISES_A_STAT) &
+ (ISES_STAT_BCHU_IFE | ISES_STAT_BCHU_IFHE))
+ ises_feed(sc);
+#endif
+
+ if (ints & ISES_STAT_SW_OQSINC) { /* A-intf output q has data */
+ ises_process_oqueue(sc);
+ }
+
+ if (ints & ISES_STAT_BCHU_OAF) { /* output data available */
+ DPRINTF(("ises_intr: BCHU_OAF bit set\n"));
+ /* ises_process_oqueue(sc); */
+ }
+
+ if (ints & ISES_STAT_BCHU_ERR) { /* We got a BCHU error */
+ DPRINTF(("ises_intr: BCHU error\n"));
+ /* XXX Error handling */
+ }
+
+ if (ints & ISES_STAT_BCHU_OFHF) { /* Output is half full */
+ DPRINTF(("ises_intr: BCHU output FIFO half full\n"));
+ /* XXX drain data? */
+ }
+
+#if 0 /* XXX Useful? */
+ if (ints & ISES_STAT_BCHU_OFF) { /* Output is full */
+ /* XXX drain data / error handling? */
+ }
+#endif
+ return (1);
+}
+
+int
+ises_feed(struct ises_softc *sc)
+{
+ struct ises_q *q;
+
+ while (!SIMPLEQ_EMPTY(&sc->sc_queue)) {
+ if (READ_REG(sc, ISES_A_STAT) & ISES_STAT_BCHU_IFF)
+ break;
+ q = SIMPLEQ_FIRST(&sc->sc_queue);
+#if 0
+ WRITE_REG(sc, ISES_OFFSET_BCHU_DATA,
+ (u_int32_t)vtophys(&q->q_mcr));
+ printf("feed: q->chip %08x %08x\n", q,
+ (u_int32_t)vtophys(&q->q_mcr));
+#endif
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q, q_next);
+ --sc->sc_nqueue;
+ SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
+ }
+ return (0);
+}
+
+/*
+ * Allocate a new 'session' and return an encoded session id. 'sidp'
+ * contains our registration id, and should contain an encoded session
+ * id on successful allocation.
+ */
+int
+ises_newsession(u_int32_t *sidp, struct cryptoini *cri)
+{
+ struct cryptoini *c, *mac = NULL, *enc = NULL;
+ struct ises_softc *sc = NULL;
+ struct ises_session *ses = NULL;
+ MD5_CTX md5ctx;
+ SHA1_CTX sha1ctx;
+ RMD160_CTX rmd160ctx;
+ int i, sesn;
+
+ if (sidp == NULL || cri == NULL)
+ return (EINVAL);
+
+ for (i = 0; i < ises_cd.cd_ndevs; i++) {
+ sc = ises_cd.cd_devs[i];
+ if (sc == NULL || sc->sc_cid == (*sidp))
+ break;
+ }
+ if (sc == NULL)
+ return (EINVAL);
+
+ for (c = cri; c != NULL; c = c->cri_next) {
+ if (c->cri_alg == CRYPTO_MD5_HMAC ||
+ c->cri_alg == CRYPTO_SHA1_HMAC ||
+ c->cri_alg == CRYPTO_RIPEMD160_HMAC) {
+ if (mac)
+ return (EINVAL);
+ mac = c;
+ } else if (c->cri_alg == CRYPTO_DES_CBC ||
+ c->cri_alg == CRYPTO_3DES_CBC) {
+ if (enc)
+ return (EINVAL);
+ enc = c;
+ } else
+ return (EINVAL);
+ }
+ if (mac == 0 && enc == 0)
+ return (EINVAL);
+
+ if (sc->sc_sessions == NULL) {
+ ses = sc->sc_sessions = (struct ises_session *)
+ malloc(sizeof(struct ises_session), M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ sesn = 0;
+ sc->sc_nsessions = 1;
+ } else {
+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++)
+ if (sc->sc_sessions[sesn].ses_used == 0) {
+ ses = &sc->sc_sessions[sesn];
+ break;
+ }
+
+ if (ses == NULL) {
+ i = sc->sc_nsessions * sizeof (struct ises_session);
+ ses = (struct ises_session *)
+ malloc(i + sizeof (struct ises_session), M_DEVBUF,
+ M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+
+ memcpy(ses, sc->sc_sessions, i);
+ memset(sc->sc_sessions, 0, i);
+ free(sc->sc_sessions, M_DEVBUF);
+ sc->sc_sessions = ses;
+ ses = &sc->sc_sessions[sc->sc_nsessions];
+ sc->sc_nsessions++;
+ }
+ }
+
+ memset(ses, 0, sizeof (struct ises_session));
+ ses->ses_used = 1;
+
+ if (enc) {
+ /* get an IV, network byte order */
+ /* XXX switch to using builtin HRNG ! */
+ get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv));
+
+ /* crypto key */
+ if (c->cri_alg == CRYPTO_DES_CBC) {
+ memcpy(&ses->ses_deskey[0], enc->cri_key, 8);
+ memcpy(&ses->ses_deskey[2], enc->cri_key, 8);
+ memcpy(&ses->ses_deskey[4], enc->cri_key, 8);
+ } else
+ memcpy(&ses->ses_deskey[0], enc->cri_key, 24);
+
+ SWAP32(ses->ses_deskey[0]);
+ SWAP32(ses->ses_deskey[1]);
+ SWAP32(ses->ses_deskey[2]);
+ SWAP32(ses->ses_deskey[3]);
+ SWAP32(ses->ses_deskey[4]);
+ SWAP32(ses->ses_deskey[5]);
+ }
+
+ if (mac) {
+ for (i = 0; i < mac->cri_klen / 8; i++)
+ mac->cri_key[i] ^= HMAC_IPAD_VAL;
+
+ if (mac->cri_alg == CRYPTO_MD5_HMAC) {
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, mac->cri_key, mac->cri_klen / 8);
+ MD5Update(&md5ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN -
+ (mac->cri_klen / 8));
+ memcpy(ses->ses_hminner, md5ctx.state,
+ sizeof(md5ctx.state));
+ } else if (mac->cri_alg == CRYPTO_SHA1_HMAC) {
+ SHA1Init(&sha1ctx);
+ SHA1Update(&sha1ctx, mac->cri_key, mac->cri_klen / 8);
+ SHA1Update(&sha1ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN -
+ (mac->cri_klen / 8));
+ memcpy(ses->ses_hminner, sha1ctx.state,
+ sizeof(sha1ctx.state));
+ } else {
+ RMD160Init(&rmd160ctx);
+ RMD160Update(&rmd160ctx, mac->cri_key,
+ mac->cri_klen / 8);
+ RMD160Update(&rmd160ctx, hmac_ipad_buffer,
+ HMAC_BLOCK_LEN - (mac->cri_klen / 8));
+ memcpy(ses->ses_hminner, rmd160ctx.state,
+ sizeof(rmd160ctx.state));
+ }
+
+ for (i = 0; i < mac->cri_klen / 8; i++)
+ mac->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
+
+ if (mac->cri_alg == CRYPTO_MD5_HMAC) {
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, mac->cri_key, mac->cri_klen / 8);
+ MD5Update(&md5ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN -
+ (mac->cri_klen / 8));
+ memcpy(ses->ses_hmouter, md5ctx.state,
+ sizeof(md5ctx.state));
+ } else if (mac->cri_alg == CRYPTO_SHA1_HMAC) {
+ SHA1Init(&sha1ctx);
+ SHA1Update(&sha1ctx, mac->cri_key, mac->cri_klen / 8);
+ SHA1Update(&sha1ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN -
+ (mac->cri_klen / 8));
+ memcpy(ses->ses_hmouter, sha1ctx.state,
+ sizeof(sha1ctx.state));
+ } else {
+ RMD160Init(&rmd160ctx);
+ RMD160Update(&rmd160ctx, mac->cri_key,
+ mac->cri_klen / 8);
+ RMD160Update(&rmd160ctx, hmac_ipad_buffer,
+ HMAC_BLOCK_LEN - (mac->cri_klen / 8));
+ memcpy(ses->ses_hmouter, rmd160ctx.state,
+ sizeof(rmd160ctx.state));
+ }
+
+ for (i = 0; i < mac->cri_klen / 8; i++)
+ mac->cri_key[i] ^= HMAC_OPAD_VAL;
+ }
+
+ *sidp = ISES_SID(sc->sc_dv.dv_unit, sesn);
+ return (0);
+}
+
+/*
+ * Deallocate a session.
+ */
+int
+ises_freesession(u_int64_t tsid)
+{
+ struct ises_softc *sc;
+ int card, sesn;
+ u_int32_t sid = ((u_int32_t) tsid) & 0xffffffff;
+
+ card = ISES_CARD(sid);
+ if (card >= ises_cd.cd_ndevs || ises_cd.cd_devs[card] == NULL)
+ return (EINVAL);
+
+ sc = ises_cd.cd_devs[card];
+ sesn = ISES_SESSION(sid);
+ memset(&sc->sc_sessions[sesn], 0, sizeof(sc->sc_sessions[sesn]));
+
+ return (0);
+}
+
+int
+ises_process(struct cryptop *crp)
+{
+ int card, err;
+ struct ises_softc *sc;
+ struct ises_q *q;
+ struct cryptodesc *maccrd, *enccrd, *crd;
+ struct ises_session *ses;
+#if 0
+ int s, i, j;
+#else
+ int s;
+#endif
+ int encoffset = 0, macoffset = 0;
+ int sskip, stheend, dtheend, cpskip, cpoffset, dskip, nicealign;
+ int16_t coffset;
+
+ if (crp == NULL || crp->crp_callback == NULL)
+ return (EINVAL);
+
+ card = ISES_CARD(crp->crp_sid);
+ if (card >= ises_cd.cd_ndevs || ises_cd.cd_devs[card] == NULL) {
+ err = EINVAL;
+ goto errout;
+ }
+
+ sc = ises_cd.cd_devs[card];
+
+ s = splnet();
+ if (sc->sc_nqueue == ISES_MAX_NQUEUE) {
+ splx(s);
+ err = ENOMEM;
+ goto errout;
+ }
+ splx(s);
+
+ q = (struct ises_q *)malloc(sizeof(struct ises_q), M_DEVBUF, M_NOWAIT);
+ if (q == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+ memset(q, 0, sizeof(struct ises_q));
+
+ q->q_sesn = ISES_SESSION(crp->crp_sid);
+ ses = &sc->sc_sessions[q->q_sesn];
+
+ /* XXX */
+
+ q->q_sc = sc;
+ q->q_crp = crp;
+
+ if (crp->crp_flags & CRYPTO_F_IMBUF) {
+ q->q_src_m = (struct mbuf *)crp->crp_buf;
+ q->q_dst_m = (struct mbuf *)crp->crp_buf;
+ } else {
+ err = EINVAL;
+ goto errout;
+ }
+
+ /*
+ * Check if the crypto descriptors are sane. We accept:
+ * - just one crd; either auth or crypto
+ * - two crds; must be one auth and one crypto, although now
+ * for encryption we only want the first to be crypto, while
+ * for decryption the second one should be crypto.
+ */
+ maccrd = enccrd = NULL;
+ err = EINVAL;
+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
+ switch (crd->crd_alg) {
+ case CRYPTO_MD5_HMAC:
+ case CRYPTO_SHA1_HMAC:
+ case CRYPTO_RIPEMD160_HMAC:
+ if (maccrd || (enccrd &&
+ (enccrd->crd_flags & CRD_F_ENCRYPT) == 0))
+ goto errout;
+ maccrd = crd;
+ break;
+ case CRYPTO_DES_CBC:
+ case CRYPTO_3DES_CBC:
+ if (enccrd ||
+ (maccrd && (crd->crd_flags & CRD_F_ENCRYPT)))
+ goto errout;
+ enccrd = crd;
+ break;
+ default:
+ goto errout;
+ }
+ }
+ if (!maccrd && !enccrd)
+ goto errout;
+ err = 0;
+
+ if (enccrd) {
+ encoffset = enccrd->crd_skip;
+
+ if (enccrd->crd_alg == CRYPTO_3DES_CBC)
+ q->q_ctx.pc_omrflags |= ISES_SOMR_BOMR_3DES;
+ else
+ q->q_ctx.pc_omrflags |= ISES_SOMR_BOMR_DES;
+ q->q_ctx.pc_omrflags |= ISES_SOMR_FMR_CBC;
+
+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
+ q->q_ctx.pc_omrflags |= ISES_SOMR_EDR; /* XXX */
+
+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
+ bcopy(enccrd->crd_iv, q->q_ctx.pc_iv, 8);
+ else {
+ q->q_ctx.pc_iv[0] = ses->ses_iv[0];
+ q->q_ctx.pc_iv[1] = ses->ses_iv[1];
+ }
+
+ if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
+ m_copyback(q->q_src_m, enccrd->crd_inject,
+ 8, (caddr_t)q->q_ctx.pc_iv);
+ } else {
+ q->q_ctx.pc_omrflags &= ~ISES_SOMR_EDR; /* XXX */
+
+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
+ bcopy(enccrd->crd_iv, q->q_ctx.pc_iv, 8);
+ else
+ m_copyback(q->q_src_m, enccrd->crd_inject,
+ 8, (caddr_t)q->q_ctx.pc_iv);
+ }
+
+ q->q_ctx.pc_deskey[0] = ses->ses_deskey[0];
+ q->q_ctx.pc_deskey[1] = ses->ses_deskey[1];
+ q->q_ctx.pc_deskey[2] = ses->ses_deskey[2];
+ q->q_ctx.pc_deskey[3] = ses->ses_deskey[3];
+ q->q_ctx.pc_deskey[4] = ses->ses_deskey[4];
+ q->q_ctx.pc_deskey[5] = ses->ses_deskey[5];
+
+ SWAP32(q->q_ctx.pc_iv[0]);
+ SWAP32(q->q_ctx.pc_iv[1]);
+ }
+
+ if (maccrd) {
+ macoffset = maccrd->crd_skip;
+
+ switch (crd->crd_alg) {
+ case CRYPTO_MD5_HMAC:
+ q->q_ctx.pc_omrflags |= ISES_HOMR_HFR_MD5;
+ break;
+ case CRYPTO_SHA1_HMAC:
+ q->q_ctx.pc_omrflags |= ISES_HOMR_HFR_SHA1;
+ break;
+ case CRYPTO_RIPEMD160_HMAC:
+ default:
+ q->q_ctx.pc_omrflags |= ISES_HOMR_HFR_RMD160;
+ break;
+ }
+
+ q->q_ctx.pc_hminner[0] = ses->ses_hminner[0];
+ q->q_ctx.pc_hminner[1] = ses->ses_hminner[1];
+ q->q_ctx.pc_hminner[2] = ses->ses_hminner[2];
+ q->q_ctx.pc_hminner[3] = ses->ses_hminner[3];
+ q->q_ctx.pc_hminner[4] = ses->ses_hminner[4];
+ q->q_ctx.pc_hminner[5] = ses->ses_hminner[5];
+
+ q->q_ctx.pc_hmouter[0] = ses->ses_hmouter[0];
+ q->q_ctx.pc_hmouter[1] = ses->ses_hmouter[1];
+ q->q_ctx.pc_hmouter[2] = ses->ses_hmouter[2];
+ q->q_ctx.pc_hmouter[3] = ses->ses_hmouter[3];
+ q->q_ctx.pc_hmouter[4] = ses->ses_hmouter[4];
+ q->q_ctx.pc_hmouter[5] = ses->ses_hmouter[5];
+ }
+
+ if (enccrd && maccrd) {
+ /* XXX Check if ises handles differing end of auth/enc etc */
+ /* XXX For now, assume not (same as ubsec). */
+ if (((encoffset + enccrd->crd_len) !=
+ (macoffset + maccrd->crd_len)) ||
+ (enccrd->crd_skip < maccrd->crd_skip)) {
+ err = EINVAL;
+ goto errout;
+ }
+
+ sskip = maccrd->crd_skip;
+ cpskip = dskip = enccrd->crd_skip;
+ stheend = maccrd->crd_len;
+ dtheend = enccrd->crd_len;
+ coffset = cpskip - sskip;
+ cpoffset = cpskip + dtheend;
+ /* XXX DEBUG ? */
+ } else {
+ cpskip = dskip = sskip = macoffset + encoffset;
+ dtheend = enccrd ? enccrd->crd_len : maccrd->crd_len;
+ stheend = dtheend;
+ cpoffset = cpskip + dtheend;
+ coffset = 0;
+ }
+ q->q_ctx.pc_offset = coffset >> 2;
+
+ q->q_src_l = mbuf2pages (q->q_src_m, &q->q_src_npa, &q->q_src_packp,
+ &q->q_src_packl, 1, &nicealign);
+ if (q->q_src_l == 0) {
+ err = ENOMEM;
+ goto errout;
+ }
+
+ /* XXX mcr stuff; q->q_mcr->mcr_pktlen = stheend; */
+
+#if 0 /* XXX */
+ for (i = j = 0; i < q->q_src_npa; i++) {
+ struct ises_pktbuf *pb;
+
+ /* XXX DEBUG? */
+
+ if (sskip) {
+ if (sskip >= q->q_src_packl) {
+ sskip -= q->q_src_packl;
+ continue;
+ }
+ q->q_src_packp += sskip;
+ q->q_src_packl -= sskip;
+ sskip = 0;
+ }
+
+ pb = NULL; /* XXX initial packet */
+
+ pb->pb_addr = q->q_src_packp;
+ if (stheend) {
+ if (q->q_src_packl > stheend) {
+ pb->pb_len = stheend;
+ stheend = 0;
+ } else {
+ pb->pb_len = q->q_src_packl;
+ stheend -= pb->pb_len;
+ }
+ } else
+ pb->pb_len = q->q_src_packl;
+
+ if ((i + 1) == q->q_src_npa)
+ pb->pb_next = 0;
+ else
+ pb->pb_next = vtophys(&q->q_srcpkt);
+
+ j++;
+ }
+
+#endif /* XXX */
+ /* XXX DEBUG ? */
+
+ if (enccrd == NULL && maccrd != NULL) {
+ /* XXX mcr stuff */
+ } else {
+ if (!nicealign) {
+ int totlen, len;
+ struct mbuf *m, *top, **mp;
+
+ totlen = q->q_dst_l = q->q_src_l;
+ if (q->q_src_m->m_flags & M_PKTHDR) {
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ M_COPY_PKTHDR(m, q->q_src_m);
+ len = MHLEN;
+ } else {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ len = MLEN;
+ }
+ if (m == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+ if (totlen >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ len = MCLBYTES;
+ }
+ m->m_len = len;
+ top = NULL;
+ mp = &top;
+
+ while (totlen > 0) {
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ m_freem(top);
+ err = ENOMEM;
+ goto errout;
+ }
+ len = MLEN;
+ }
+ if (top && totlen >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ len = MCLBYTES;
+ }
+ m->m_len = len = min(totlen, len);
+ totlen -= len;
+ *mp = m;
+
+ mp = &m->m_next;
+ }
+ q->q_dst_m = top;
+ ubsec_mcopy(q->q_src_m, q->q_dst_m, cpskip, cpoffset);
+ } else
+ q->q_dst_m = q->q_src_m;
+
+ q->q_dst_l = mbuf2pages(q->q_dst_m, &q->q_dst_npa,
+ &q->q_dst_packp, &q->q_dst_packl,
+ 1, NULL);
+
+#if 0
+ for (i = j = 0; i < q->q_dst_npa; i++) {
+ struct ises_pktbuf *pb;
+
+ if (dskip) {
+ if (dskip >= q->q_dst_packl[i]) {
+ dskip -= q->q_dst_packl[i];
+ continue;
+ }
+ q->q_dst_packp[i] += dskip;
+ q->q_dst_packl[i] -= dskip;
+ dskip = 0;
+ }
+
+ if (j == 0)
+ pb = NULL; /* &q->q_mcr->mcr_opktbuf; */
+ else
+ pb = &q->q_dstpkt[j - 1];
+
+ pb->pb_addr = q->q_dst_packp[i];
+
+ if (dtheend) {
+ if (q->q_dst_packl[i] > dtheend) {
+ pb->pb_len = dtheend;
+ dtheend = 0;
+ } else {
+ pb->pb_len = q->q_dst_packl[i];
+ dtheend -= pb->pb_len;
+ }
+ } else
+ pb->pb_len = q->q_dst_packl[i];
+
+ if ((i + 1) == q->q_dst_npa) {
+ if (maccrd)
+ pb->pb_next = vtophys(q->q_macbuf);
+ else
+ pb->pb_next = 0;
+ } else
+ pb->pb_next = vtophys(&q->q_dstpkt[j]);
+ j++;
+ }
+#endif
+ }
+
+ s = splnet();
+ SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next);
+ sc->sc_nqueue++;
+ ises_feed(sc);
+ splx(s);
+
+ return (0);
+
+errout:
+ if (q) {
+ if (q->q_src_m != q->q_dst_m)
+ m_freem(q->q_dst_m);
+ free(q, M_DEVBUF);
+ }
+ crp->crp_etype = err;
+ crp->crp_callback(crp);
+ return (0);
+}
+
+void
+ises_callback(struct ises_q *q)
+{
+ struct cryptop *crp = (struct cryptop *)q->q_crp;
+ struct cryptodesc *crd;
+
+ if ((crp->crp_flags & CRYPTO_F_IMBUF) && (q->q_src_m != q->q_dst_m)) {
+ m_freem(q->q_src_m);
+ crp->crp_buf = (caddr_t)q->q_dst_m;
+ }
+
+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
+ if (crd->crd_alg != CRYPTO_MD5_HMAC &&
+ crd->crd_alg != CRYPTO_SHA1_HMAC &&
+ crd->crd_alg != CRYPTO_RIPEMD160_HMAC)
+ continue;
+ m_copyback((struct mbuf *)crp->crp_buf,
+ crd->crd_inject, 12, (u_int8_t *)&q->q_macbuf[0]);
+ break;
+ }
+
+ free(q, M_DEVBUF);
+ crypto_done(crp);
+}
+
+/* Initilize the ISES hardware RNG, and set up timeouts. */
+void
+ises_hrng_init(struct ises_softc *sc)
+{
+ u_int32_t cmd, r;
+ int i;
+#ifdef ISESDEBUG
+ struct timeval tv1, tv2;
+#endif
+
+ /* Asking for random data will seed LFSR and start the RBG */
+ cmd = ISES_MKCMD(ISES_CMD_HBITS, 1);
+ r = 8; /* 8 * 32 = 256 bits */
+
+ if (ises_queue_cmd(sc, cmd, &r))
+ return;
+
+ /* Wait until response arrives. */
+ for (i = 1000; i && READ_REG(sc, ISES_A_OQS) == 0; i--)
+ DELAY(10);
+
+ if (!READ_REG(sc, ISES_A_OQS))
+ return;
+
+ /* Drain cmd response and 8*32 bits data */
+ for (i = 0; i <= r; i++)
+ (void)READ_REG(sc, ISES_A_OQD);
+
+ /* ACK the response */
+ WRITE_REG(sc, ISES_A_OQS, 0);
+ DELAY(1);
+ printf(", rng active", sc->sc_dv.dv_xname);
+
+#ifdef ISESDEBUG
+ /* Benchmark the HRNG. */
+
+ /*
+ * XXX These values gets surprisingly large. Docs state the
+ * HNRG produces > 1 mbit/s of random data. The values I'm seeing
+ * are much higher, ca 2.7-2.8 mbit/s. AFAICT the algorithm is sound.
+ * Compiler optimization issues, perhaps?
+ */
+
+#define ISES_WPR 250
+#define ISES_ROUNDS 100
+ cmd = ISES_MKCMD(ISES_CMD_HBITS, 1);
+ r = ISES_WPR;
+
+ /* Queue 100 cmds; each generate 250 32-bit words of rnd data. */
+ microtime(&tv1);
+ for (i = 0; i < ISES_ROUNDS; i++)
+ ises_queue_cmd(sc, cmd, &r);
+ for (i = 0; i < ISES_ROUNDS; i++) {
+ while (READ_REG(sc, ISES_A_OQS) == 0) ; /* Wait for response */
+
+ (void)READ_REG(sc, ISES_A_OQD); /* read response */
+ for (r = ISES_WPR; r--;)
+ (void)READ_REG(sc, ISES_A_OQD); /* read data */
+ WRITE_REG(sc, ISES_A_OQS, 0); /* ACK resp */
+ DELAY(1); /* OQS needs 1us to decrement */
+ }
+ microtime(&tv2);
+
+ timersub(&tv2, &tv1, &tv1);
+ tv1.tv_usec += 1000000 * tv1.tv_sec;
+ printf(", %dKb/sec",
+ ISES_WPR * ISES_ROUNDS * 32 / 1024 * 1000000 / tv1.tv_usec);
+#endif
+
+ printf ("\n");
+ timeout_set(&sc->sc_timeout, ises_hrng, sc);
+ ises_hrng(sc); /* Call first update */
+}
+
+/* Called by timeout (and once by ises_init_hrng()). */
+void
+ises_hrng(void *v)
+{
+ /*
+ * Throw a HRNG read random bits command on the command queue.
+ * The normal loop will manage the result and add it to the pool.
+ */
+ struct ises_softc *sc = v;
+ u_int32_t cmd, n;
+ extern int hz; /* from param.c */
+
+ /* XXX How often should we repeat? */
+ timeout_add(&sc->sc_timeout, hz/ISESRNGIPS);
+
+ if (ises_assert_cmd_mode(sc) != 0)
+ return;
+
+ cmd = ISES_MKCMD(ISES_CMD_HBITS, 1);
+ n = (ISESRNGBITS >> 5) & 0xff; /* ask for N 32 bit words */
+
+ ises_queue_cmd(sc, cmd, &n);
+}
+
+u_int32_t
+ises_get_fwversion(struct ises_softc *sc)
+{
+ u_int32_t r;
+ int i;
+
+ r = ISES_MKCMD(ISES_CMD_CHIP_ID, 0);
+ WRITE_REG(sc, ISES_A_IQD, r);
+ WRITE_REG(sc, ISES_A_IQS, 0);
+
+ for (i = 100; i > 0 && READ_REG(sc, ISES_A_OQS) == 0; i--)
+ DELAY(1);
+
+ if (i < 1)
+ return (0); /* No response */
+
+ r = READ_REG(sc, ISES_A_OQD);
+
+ /* Check validity. On error drain reponse data. */
+ if (((r >> 16) & 0xff) != ISES_CMD_CHIP_ID ||
+ ((r >> 24) & 0xff) != 3 || (r & ISES_RC_MASK) != ISES_RC_SUCCESS) {
+ if ((r & ISES_RC_MASK) == ISES_RC_SUCCESS)
+ for (i = ((r >> 24) & 0xff); i; i--)
+ (void) READ_REG(sc, ISES_A_OQD);
+ r = 0;
+ goto out;
+ }
+
+ r = READ_REG(sc, ISES_A_OQD); /* read version */
+ (void) READ_REG (sc, ISES_A_OQD); /* Discard 64bit "chip-id" */
+ (void) READ_REG (sc, ISES_A_OQD);
+ out:
+ WRITE_REG(sc, ISES_A_OQS, 0); /* Ack the response */
+ DELAY(1);
+ return (r);
+}
+
+/*
+ * ises_assert_cmd_mode() returns
+ * -1 for failure to go to cmd
+ * 0 if mode already was cmd
+ * >0 if mode was other (WFC/WFR) but now is cmd (this has reset the queues)
+ */
+int
+ises_assert_cmd_mode(struct ises_softc *sc)
+{
+ switch (ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT))) {
+ case 0x0: /* Selftest. XXX This is a transient state. */
+ DELAY(1000000);
+ if (ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT)) == 0)
+ return (-1);
+ return (ises_assert_cmd_mode(sc));
+ case 0x1: /* Command mode */
+ return (0);
+ case 0x2: /* Waiting For Continue / WFC */
+ bus_space_write_2(sc->sc_memt, sc->sc_memh, ISES_A_CTRL,
+ ISES_A_CTRL_CONTINUE);
+ DELAY(1);
+ return ((ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT)) == 0) ? 1 : -1);
+ case 0x3: /* Waiting For Reset / WFR */
+ bus_space_write_2(sc->sc_memt, sc->sc_memh, ISES_A_CTRL,
+ ISES_A_CTRL_RESET);
+ DELAY(1000000);
+ return ((ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT)) == 0) ? 2 : -1);
+ default:
+ return (-1); /* Unknown mode */
+ }
+}
+
diff --git a/sys/dev/pci/isesreg.h b/sys/dev/pci/isesreg.h
new file mode 100644
index 00000000000..e49bea9a676
--- /dev/null
+++ b/sys/dev/pci/isesreg.h
@@ -0,0 +1,645 @@
+/* $OpenBSD: isesreg.h,v 1.1 2001/01/29 08:45:58 ho Exp $ $ */
+
+/*
+ * Copyright (c) 2000 Håkan Olsson (ho@crt.se)
+ * Copyright (c) 2000 Theo de Raadt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Register definitions for Pijnenburg PCC-ISES crypto chip.
+ * Definitions from revision 1.6 of the product datasheet.
+ */
+
+/* DMA offsets */
+#define ISES_DMA_WRITE_COUNT 0x0100
+#define ISES_DMA_READ_COUNT 0x0102
+#define ISES_DMA_WRITE_START 0x0104
+#define ISES_DMA_READ_START 0x0108
+#define ISES_DMA_STATUS 0x010c
+
+/*
+ * PCC-ISES A-interface
+ */
+
+#define ISES_A_OFFSET 0x0200
+#define ISES_A(x) (ISES_A_OFFSET + (x))
+
+#define ISES_A_STAT ISES_A(0x00) /* status register */
+#define ISES_A_INTS ISES_A(0x04) /* interupt status register */
+#define ISES_A_INTE ISES_A(0x08) /* interupt enable register */
+#define ISES_A_SREQ ISES_A(0x0C) /* service request (read) */
+#define ISES_A_CTRL ISES_A_SREQ /* control register (write) */
+#define ISES_A_OQD ISES_A(0x10) /* Output Queue Data (read) */
+#define ISES_A_IQD ISES_A_OQD /* Input Queue Data (write) */
+#define ISES_A_OQS ISES_A(0x14) /* Output Queue Semaphore */
+#define ISES_A_IQS ISES_A(0x18) /* Input Queue Semaphore */
+#define ISES_A_OQF ISES_A(0x1C) /* Output Queue Filled (ro) */
+#define ISES_A_IQF ISES_A(0x20) /* Input Queue Free (ro) */
+
+/*
+ * PCC-ISES B-interface
+ */
+
+#define ISES_B_OFFSET 0x0300
+#define ISES_B(x) (ISES_B_OFFSET + (x))
+
+#define ISES_B_BDATAIN ISES_B(0x0)
+#define ISES_B_BDATAOUT ISES_B(0x4)
+#define ISES_B_STAT ISES_B(0x8)
+
+/*
+ * PCC-ISES I-interface (not used)
+ */
+
+#define ISES_I_OFFSET 0x0400
+
+/*
+ * PCC-ISES board registers
+ */
+
+#define ISES_BO_OFFSET 0x0500
+#define ISES_BO(x) (ISES_BO_OFFSET + (x))
+
+#define ISES_BO_STAT ISES_BO(0x0)
+#define ISES_BO_LOOPCOUNTER ISES_BO(0x4)
+#define ISES_BO_TESTREG ISES_BO(0x8)
+
+#define ISES_BO_STAT_LOOP 0x00000001 /* B-interface LoopMode */
+#define ISES_BO_STAT_TAMPER 0x00000002 /* Set tamper */
+#define ISES_BO_STAT_POWERDOWN 0x00000004 /* Set power down */
+#define ISES_BO_STAT_ACONF 0x00000008 /* Set A-intf access to 16b */
+#define ISES_BO_STAT_HWRESET 0x00000010 /* Reset PCC-ISES (hw) */
+#define ISES_BO_STAT_AIRQ 0x00000020 /* A-interface interrupt (ro)*/
+
+/*
+ * PCC-ISES A-interface STAT register bits
+ */
+
+#define ISES_STAT_LNAU_MASKED 0x00000001 /* LNAU flags masked, this bit
+ must be zero for the other
+ LNAU flags to be read
+ correctly. */
+#define ISES_STAT_LNAU_BUSY_1 0x00000002 /* LNAU unit 1 is busy */
+#define ISES_STAT_LNAU_ERR_1 0x00000004 /* LNAU unit 1 error */
+#define ISES_STAT_LNAU_BUSY_2 0x00000008 /* LNAU unit 2 is busy */
+#define ISES_STAT_LNAU_ERR_2 0x00000010 /* LNAU unit 2 error */
+#define ISES_STAT_BCHU_MASKED 0x00000020 /* BCHU flags masked */
+#define ISES_STAT_BCHU_BUSY 0x00000040 /* BCHU is busy */
+#define ISES_STAT_BCHU_ERR 0x00000080 /* BCHU error flag */
+#define ISES_STAT_BCHU_SCIF 0x00000100 /* symm. crypto inoperative */
+#define ISES_STAT_BCHU_HIF 0x00000200 /* hash unit inoperative */
+#define ISES_STAT_BCHU_DDB 0x00000400 /* discard data blocks */
+#define ISES_STAT_BCHU_IRF 0x00000800 /* input request flag */
+#define ISES_STAT_BCHU_OAF 0x00001000 /* output available flag */
+#define ISES_STAT_BCHU_DIE 0x00002000 /* data input enabled */
+#define ISES_STAT_BCHU_UE 0x00004000 /* unit enable bit */
+#define ISES_STAT_BCHU_IFE 0x00008000 /* input FIFO empty */
+#define ISES_STAT_BCHU_IFHE 0x00010000 /* input FIFO half emtpy */
+#define ISES_STAT_BCHU_IFF 0x00020000 /* input FIFO full */
+#define ISES_STAT_BCHU_OFE 0x00040000 /* output FIFO emtpy */
+#define ISES_STAT_BCHU_OFHF 0x00080000 /* output FIFO half full */
+#define ISES_STAT_BCHU_OFF 0x00100000 /* output FIFO full */
+#define ISES_STAT_HW_DA 0x00200000 /* downloaded appl flag */
+#define ISES_STAT_HW_ACONF 0x00400000 /* A-intf configuration flag */
+#define ISES_STAT_SW_WFOQ 0x00800000 /* SW: Waiting for out queue */
+#define ISES_STAT_SW_OQSINC 0x08000000 /* SW 2.x: OQS increased */
+
+#define ISES_STAT_IDP_MASK 0x0f000000 /* IDP state mask (HW_DA=0) */
+#define ISES_STAT_IDP_STATE(x) (((x) & ISES_STAT_IDP_MASK) >> 24)
+
+static const char *ises_idp_state[] =
+{
+ "reset state", /* 0x0 */
+ "testing NSRAM", /* 0x1 */
+ "checking for firmware", /* 0x2 */
+ "clearing NSRAM", /* 0x3 */
+ "waiting for program length", /* 0x4 */
+ "waiting for program data", /* 0x5 */
+ "waiting for program CRC", /* 0x6 */
+ "functional test program", /* 0x7 */
+ 0, 0, 0, 0, 0, 0, 0, /* 0x8-0xe */
+ "Error: NSRAM or firmware failed" /* 0xf */
+};
+
+#define ISES_STAT_SW_MASK 0x03000000 /* SW mode (HW_DA=1) */
+#define ISES_STAT_SW_MODE(x) (((x) & ISES_STAT_SW_MASK) >> 24)
+
+#define ISES_A_CTRL_RESET 0x0000 /* SW reset (go to ST mode) */
+#define ISES_A_CTRL_CONTINUE 0x0001 /* Return to CMD from WFC */
+
+#ifdef ISESDEBUG
+static const char *ises_sw_mode[] =
+{
+ "ST (SelfTest)", /* 0x0 */
+ "CMD", /* 0x1 (normal) */
+ "WFC (Wait for continue)", /* 0x2 */
+ "CMD (Wait for reset)" /* 0x3 */
+};
+#endif
+
+/* BERR (BCHU Error Register) */
+#define ISES_BERR_DPAR 0x00000001 /* DES parity error */
+#define ISES_BERR_IDESBCP 0x00000002 /* illegal DES mode value */
+#define ISES_BERR_ISFRBCP 0x00000004 /* illegal SAFER rounds spec */
+#define ISES_BERR_INCMBCP 0x00000008 /* illegal non-crypto mode */
+#define ISES_BERR_IBCF 0x00000010 /* illegal value in BCFR */
+#define ISES_BERR_reserved 0x00000020 /* reserved */
+#define ISES_BERR_SRB 0x00000040 /* write SCU while busy */
+#define ISES_BERR_HRB 0x00000080 /* write HU while busy */
+#define ISES_BERR_IHFR 0x00000100 /* illegal value in HFR */
+#define ISES_BERR_PADERR 0x00000200 /* padding error */
+#define ISES_BERR_BIDM 0x00000400 /* B-interface input data
+ misalignment */
+/* BCHCR (BCHU Control Register) */
+#define ISES_BCHCR_BCHU_DIE 0x00000001 /* data input enabled */
+#define ISES_BCHCR_BCHU_UE 0x00000002 /* unit enable */
+#define ISES_BCHCR_BCHU_RST 0x00000004 /* BCHU reset */
+
+/*
+ * OMR (Operation Method Register)
+ */
+/* -- SELR (Selector Register) */
+#define ISES_SELR_BCHU_EH 0x80000000 /* stop/continue on error */
+#define ISES_SELR_BCHU_HISOF 0x01000000 /* HU input is SCU output */
+#define ISES_SELR_BCHU_DIS 0x02000000 /* data interface select */
+
+/* -- HOMR (HU Operation Mode Register) */
+#define ISES_HOMR_HMTR 0x00800000 /* hash message type reg bit */
+#define ISES_HOMR_ER 0x00300000 /* BE/LE, 2bit mask */
+
+#define ISES_HOMR_HFR 0x00070000 /* Hash function mask, 3bits */
+#define ISES_HOMR_HFR_NOP 0x00000000 /* NOP */
+#define ISES_HOMR_HFR_MD5 0x00010000 /* MD5 */
+#define ISES_HOMR_HFR_RMD160 0x00020000 /* RIPEMD-160 */
+#define ISES_HOMR_HFR_RMD128 0x00030000 /* RIPEMD-128 */
+#define ISES_HOMR_HFR_SHA1 0x00040000 /* SHA-1 */
+
+/* -- SOMR (Symmetric crypto Operation Method Register) */
+#define ISES_SOMR_BCFR 0x0000f000 /* block cipher function reg */
+#define ISES_SOMR_BCPR 0x00000ff0 /* block cipher parameters */
+#define ISES_SOMR_BOMR (ISES_SOMR_BCFR | ISES_SOMR_BCPR)
+#define ISES_SOMR_BOMR_NOP 0x00000000 /* NOP */
+#define ISES_SOMR_BOMR_TRANSPARENT 0x00000010 /* Transparent */
+#define ISES_SOMR_BOMR_DES 0x00001000 /* DES */
+#define ISES_SOMR_BOMR_3DES2 0x00001010 /* 3DES-2 */
+#define ISES_SOMR_BOMR_3DES 0x00001020 /* 3DES-3 */
+#define ISES_SOMR_BOMR_SAFER 0x00002000 /* SAFER (actually more) */
+#define ISES_SOMR_EDR 0x00000008 /* Encrypt/Decrypt register */
+#define ISES_SOMR_FMR 0x00000003 /* feedback mode mask */
+#define ISES_SOMR_FMR_ECB 0x00000000 /* EBC */
+#define ISES_SOMR_FMR_CBC 0x00000001 /* CBC */
+#define ISES_SOMR_FMR_CFB64 0x00000002 /* CFB64 */
+#define ISES_SOMR_FMR_OFB64 0x00000003 /* OFB64 */
+
+/*
+ * HRNG (Hardware Random Number Generator)
+ */
+#define ISES_OFFSET_HRNG_CTRL 0x00 /* Control register */
+#define ISES_OFFSET_HRNG_LFSR 0x04 /* Linear feedback shift reg */
+#define ISES_HRNG_CTRL_HE 0x00000001 /* HRNG enable */
+
+/*
+ * A-interface commands
+ */
+#define ISES_MKCMD(cmd,len) (cmd | cmd << 16 | len << 8 | len << 24)
+
+/* Command name Code Len RLen Desc */
+#define ISES_CMD_CHIP_ID 0x00 /* 0 3 Read chipID */
+/* LNAU commands */
+#define ISES_CMD_LRESET_1 0x01 /* 0 0 LNAU 1 reset */
+#define ISES_CMD_LRSFLG_1 0x02 /* 0 0 LNAU 1 flags reset */
+#define ISES_CMD_LUPLOAD_1 0x03 /* 0 64 */
+#define ISES_CMD_LW_A_1 0x04 /* ?64 0 */
+#define ISES_CMD_LW_B_1 0x05 /* ?64 0 */
+#define ISES_CMD_LW_N_1 0x06 /* ?64 0 */
+#define ISES_CMD_LW_Bq_1 0x07 /* ?32 0 */
+#define ISES_CMD_LW_Nq_1 0x08 /* ?32 0 */
+#define ISES_CMD_LW_Bp_1 0x09 /* ?34 0 */
+#define ISES_CMD_LW_Np_1 0x0a /* ?34 0 */
+#define ISES_CMD_LW_U_1 0x0b /* ?34 0 */
+#define ISES_CMD_LMOD_1 0x0c /* 0 0 */
+#define ISES_CMD_LMULMOD_1 0x0d /* 0 0 */
+#define ISES_CMD_LEXPMOD_1 0x0e /* 0 0 */
+#define ISES_CMD_LECMOD_1 0x0f /* 0 0 */
+#define ISES_CMD_LRESET_2 0x10 /* 0 0 */
+#define ISES_CMD_LRSFLG_2 0x11 /* 0 0 */
+#define ISES_CMD_LUPLOAD_2 0x12 /* 0 64 */
+#define ISES_CMD_LW_A_2 0x13 /* ?64 0 */
+#define ISES_CMD_LW_B_2 0x14 /* ?64 0 */
+#define ISES_CMD_LW_N_2 0x15 /* ?64 0 */
+#define ISES_CMD_LW_Bq_2 0x16 /* ?32 0 */
+#define ISES_CMD_LW_Nq_2 0x17 /* ?32 0 */
+#define ISES_CMD_LW_Bp_2 0x18 /* ?34 0 */
+#define ISES_CMD_LW_Np_2 0x19 /* ?34 0 */
+#define ISES_CMD_LW_U_2 0x1a /* ?34 0 */
+#define ISES_CMD_LMOD_2 0x1b /* 0 0 */
+#define ISES_CMD_LMULMOD_2 0x1c /* 0 0 */
+#define ISES_CMD_LEXPMOD_2 0x1d /* 0 0 */
+#define ISES_CMD_LECMOD_2 0x1e /* 0 0 */
+/* BCHU commands */
+#define ISES_CMD_RST_BERR 0x1f /* 0 0 Reset BERR */
+#define ISES_CMD_BR_BERR 0x20 /* 0 0 Read BERR */
+#define ISES_CMD_BW_DATA 0x21 /* 2 0 Write DATA */
+#define ISES_CMD_BR_DATA 0x22 /* 0 2 Read DATA */
+#define ISES_CMD_BW_BCHCR 0x23 /* 1 0 Write BCHCR */
+#define ISES_CMD_BR_BCHCR 0x24 /* 0 0 Read BCHCR */
+#define ISES_CMD_BW_OMR 0x25 /* 1 0 Write OMR */
+#define ISES_CMD_BR_OMR 0x26 /* 0 1 Read OMR */
+#define ISES_CMD_BW_KR0 0x27 /* 2 0 Write key 0 */
+#define ISES_CMD_BR_KR0 0x28 /* 0 2 Read key 0 */
+#define ISES_CMD_BW_KR1 0x29 /* 2 0 Write key 1 */
+#define ISES_CMD_BR_KR1 0x2a /* 0 2 Read key 1 */
+#define ISES_CMD_BW_KR2 0x2b /* 2 0 Write key 2 */
+#define ISES_CMD_BR_KR2 0x2c /* 0 2 Read key 2 */
+#define ISES_CMD_BW_SCCR 0x2d /* 2 0 Write SCCR */
+#define ISES_CMD_BR_SCCR 0x2e /* 0 2 Read SCCR */
+#define ISES_CMD_BW_DBCR 0x2f /* 2 0 Write DBCR */
+#define ISES_CMD_BR_DBCR 0x30 /* 0 2 Read DBCR */
+#define ISES_CMD_BW_HMLR 0x31 /* 2 0 Write HMLR */
+#define ISES_CMD_BR_HMLR 0x32 /* 0 2 Read HMLR */
+#define ISES_CMD_BW_CVR 0x33 /* 5 0 Write CVR */
+#define ISES_CMD_BR_CVR 0x34 /* 0 5 Read CVR */
+#define ISES_CMD_BPROC 0x35 /* ?255 ?255 Process data blocks */
+#define ISES_CMD_BTERM 0x36 /* 0 0 Terminate session */
+#define ISES_CMD_BSWITCH 0x37 /* 18 18 Switch BCHU session */
+/* HRNG commands */
+#define ISES_CMD_HSTART 0x38 /* 0 0 Start RBG unit */
+#define ISES_CMD_HSTOP 0x39 /* 0 0 Stop RGB unit */
+#define ISES_CMD_HSEED 0x3a /* 1 0 Seed LFSR */
+#define ISES_CMD_HBITS 0x3b /* 1 ?255 Return n*32 rnd bits */
+
+/* Command return codes (RC) */
+#define ISES_RC_MASK 0x0000ffff
+#define ISES_RC_SUCCESS 0x0000 /* success */
+#define ISES_RC_CMDERR 0x0001 /* cmd interpretation error */
+#define ISES_RC_QERR 0x0002 /* queue handling error */
+#define ISES_RC_LNAU_ERR 0x0003 /* LNAU cmd proc error */
+#define ISES_RC_BCHU_ERR 0x0004 /* BCHU cmd proc error */
+#define ISES_RC_BCHU_BIFCSEL 0x0005 /* OMR says B-if, must be A */
+#define ISES_RC_BCHU_ODD 0x0006 /* odd #words in param list */
+#define ISES_RC_HRNG_ILLEN 0x0007 /* too large bitstream */
+
+/* Interrupt bits, IRQE, IRQES, IRQEC, IRQSS, IRQ registers */
+#define ISES_IRQ_TIMER_1 0x00000001 /* Timer 1 reached zero */
+#define ISES_IRQ_TIMER_2 0x00000002 /* Timer 2 reached zero */
+#define ISES_IRQ_I_IIN0 0x00000004 /* I-int 'Iin0' */
+#define ISES_IRQ_I_IIN1 0x00000008 /* I-int 'Iin1' */
+#define ISES_IRQ_I_IIN2 0x00000010 /* I-int 'Iin2' */
+#define ISES_IRQ_I_IIN3 0x00000020 /* I-int 'Iin3' */
+#define ISES_IRQ_LNAU_1_ERROR 0x00000040 /* LNAU 1 op error/abort */
+#define ISES_IRQ_LNAU_1_DONE 0x00000080 /* LNAU 1 op done */
+#define ISES_IRQ_LNAU_2_ERROR 0x00000100 /* LNAU 2 op error/abort */
+#define ISES_IRQ_LNAU_2_DONE 0x00000200 /* LNAU 1 op done */
+#define ISES_IRQ_BCHU_DONE 0x00000400 /* BCHU operation done */
+#define ISES_IRQ_BCHU_ERROR 0x00000800 /* BCHU operation error/abrt */
+#define ISES_IRQ_BCHU_IRF 0x00001000 /* BCHU input request flag >1*/
+#define ISES_IRQ_BCHU_OAF 0x00002000 /* BCHU output avail flag >1 */
+#define ISES_IRQ_BCHU_IEF 0x00004000 /* BCHU input empty flag >1 */
+#define ISES_IRQ_A_WCTRL 0x00008000 /* A-int CTRL reg was written*/
+#define ISES_IRQ_A_RSREQ 0x00010000 /* A-int SREQ reg was read */
+#define ISES_IRQ_A_DIQ 0x00020000 /* in queue emtpy, IQD write */
+#define ISES_IRQ_A_CIQ 0x00040000 /* in queue has complete cmd */
+#define ISES_IRQ_A_OQF 0x00080000 /* output queue full */
+
+#define ISES_SESSION(sid) ( (sid) & 0x0fffffff)
+#define ISES_CARD(sid) (((sid) & 0xf0000000) >> 28)
+#define ISES_SID(crd,ses) (((crd) << 28) | ((ses) & 0x0fffffff))
+
+struct ises_pktctx {
+ u_int32_t pc_deskey[6]; /* 3DES key */
+ u_int32_t pc_hminner[5]; /* hmac inner state */
+ u_int32_t pc_hmouter[5]; /* hmac outer state */
+ u_int32_t pc_iv[2]; /* [3]DES iv */
+ u_int32_t pc_omrflags; /* OMR flags, as above */
+ u_int32_t pc_paddr;
+ u_int16_t pc_offset; /* crypto offset */
+ u_int8_t pad[16];
+};
+
+struct ises_pktbuf {
+ volatile u_int32_t pb_addr; /* address of buffer start */
+ volatile u_int32_t pb_len; /* packet length */
+};
+
+#define ISES_B_DATASIZE 4096
+struct ises_databuf {
+ u_int8_t data[ISES_B_DATASIZE];
+} __attribute__((packed));
+
+/*
+ * ------------------------------------------
+ * PCC-ISES Basic Functionality firmware v2.0
+ * ------------------------------------------
+ */
+
+/*
+ * Copyright (C) 1999, 2000 Pijnenburg Custom Chips B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that the following conditions are met:
+ * 1. Redistribution of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistribution in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define ISES_BF_IDPLEN 0x00000403 /* Total length, 32bit words */
+#define ISES_BF_IDPCRC 0x59DE7DEF /* Firmware CRC */
+
+static const u_int32_t ises_bf_fw[] = {
+ 0xEA000006, 0xE1A00000, 0xE1A00000, 0xE1A00000,
+ 0xE1A00000, 0xE1A00000, 0xEA000013, 0xEA000026,
+ 0xE59FD0C4, 0xE3A000D2, 0xE121F000, 0xE59FD0BC,
+ 0xE3A000D1, 0xE121F000, 0xE59FD0B0, 0xE3A000D3,
+ 0xE121F000, 0xEB00029B, 0xEAFFFFFE, 0xE10F1000,
+ 0xE1811000, 0xE121F001, 0xE12FFF1E, 0xE10F1000,
+ 0xE1C11000, 0xE121F001, 0xE12FFF1E, 0xE92D0003,
+ 0xE59F107C, 0xE5910004, 0xE5810000, 0xE3100902,
+ 0x0A00000B, 0xE59F106C, 0xE5910000, 0xE3500000,
+ 0x1A000003, 0xE59F1060, 0xE3A00001, 0xE5810000,
+ 0xEA000003, 0xE3500001, 0x1A000001, 0xE59F1038,
+ 0xE5810000, 0xE8BD0003, 0xE25EF004, 0xE25EF004,
+ 0xE3A000D3, 0xE121F000, 0xE59FE030, 0xE3A00000,
+ 0xE3A01032, 0xE48E0004, 0xE2511001, 0x1AFFFFFC,
+ 0xE91E3FFE, 0xE3A0E000, 0xE3A0F000, 0x000017B4,
+ 0x000017DC, 0xFFFFEA00, 0xFFFFE60C, 0xFFFFF000,
+ 0x00001714, 0xE3A01001, 0xE3A00AFE, 0xE2400601,
+ 0xE5A01624, 0xE1A0F00E, 0xE3A00AFE, 0xE2400601,
+ 0xE5901620, 0xE3510000, 0x0AFFFFFC, 0xE5900610,
+ 0xE1A0F00E, 0xE3A02000, 0xE3510000, 0x91A0F00E,
+ 0xE3A03AFE, 0xE2433601, 0xE593C620, 0xE35C0000,
+ 0x0AFFFFFC, 0xE593C610, 0xE2822001, 0xE1520001,
+ 0xE480C004, 0x3AFFFFF7, 0xE1A0F00E, 0xE3A01000,
+ 0xE3A00AFE, 0xE2400601, 0xE5A01618, 0xE1A0F00E,
+ 0xE3A01002, 0xE3A00AFE, 0xE2400601, 0xE5A01624,
+ 0xE1A0F00E, 0xE3A01AFE, 0xE2411601, 0xE591261C,
+ 0xE3520000, 0x1A000006, 0xE3A02506, 0xE5812600,
+ 0xE591261C, 0xE3520000, 0x0AFFFFFC, 0xE3A02401,
+ 0xE5812600, 0xE5A10610, 0xE1A0F00E, 0xE3A03000,
+ 0xE3510000, 0x91A0F00E, 0xE92D4010, 0xE3A0E506,
+ 0xE3A0C401, 0xE3A02AFE, 0xE2422601, 0xE592461C,
+ 0xE3540000, 0x1A000004, 0xE582E600, 0xE592461C,
+ 0xE3540000, 0x0AFFFFFC, 0xE582C600, 0xE4904004,
+ 0xE5824610, 0xE2833001, 0xE1530001, 0x3AFFFFF2,
+ 0xE8BD8010, 0xE3A01000, 0xE3A00AFE, 0xE2400601,
+ 0xE5A01614, 0xE3A00CE6, 0xE2400801, 0xE5901000,
+ 0xE3811302, 0xE5801000, 0xE5901000, 0xE3C11302,
+ 0xE5801000, 0xE1A0F00E, 0xE59F2038, 0xE59F0038,
+ 0xE5901000, 0xE0821181, 0xE5D11006, 0xE20120F0,
+ 0xE3A03BC2, 0xE2433701, 0xE0832402, 0xE5802008,
+ 0xE2822004, 0xE580200C, 0xE2432B02, 0xE0821401,
+ 0xE5A01010, 0xE1A0F00E, 0x00000E00, 0x00001000,
+ 0xE92D4000, 0xEBFFFFB0, 0xE3A01002, 0xE59F0028,
+ 0xE5801000, 0xE3A01AFE, 0xE2411601, 0xE5912204,
+ 0xE5802004, 0xE5911208, 0xE5801008, 0xE3A01003,
+ 0xEB000264, 0xE3A00000, 0xE8BD8000, 0x00001014,
+ 0xE92D4000, 0xEBFFFFDB, 0xEBFFFF9F, 0xE51F005C,
+ 0xE51F205C, 0xE5921000, 0xE0800181, 0xE5D01007,
+ 0xE3510011, 0x1A000004, 0xE51F0074, 0xE5900008,
+ 0xE5903000, 0xE3130008, 0x0AFFFFFC, 0xE5B2000C,
+ 0xE5801000, 0xE3A00000, 0xEB000247, 0xE3A00000,
+ 0xE8BD8000, 0xE92D4000, 0xEBFFFFC6, 0xEBFFFF8A,
+ 0xE51F10AC, 0xE5910008, 0xE5902000, 0xE3120008,
+ 0x0AFFFFFC, 0xE5900000, 0xE3100002, 0x0A000002,
+ 0xE3A00003, 0xEB000238, 0xEA000002, 0xE5B10010,
+ 0xE3A01040, 0xEB00023B, 0xE3A00000, 0xE8BD8000,
+ 0xE92D4010, 0xEBFFFFB3, 0xE51F40F4, 0xE5940008,
+ 0xE5901000, 0xE3110008, 0x0AFFFFFC, 0xE5900000,
+ 0xE3100002, 0x0A000005, 0xE5B41004, 0xE51F00D8,
+ 0xEBFFFF5F, 0xEBFFFF6C, 0xE3A00003, 0xEA00000B,
+ 0xE5940010, 0xE5941004, 0xEBFFFF59, 0xEBFFFF66,
+ 0xE51F0140, 0xE5941000, 0xE0800181, 0xE5D02007,
+ 0xE5B41004, 0xE594000C, 0xEB00024E, 0xE3A00000,
+ 0xEB000215, 0xE3A00000, 0xE8BD8010, 0xE92D4010,
+ 0xEBFFFF94, 0xEBFFFF58, 0xE51F0174, 0xE5901008,
+ 0xE5912000, 0xE3120008, 0x0AFFFFFC, 0xE5911000,
+ 0xE3110002, 0xE3A04000, 0x13A00003, 0x1A00000F,
+ 0xE51F11A0, 0xE5902000, 0xE0812182, 0xE5D22007,
+ 0xE3520034, 0x1A000003, 0xE5902010, 0xE5224088,
+ 0xE5902010, 0xE5224084, 0xE5902000, 0xE0811182,
+ 0xE5D11007, 0xE590000C, 0xE5801000, 0xE3A00000,
+ 0xEB0001F5, 0xE1A00004, 0xE8BD8010, 0xE92D4010,
+ 0xEBFFFF39, 0xE3A04000, 0xE3A00AFE, 0xE2400601,
+ 0xE5A04400, 0xE3A00000, 0xEB0001EB, 0xE1A00004,
+ 0xE8BD8010, 0xE92D4010, 0xE51F01D4, 0xE1A04000,
+ 0xE3A01002, 0xEBFFFF1E, 0xEBFFFF2B, 0xE3A00AFE,
+ 0xE2400601, 0xE5901474, 0xE3110002, 0x1A00000F,
+ 0xE5901424, 0xE3110402, 0x13A00005, 0x1A00000E,
+ 0xE3A01003, 0xE5801470, 0xE5901474, 0xE3110020,
+ 0x0AFFFFFC, 0xE5941000, 0xE5801478, 0xE5B41004,
+ 0xE5801478, 0xE5900474, 0xE3100002, 0x0A000001,
+ 0xE3A00004, 0xEA000000, 0xE3A00000, 0xEB0001CA,
+ 0xE3A00000, 0xE8BD8010, 0xE92D4000, 0xEBFFFF0E,
+ 0xE3A00AFE, 0xE2400601, 0xE5901474, 0xE3110002,
+ 0xE51F126C, 0x1A00000D, 0xE5902424, 0xE3120402,
+ 0x13A00005, 0x1A00000C, 0xE5902474, 0xE3120040,
+ 0x0AFFFFFC, 0xE5902478, 0xE5812000, 0xE5902478,
+ 0xE5812004, 0xE5900474, 0xE3100002, 0x0A000001,
+ 0xE3A00004, 0xEA000000, 0xE3A00000, 0xE3500000,
+ 0x1A000003, 0xE1A00001, 0xE3A01002, 0xEB0001B1,
+ 0xEA000000, 0xEB0001A8, 0xE3A00000, 0xE8BD8000,
+ 0xE92D40F0, 0xE51F6320, 0xE5961004, 0xE51F02E8,
+ 0xE1A04000, 0xEBFFFEDA, 0xEBFFFEE7, 0xE3A05AFE,
+ 0xE2455601, 0xE3A07000, 0xE5960000, 0xE3500023,
+ 0x1A000004, 0xE5941000, 0xE3110004, 0x13A00004,
+ 0x15A50470, 0x1A000018, 0xE3500023, 0x13500031,
+ 0x0A000002, 0xE5951474, 0xE3110001, 0x1AFFFFFC,
+ 0xE3500025, 0x1A000003, 0xE5940000, 0xE3C0033F,
+ 0xE5840000, 0xE5857470, 0xE5960004, 0xE1A02100,
+ 0xE51F03A0, 0xE5961000, 0xE0800181, 0xE5D00006,
+ 0xE2400B07, 0xE1A01004, 0xEB0001D0, 0xE5B50474,
+ 0xE3100002, 0x13A00004, 0x1A000000, 0xE3A00000,
+ 0xEB000179, 0xE1A00007, 0xE8BD80F0, 0xE92D40F0,
+ 0xEBFFFEBD, 0xE3A06AFE, 0xE2466601, 0xE5960474,
+ 0xE3100002, 0xE51F73B0, 0xE51F43F4, 0x15940000,
+ 0x13500020, 0x1A000014, 0xE5940000, 0xE350002E,
+ 0x13500030, 0x13500034, 0x1A000002, 0xE5961474,
+ 0xE3110001, 0x1AFFFFFC, 0xE51F1428, 0xE0810180,
+ 0xE5D05007, 0xE1A02105, 0xE5D00006, 0xE2401B07,
+ 0xE1A00007, 0xEB0001AD, 0xE5B60474, 0xE3100002,
+ 0x15940000, 0x13500020, 0x0A000001, 0xE3A00004,
+ 0xEA000000, 0xE3A00000, 0xE3500000, 0x1A000003,
+ 0xE1A01005, 0xE1A00007, 0xEB000156, 0xEA000000,
+ 0xEB00014D, 0xE3A00000, 0xE8BD80F0, 0xE92D41F0,
+ 0xE3A04000, 0xE3A00003, 0xE3A08AFE, 0xE2488601,
+ 0xE5880470, 0xE5980474, 0xE3100002, 0xE51F54A8,
+ 0x13A04004, 0x1A000006, 0xE5950004, 0xE3100001,
+ 0x13A04006, 0x1A000002, 0xE5980424, 0xE3100402,
+ 0x13A04005, 0xE51F7490, 0xE3540000, 0x0A000004,
+ 0xE1A00007, 0xE5951004, 0xEBFFFE6D, 0xEBFFFE7A,
+ 0xEA00001D, 0xE3A06000, 0xE5950004, 0xE3500000,
+ 0xDA000015, 0xE5980474, 0xE3100020, 0x0AFFFFFC,
+ 0xEBFFFE5C, 0xE5880478, 0xEBFFFE5A, 0xE5880478,
+ 0xE5980474, 0xE3100004, 0x1A000007, 0xE5980474,
+ 0xE3100040, 0x0AFFFFFC, 0xE5980478, 0xE7870106,
+ 0xE5980478, 0xE0871106, 0xE5A10004, 0xE2866002,
+ 0xE5950004, 0xE1560000, 0xBAFFFFE9, 0xEBFFFE5E,
+ 0xE5980474, 0xE3100002, 0x13A04004, 0xE3540000,
+ 0x05B80474, 0x03100004, 0x1A000003, 0xE1A00007,
+ 0xE5B51004, 0xEB000113, 0xEA000001, 0xE1A00004,
+ 0xEB000109, 0xE3A00000, 0xE8BD81F0, 0xE92D4010,
+ 0xEBFFFE4D, 0xE3A00AFE, 0xE2400601, 0xE5901474,
+ 0xE3110002, 0xE3A04000, 0x1A000013, 0xE5901424,
+ 0xE3110402, 0x0A000003, 0xE5901474, 0xE3110C02,
+ 0x0AFFFFFC, 0xEA000002, 0xE5901474, 0xE3110020,
+ 0x0AFFFFFC, 0xE5901470, 0xE3C11001, 0xE5801470,
+ 0xE5901474, 0xE3110001, 0x1AFFFFFC, 0xE5804470,
+ 0xE5900474, 0xE3100002, 0x0A000001, 0xE3A00004,
+ 0xEA000000, 0xE3A00000, 0xEB0000E7, 0xE1A00004,
+ 0xE8BD8010, 0xE92D4070, 0xE3A00AFE, 0xE2400601,
+ 0xE5901474, 0xE3110002, 0xE51F55F4, 0xE3A06000,
+ 0x0A000005, 0xE3A04004, 0xE1A00005, 0xE3A01012,
+ 0xEBFFFE13, 0xEBFFFE20, 0xEA000027, 0xE5901424,
+ 0xE3110402, 0x0A000003, 0xE5901474, 0xE3110C02,
+ 0x0AFFFFFC, 0xEA000002, 0xE5901474, 0xE3110020,
+ 0x0AFFFFFC, 0xE5901470, 0xE3C11001, 0xE5801470,
+ 0xE5901474, 0xE3110001, 0x1AFFFFFC, 0xE1A04000,
+ 0xE5806470, 0xE1A00005, 0xE3A02048, 0xE3A0100C,
+ 0xE2411B07, 0xEB000111, 0xE3A01006, 0xE3A0000C,
+ 0xE2400B07, 0xEBFFFDF6, 0xEBFFFDEE, 0xE3C0033F,
+ 0xE5840424, 0xE3A0100B, 0xE3A00028, 0xE2400B07,
+ 0xEBFFFDEF, 0xEBFFFDFC, 0xE3A00003, 0xE5840470,
+ 0xE5B40474, 0xE2104002, 0x13A04004, 0xE3540000,
+ 0x1A000003, 0xE1A00005, 0xE3A01012, 0xEB0000B1,
+ 0xEA000001, 0xE1A00004, 0xEB0000A7, 0xE1A00006,
+ 0xE8BD8070, 0xE92D4000, 0xEBFFFDEB, 0xE51F172C,
+ 0xE51F072C, 0xE5900000, 0xE0810180, 0xE5D00007,
+ 0xE3A01AFE, 0xE2411601, 0xE5A10C00, 0xE3A00000,
+ 0xEB000099, 0xE3A00000, 0xE8BD8000, 0xE92D4000,
+ 0xEBFFFDC8, 0xE3A01AFE, 0xE2411601, 0xE5A10C04,
+ 0xEBFFFDD9, 0xE3A00000, 0xEB00008F, 0xE3A00000,
+ 0xE8BD8000, 0xE92D41F0, 0xEBFFFDBE, 0xE1A04000,
+ 0xEBFFFDD1, 0xE3A06000, 0xE35400FF, 0x9A000002,
+ 0xE3A00007, 0xEB000084, 0xEA00001C, 0xE3A00000,
+ 0xE51F376C, 0xE3540000, 0x9A000015, 0xE3A07064,
+ 0xE3A0C080, 0xE3A02AFE, 0xE2422601, 0xE3A0E001,
+ 0xE3A01000, 0xE5827800, 0xE582C808, 0xE5928A00,
+ 0xE3180001, 0x0AFFFFFC, 0xE582EA00, 0xE5928C04,
+ 0xE20880FF, 0xE0885405, 0xE2811001, 0xE3510004,
+ 0x3AFFFFF3, 0xE7835100, 0xE2800001, 0xE1500004,
+ 0x3AFFFFEE, 0xE1A01004, 0xE1A00003, 0xEB00006D,
+ 0xE1A00006, 0xE8BD81F0, 0xE92D47F0, 0xEB0000A1,
+ 0xE3A09004, 0xE3A08AFE, 0xE2488601, 0xE3A07010,
+ 0xE1A06088, 0xE2485A01, 0xE3500000, 0x0A000001,
+ 0xEB000084, 0xEA000015, 0xEB000082, 0xE5889470,
+ 0xE3A0A000, 0xE59F4040, 0xEBFFFD81, 0xEBFFFD9F,
+ 0xE3A00001, 0xEB000014, 0xEB000019, 0xE3500002,
+ 0x0A00000A, 0xE5867804, 0xE5857804, 0xE5889470,
+ 0xE3A00002, 0xEB00000C, 0xE584A000, 0xE5940000,
+ 0xE3500000, 0x0AFFFFFC, 0xEAFFFFEE, 0x000017B4,
+ 0xE5A67804, 0xE5A57804, 0xE5A89470, 0xE3A00003,
+ 0xEB000001, 0xEAFFFFFF, 0xEAFFFFFE, 0xE1A00C00,
+ 0xE3A01AFE, 0xE2411601, 0xE5A10600, 0xE1A0F00E,
+ 0xE1A0F00E, 0xE92D43F0, 0xE3A07001, 0xE3A09AFE,
+ 0xE2499601, 0xE3A080FF, 0xE59F6030, 0xE59F5030,
+ 0xE59F4030, 0xE5990618, 0xE3500C01, 0x0A000005,
+ 0xE5990618, 0xE3500000, 0x9A000007, 0xE5990620,
+ 0xE3500000, 0x1A000004, 0xE3A00002, 0xEA000019,
+ 0x00001004, 0x00001000, 0x00000E00, 0xE5990618,
+ 0xE3500000, 0x0AFFFFFC, 0xEBFFFD4E, 0xE20010FF,
+ 0xE0082420, 0xE5851000, 0xE1A03800, 0xE1A03823,
+ 0xE1530820, 0xE5862000, 0x1A000007, 0xE351003E,
+ 0xD0843181, 0xD5D3C004, 0xD15C0002, 0xCA000002,
+ 0xE5D33005, 0xE1530002, 0xAA000006, 0xE1A00820,
+ 0xE1A00800, 0xE3800001, 0xEBFFFD59, 0xEBFFFD7C,
+ 0xE1A00007, 0xE8BD83F0, 0xE1A0E00F, 0xE794F181,
+ 0xE3500000, 0x0AFFFFD2, 0xE8BD83F0, 0xE92D4000,
+ 0xE51F1094, 0xE5911000, 0xE1800801, 0xEBFFFD4C,
+ 0xE8BD4000, 0xEAFFFD6E, 0xE92D4030, 0xE1A05000,
+ 0xE1A04001, 0xE1A00C01, 0xE51F10BC, 0xE5911000,
+ 0xE1800801, 0xEBFFFD42, 0xE1A01004, 0xE1A00005,
+ 0xEBFFFD4D, 0xE8BD4030, 0xEAFFFD61, 0xE59F1020,
+ 0xE5910000, 0xE59F201C, 0xE1500002, 0x21A0F00E,
+ 0xE5922000, 0xE5802000, 0xE3E00000, 0xE5810000,
+ 0xE1A0F00E, 0x000017FC, 0x000017F8, 0xE92D4010,
+ 0xE1A04000, 0xEB000010, 0xE3540018, 0x03A00080,
+ 0x0A000002, 0xE354001C, 0x18BD8010, 0xE3A00040,
+ 0xE8BD4010, 0xEAFFFCD8, 0xE92D4000, 0xE3A01001,
+ 0xE3A00018, 0xEBFFFFF0, 0xE3A01902, 0xE3A00AFE,
+ 0xE2400601, 0xE5A01A08, 0xE8BD8000, 0xE3A000C0,
+ 0xEAFFFCC9, 0xE1A0F00E, 0xE3A03000, 0xE1510002,
+ 0x21A0F00E, 0xE7803101, 0xE2811001, 0xE1510002,
+ 0x3AFFFFFB, 0xE1A0F00E, 0xE3A00000, 0xE1A0F00E,
+ 0xE3A00001, 0xE1A0F00E, 0xE3A00002, 0xE1A0F00E,
+ 0xE92D4000, 0xE59F001C, 0xE5901000, 0xE59F0018,
+ 0xEBFFFCEF, 0xEBFFFCFC, 0xE3A00011, 0xEBFFFFB2,
+ 0xE3A00000, 0xE8BD8000, 0x00001004, 0x00001014,
+ 0xE1803001, 0xE1833002, 0xE3130003, 0x1A00000B,
+ 0xE1A0C122, 0xE1A03000, 0xE24C2001, 0xE35C0000,
+ 0x91A0F00E, 0xE491C004, 0xE483C004, 0xE1A0C002,
+ 0xE2422001, 0xE35C0000, 0x8AFFFFF9, 0xE1A0F00E,
+ 0xE1A03000, 0xE1A0C002, 0xE2422001, 0xE35C0000,
+ 0x91A0F00E, 0xE4D1C001, 0xE4C3C001, 0xE1A0C002,
+ 0xE2422001, 0xE35C0000, 0x8AFFFFF9, 0xE1A0F00E,
+ 0x000002A0, 0x00000000, 0x000002E0, 0x10C80000,
+ 0x000002E0, 0x11C80000, 0x00000334, 0x00C00000,
+ 0x00000380, 0x40C04000, 0x00000380, 0x40C14000,
+ 0x00000380, 0x40C24000, 0x00000380, 0x20C52000,
+ 0x00000380, 0x20C72000, 0x00000380, 0x22C42200,
+ 0x00000380, 0x22C62200, 0x00000380, 0x22C32200,
+ 0x000003FC, 0x34C80000, 0x000003FC, 0x35C80000,
+ 0x000003FC, 0x36C80000, 0x000003FC, 0x37C80000,
+ 0x000002E0, 0x10D80000, 0x000002E0, 0x11D80000,
+ 0x00000334, 0x00D00000, 0x00000380, 0x40D04000,
+ 0x00000380, 0x40D14000, 0x00000380, 0x40D24000,
+ 0x00000380, 0x20D52000, 0x00000380, 0x20D72000,
+ 0x00000380, 0x22D42200, 0x00000380, 0x22D62200,
+ 0x00000380, 0x22D32200, 0x000003FC, 0x34D80000,
+ 0x000003FC, 0x35D80000, 0x000003FC, 0x36D80000,
+ 0x000003FC, 0x37D80000, 0x0000047C, 0x00000000,
+ 0x0000066C, 0x01000000, 0x000004A4, 0x00000202,
+ 0x00000528, 0x00000000, 0x000005B0, 0x01700101,
+ 0x0000066C, 0x01700000, 0x000005B0, 0x01240101,
+ 0x0000066C, 0x01240000, 0x000005B0, 0x021C0202,
+ 0x0000066C, 0x021C0000, 0x000005B0, 0x02140202,
+ 0x0000066C, 0x02140000, 0x000005B0, 0x020C0202,
+ 0x0000066C, 0x020C0000, 0x000005B0, 0x02280202,
+ 0x0000066C, 0x02280000, 0x000005B0, 0x02440202,
+ 0x0000066C, 0x02440000, 0x000005B0, 0x024C0202,
+ 0x0000066C, 0x024C0000, 0x000005B0, 0x05300505,
+ 0x0000066C, 0x05300000, 0x0000071C, 0x0000FF00,
+ 0x0000082C, 0x00000000, 0x000008B4, 0x00001212,
+ 0x000009B4, 0x01000000, 0x000009B4, 0x00000000,
+ 0x000009EC, 0x00000101, 0x00000A14, 0x00000101,
+ 0x00000D58, 0x00004040, 0x00000D60, 0x00002020,
+ 0x00000D60, 0x0000FF00, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000
+};
diff --git a/sys/dev/pci/isesvar.h b/sys/dev/pci/isesvar.h
new file mode 100644
index 00000000000..efe90d7acb2
--- /dev/null
+++ b/sys/dev/pci/isesvar.h
@@ -0,0 +1,83 @@
+/* $OpenBSD: isesvar.h,v 1.1 2001/01/29 08:45:58 ho Exp $ */
+
+/*
+ * Copyright (c) 2000 Håkan Olsson (ho@crt.se)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct ises_softc {
+ struct device sc_dv; /* generic device */
+ void *sc_ih; /* interrupt handler cookie */
+ bus_space_handle_t sc_memh; /* memory handle */
+ bus_space_tag_t sc_memt; /* memory tag */
+ bus_dma_tag_t sc_dmat; /* dma tag */
+ bus_dmamap_t sc_dmamap_xfer; /* dma xfer map */
+ struct ises_databuf sc_dmamap; /* data area */
+ bus_addr_t sc_dmamap_phys; /* bus address of data area */
+ int32_t sc_cid; /* crypto tag */
+ u_int32_t sc_intrmask; /* interrupt mask */
+ u_int32_t sc_omr; /* OMR */
+ SIMPLEQ_HEAD(,ises_q) sc_queue; /* packet queue */
+ int sc_nqueue; /* count enqueued */
+ SIMPLEQ_HEAD(,ises_q) sc_qchip; /* on chip */
+ struct timeout sc_timeout; /* init + hrng timeout */
+ int sc_nsessions; /* nr of sessions */
+ struct ises_session *sc_sessions; /* sessions */
+ int sc_initstate; /* card initialization state */
+};
+
+struct ises_q {
+ SIMPLEQ_ENTRY(ises_q) q_next;
+ struct cryptop *q_crp;
+ struct ises_pktbuf q_srcpkt;
+ struct ises_pktbuf q_dstpkt;
+ struct ises_pktctx q_ctx;
+
+ struct ises_softc *q_sc;
+ struct mbuf *q_src_m, *q_dst_m;
+
+ int q_sesn;
+ long q_src_packp;
+ int q_src_packl;
+ int q_src_npa, q_src_l;
+
+ long q_dst_packp;
+ int q_dst_packl;
+ int q_dst_npa, q_dst_l;
+ u_int32_t q_macbuf[5];
+};
+
+struct ises_session {
+ u_int32_t ses_used;
+ u_int32_t ses_deskey[6]; /* 3DES key */
+ u_int32_t ses_hminner[5]; /* hmac inner state */
+ u_int32_t ses_hmouter[5]; /* hmac outer state */
+ u_int32_t ses_iv[2]; /* DES/3DES iv */
+};
+
+/* Maximum queue length */
+#ifndef ISES_MAX_NQUEUE
+#define ISES_MAX_NQUEUE 24
+#endif