newer HIFN support 7955/7956

Andrew Atrens atrens at nortel.com
Fri Aug 24 06:07:46 PDT 2007


more stuff from my tree.. originally from FreeBSD/OpenBSD - it's had 18+ months of soak .. hopefully
I haven't missed any dependencies :(



Index: cryptodev.h
===================================================================
RCS file: /usr/dfly/repo/src/sys/opencrypto/cryptodev.h,v
retrieving revision 1.2
diff -u -r1.2 cryptodev.h
--- cryptodev.h 17 Jun 2003 04:28:54 -0000      1.2
+++ cryptodev.h 11 Apr 2007 03:41:59 -0000
@@ -229,6 +229,8 @@
 #define        CRD_F_IV_EXPLICIT       0x04    /* IV explicitly provided */
 #define        CRD_F_DSA_SHA_NEEDED    0x08    /* Compute SHA-1 of buffer for DSA */
 #define CRD_F_COMP             0x0f    /* Set when doing compression */
+#define CRD_F_KEY_EXPLICIT      0x10
+

        struct cryptoini        CRD_INI; /* Initialization/context data */
 #define crd_iv         CRD_INI.cri_iv
Index: cryptosoft.c
===================================================================
RCS file: /usr/dfly/repo/src/sys/opencrypto/cryptosoft.c,v
retrieving revision 1.5
diff -u -r1.5 cryptosoft.c
--- cryptosoft.c        5 Sep 2006 03:48:13 -0000       1.5
+++ cryptosoft.c        11 Apr 2007 03:41:59 -0000
@@ -154,6 +154,16 @@
                }
        }

+        if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
+                int error;
+
+                if (sw->sw_kschedule)
+                        exf->zerokey(&(sw->sw_kschedule));
+                error = exf->setkey(&sw->sw_kschedule,
+                                crd->crd_key, crd->crd_klen / 8);
+                if (error)
+                        return (error);
+       }
        ivp = iv;

        if (outtype == CRYPTO_BUF_CONTIG) {

Index: hifn7751.c
===================================================================
RCS file: /usr/dfly/repo/src/sys/dev/crypto/hifn/hifn7751.c,v
retrieving revision 1.13
diff -u -r1.13 hifn7751.c
--- hifn7751.c	22 Dec 2006 23:26:15 -0000	1.13
+++ hifn7751.c	11 Apr 2007 03:41:10 -0000
@@ -2,12 +2,13 @@
 /* $DragonFly: src/sys/dev/crypto/hifn/hifn7751.c,v 1.13 2006/12/22 23:26:15 swildner Exp $ */
 /*	$OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $	*/

-/*
+/*-
  * Invertex AEON / Hifn 7751 driver
  * Copyright (c) 1999 Invertex Inc. All rights reserved.
  * Copyright (c) 1999 Theo de Raadt
  * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  *			http://www.netsec.net
+ * Copyright (c) 2003 Hifn Inc.
  *
  * This driver is based on a previous driver by Invertex, for which they
  * requested:  Please send any comments, feedback, bug-fixes, or feature
@@ -43,7 +44,7 @@
  */

 /*
- * Driver for the Hifn 7751 encryption processor.
+ * Driver for various Hifn encryption processors.
  */
 #include "opt_hifn.h"

@@ -60,6 +61,9 @@
 #include <sys/random.h>
 #include <sys/thread2.h>

+#include <sys/bus.h>
+#include <sys/uio.h>
+
 #include <vm/vm.h>
 #include <vm/pmap.h>

@@ -194,11 +198,17 @@
 	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
 	    (pci_get_device(dev) == PCI_PRODUCT_HIFN_7751 ||
 	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7956 ||
 	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7811))
 		return (0);
 	if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
 	    pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751)
 		return (0);
+	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN) {
+		device_printf(dev,"device id = 0x%x\n", pci_get_device(dev) );
+		return (0);
+	}
 	return (ENXIO);
 }

@@ -220,6 +230,8 @@
 		case PCI_PRODUCT_HIFN_7751:	return "Hifn 7751";
 		case PCI_PRODUCT_HIFN_7811:	return "Hifn 7811";
 		case PCI_PRODUCT_HIFN_7951:	return "Hifn 7951";
+		case PCI_PRODUCT_HIFN_7955:	return "Hifn 7955";
+		case PCI_PRODUCT_HIFN_7956:	return "Hifn 7956";
 		}
 		return "Hifn unknown-part";
 	case PCI_VENDOR_INVERTEX:
@@ -244,6 +256,84 @@
 		add_true_randomness(*p++);
 }

+static u_int
+checkmaxmin(device_t dev, const char *what, u_int v, u_int min, u_int max)
+{
+	if (v > max) {
+		device_printf(dev, "Warning, %s %u out of range, "
+			"using max %u\n", what, v, max);
+		v = max;
+	} else if (v < min) {
+		device_printf(dev, "Warning, %s %u out of range, "
+			"using min %u\n", what, v, min);
+		v = min;
+	}
+	return v;
+}
+
+/*
+ * Select PLL configuration for 795x parts.  This is complicated in
+ * that we cannot determine the optimal parameters without user input.
+ * The reference clock is derived from an external clock through a
+ * multiplier.  The external clock is either the host bus (i.e. PCI)
+ * or an external clock generator.  When using the PCI bus we assume
+ * the clock is either 33 or 66 MHz; for an external source we cannot
+ * tell the speed.
+ *
+ * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
+ * for an external source, followed by the frequency.  We calculate
+ * the appropriate multiplier and PLL register contents accordingly.
+ * When no configuration is given we default to "pci66" since that
+ * always will allow the card to work.  If a card is using the PCI
+ * bus clock and in a 33MHz slot then it will be operating at half
+ * speed until the correct information is provided.
+ */
+static void
+hifn_getpllconfig(device_t dev, u_int *pll)
+{
+	char *pllspec;
+	u_int freq, mul, fl, fh;
+	u_int32_t pllconfig;
+	char *nxt;
+
+       if (resource_string_value("hifn", device_get_unit(dev),
+            "pllconfig", &pllspec))
+                pllspec = "pci66";
+        fl = 33, fh = 66;
+        pllconfig = 0;
+	if (strncmp(pllspec, "ext", 3) == 0) {
+		pllspec += 3;
+		pllconfig |= HIFN_PLL_REF_SEL;
+		switch (pci_get_device(dev)) {
+		case PCI_PRODUCT_HIFN_7955:
+		case PCI_PRODUCT_HIFN_7956:
+			fl = 20, fh = 100;
+			break;
+#ifdef notyet
+		case PCI_PRODUCT_HIFN_7954:
+			fl = 20, fh = 66;
+			break;
+#endif
+		}
+	} else if (strncmp(pllspec, "pci", 3) == 0)
+		pllspec += 3;
+	freq = strtoul(pllspec, &nxt, 10);
+	if (nxt == pllspec)
+		freq = 66;
+	else
+		freq = checkmaxmin(dev, "frequency", freq, fl, fh);
+	/*
+	 * Calculate multiplier.  We target a Fck of 266 MHz,
+	 * allowing only even values, possibly rounded down.
+	 * Multipliers > 8 must set the charge pump current.
+	 */
+	mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
+	pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
+	if (mul > 8)
+		pllconfig |= HIFN_PLL_IS;
+	*pll = pllconfig;
+}
+
 /*
  * Attach an interface that successfully probed.
  */
@@ -264,11 +354,13 @@
 	/* XXX handle power management */

 	/*
-	 * The 7951 has a random number generator and
+	 * The 7951 and 795x have a random number generator and
 	 * public key support; note this.
 	 */
 	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
-	    pci_get_device(dev) == PCI_PRODUCT_HIFN_7951)
+	    (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
 		sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
 	/*
 	 * The 7811 has a random number generator and
@@ -279,6 +371,21 @@
 		sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;

 	/*
+	 * The 795x parts support AES.
+	 */
+	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
+	    (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
+		sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
+		/*
+		 * Select PLL configuration.  This depends on the
+		 * bus and board design and must be manually configured
+		 * if the default setting is unacceptable.
+		 */
+		hifn_getpllconfig(dev, &sc->sc_pllconfig);
+	}
+
+	/*
 	 * Configure support for memory-mapped access to
 	 * registers and for DMA operations.
 	 */
@@ -368,10 +475,10 @@
 	sc->sc_dma = (struct hifn_dma *)kva;
 	bzero(sc->sc_dma, sizeof(*sc->sc_dma));

-	KASSERT(sc->sc_st0 != NULL, ("hifn_attach: null bar0 tag!"));
-	KASSERT(sc->sc_sh0 != NULL, ("hifn_attach: null bar0 handle!"));
-	KASSERT(sc->sc_st1 != NULL, ("hifn_attach: null bar1 tag!"));
-	KASSERT(sc->sc_sh1 != NULL, ("hifn_attach: null bar1 handle!"));
+	KASSERT(sc->sc_st0 != 0, ("hifn_attach: null bar0 tag!"));
+	KASSERT(sc->sc_sh0 != 0, ("hifn_attach: null bar0 handle!"));
+	KASSERT(sc->sc_st1 != 0, ("hifn_attach: null bar1 tag!"));
+	KASSERT(sc->sc_sh1 != 0, ("hifn_attach: null bar1 handle!"));

 	/*
 	 * Reset the board and do the ``secret handshake''
@@ -392,7 +499,10 @@
 	hifn_init_dma(sc);
 	hifn_init_pci_registers(sc);

-	if (hifn_ramtype(sc))
+	/* XXX can't dynamically determine ram type for 795x; force dram */
+	if (sc->sc_flags & HIFN_IS_7956)
+		sc->sc_drammodel = 1;
+	else if (hifn_ramtype(sc))
 		goto fail_mem;

 	if (sc->sc_drammodel == 0)
@@ -423,7 +533,7 @@
 	 * NB: Network code assumes we are blocked with splimp()
 	 *     so make sure the IRQ is marked appropriately.
 	 */
-	if (bus_setup_intr(dev, sc->sc_irq, 0,
+	if (bus_setup_intr(dev, sc->sc_irq, INTR_FAST,
 			   hifn_intr, sc,
 			   &sc->sc_intrhand, NULL)) {
 		device_printf(dev, "could not setup interrupt\n");
@@ -448,6 +558,12 @@
 		hifn_partname(sc), rev,
 		rseg, rbase, sc->sc_drammodel ? 'd' : 's',
 		sc->sc_maxses);
+	if (sc->sc_flags & HIFN_IS_7956)
+		kprintf(", pll=0x%x<%s clk, %ux mult>",
+			sc->sc_pllconfig,
+			sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
+			2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
+	kprintf("\n");

 	sc->sc_cid = crypto_get_driverid(0);
 	if (sc->sc_cid < 0) {
@@ -465,6 +581,10 @@
 		    hifn_newsession, hifn_freesession, hifn_process, sc);
 		crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0,
 		    hifn_newsession, hifn_freesession, hifn_process, sc);
+		if (sc->sc_flags & HIFN_HAS_AES)
+			crypto_register(sc->sc_cid, CRYPTO_AES_CBC,  0, 0,
+				hifn_newsession, hifn_freesession,
+				hifn_process, sc);
 		/*FALLTHROUGH*/
 	case HIFN_PUSTAT_ENA_1:
 		crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0,
@@ -524,6 +644,9 @@

 	KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));

+	/* disable interrupts */
+	WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
+
 	crit_enter();
 	/*XXX other resources */
 	callout_stop(&sc->sc_tickto);
@@ -875,6 +998,16 @@
 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		  0x00, 0x00, 0x00, 0x00, 0x00 }
 	}, {
+		PCI_VENDOR_HIFN,
+		PCI_PRODUCT_HIFN_7955,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00 }
+	}, {
+		PCI_VENDOR_HIFN,
+		PCI_PRODUCT_HIFN_7956,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00 }
+	}, {
 		PCI_VENDOR_NETSEC,
 		PCI_PRODUCT_NETSEC_7751,
 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -1055,10 +1188,36 @@
 	sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
 	WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);

-	WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
-	    HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
-	    HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
-	    (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
+
+	if (sc->sc_flags & HIFN_IS_7956) {
+		u_int32_t pll;
+
+		WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
+		    HIFN_PUCNFG_TCALLPHASES |
+		    HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
+
+		/* turn off the clocks and insure bypass is set */
+		pll = READ_REG_1(sc, HIFN_1_PLL);
+		pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
+		    | HIFN_PLL_BP;
+		WRITE_REG_1(sc, HIFN_1_PLL, pll);
+		DELAY(10*1000);		/* 10ms */
+		/* change configuration */
+		pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
+		WRITE_REG_1(sc, HIFN_1_PLL, pll);
+		DELAY(10*1000);		/* 10ms */
+		/* disable bypass */
+		pll &= ~HIFN_PLL_BP;
+		WRITE_REG_1(sc, HIFN_1_PLL, pll);
+		/* enable clocks with new configuration */
+		pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
+		WRITE_REG_1(sc, HIFN_1_PLL, pll);
+	} else {
+		WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
+		    HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
+		    HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
+		    (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
+	}

 	WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
 	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
@@ -1087,8 +1246,14 @@
 			ctxsize = 128;
 		else
 			ctxsize = 512;
-		sc->sc_maxses = 1 +
-		    ((sc->sc_ramsize - 32768) / ctxsize);
+		/*
+		 * 7955/7956 has internal context memory of 32K
+		 */
+		if (sc->sc_flags & HIFN_IS_7956)
+			sc->sc_maxses = 32768 / ctxsize;
+		else
+			sc->sc_maxses = 1 +
+			    ((sc->sc_ramsize - 32768) / ctxsize);
 	} else
 		sc->sc_maxses = sc->sc_ramsize / 16384;

@@ -1175,9 +1340,16 @@
 {
 	u_int32_t cnfg;

-	cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
-	    HIFN_PUCNFG_DRAMMASK;
-	sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
+	if (sc->sc_flags & HIFN_IS_7956) {
+		/*
+		 * 7955/7956 have a fixed internal ram of only 32K.
+		 */
+		sc->sc_ramsize = 32768;
+	} else {
+		cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
+		    HIFN_PUCNFG_DRAMMASK;
+		sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
+	}
 	return (0);
 }

@@ -1393,7 +1565,7 @@
 	hifn_base_command_t *base_cmd;
 	hifn_mac_command_t *mac_cmd;
 	hifn_crypt_command_t *cry_cmd;
-	int using_mac, using_crypt, len;
+	int using_mac, using_crypt, len, ivlen;
 	u_int32_t dlen, slen;

 	buf_pos = buf;
@@ -1411,7 +1583,11 @@
 	base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
 	dlen >>= 16;
 	slen >>= 16;
+#if 0
 	base_cmd->session_num = htole16(cmd->session_num |
+#else
+	base_cmd->session_num = htole16(
+#endif
 	    ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
 	    ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
 	buf_pos += sizeof(hifn_base_command_t);
@@ -1453,7 +1629,7 @@
 			break;
 		case HIFN_CRYPT_CMD_ALG_DES:
 			bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
-			buf_pos += cmd->cklen;
+			buf_pos += HIFN_DES_KEY_LENGTH;
 			break;
 		case HIFN_CRYPT_CMD_ALG_RC4:
 			len = 256;
@@ -1468,12 +1644,28 @@
 			bzero(buf_pos, 4);
 			buf_pos += 4;
 			break;
+		case HIFN_CRYPT_CMD_ALG_AES:
+			/*
+			 * AES keys are variable 128, 192 and
+			 * 256 bits (16, 24 and 32 bytes).
+			 */
+			bcopy(cmd->ck, buf_pos, cmd->cklen);
+			buf_pos += cmd->cklen;
+			break;
 		}
 	}

 	if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
-		bcopy(cmd->iv, buf_pos, HIFN_IV_LENGTH);
-		buf_pos += HIFN_IV_LENGTH;
+		switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
+		case HIFN_CRYPT_CMD_ALG_AES:
+			ivlen = HIFN_AES_IV_LENGTH;
+			break;
+		default:
+			ivlen = HIFN_IV_LENGTH;
+			break;
+		}
+		bcopy(cmd->iv, buf_pos, ivlen);
+		buf_pos += ivlen;
 	}

 	if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
@@ -1658,6 +1850,7 @@
 			goto err_srcmap1;
 		}
 	} else if (crp->crp_flags & CRYPTO_F_IOV) {
+		cmd->src_io->uio_segflg = UIO_USERSPACE;
 		if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map,
 		    cmd->src_io, hifn_op_cb, &cmd->src, BUS_DMA_NOWAIT)) {
 			hifnstats.hst_nomem_load++;
@@ -1769,6 +1962,7 @@
 				goto err_dstmap1;
 			}
 		} else if (crp->crp_flags & CRYPTO_F_IOV) {
+			cmd->dst_io->uio_segflg |= UIO_USERSPACE;
 			if (bus_dmamap_load_uio(sc->sc_dmat, cmd->dst_map,
 			    cmd->dst_io, hifn_op_cb, &cmd->dst, BUS_DMA_NOWAIT)) {
 				hifnstats.hst_nomem_load++;
@@ -1979,10 +2173,16 @@
 	u_int32_t dmacsr, restart;
 	int i, u;

-	dma = sc->sc_dma;
-
 	dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);

+	/* Nothing in the DMA unit interrupted */
+	if ((dmacsr & sc->sc_dmaier) == 0) {
+		hifnstats.hst_noirq++;
+		return;
+	}
+
+	dma = sc->sc_dma;
+
 #ifdef HIFN_DEBUG
 	if (hifn_debug) {
 		device_printf(sc->sc_dev,
@@ -1994,12 +2194,6 @@
 	}
 #endif

-	/* Nothing in the DMA unit interrupted */
-	if ((dmacsr & sc->sc_dmaier) == 0) {
-		hifnstats.hst_noirq++;
-		return;
-	}
-
 	WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);

 	if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
@@ -2130,17 +2324,44 @@
 {
 	struct cryptoini *c;
 	struct hifn_softc *sc = arg;
-	int i, mac = 0, cry = 0;
+	int mac = 0, cry = 0, sesn;
+	struct hifn_session *ses = NULL;

 	KASSERT(sc != NULL, ("hifn_newsession: null softc"));
 	if (sidp == NULL || cri == NULL || sc == NULL)
 		return (EINVAL);

-	for (i = 0; i < sc->sc_maxses; i++)
-		if (sc->sc_sessions[i].hs_state == HS_STATE_FREE)
-			break;
-	if (i == sc->sc_maxses)
-		return (ENOMEM);
+	if (sc->sc_sessions == NULL) {
+		ses = sc->sc_sessions = (struct hifn_session *)kmalloc(
+		    sizeof(*ses), 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].hs_used) {
+				ses = &sc->sc_sessions[sesn];
+				break;
+			}
+		}
+
+		if (ses == NULL) {
+			sesn = sc->sc_nsessions;
+			ses = (struct hifn_session *)kmalloc((sesn + 1) *
+			    sizeof(*ses), M_DEVBUF, M_NOWAIT);
+			if (ses == NULL)
+				return (ENOMEM);
+			bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
+			bzero(sc->sc_sessions, sesn * sizeof(*ses));
+			kfree(sc->sc_sessions, M_DEVBUF);
+			sc->sc_sessions = ses;
+			ses = &sc->sc_sessions[sesn];
+			sc->sc_nsessions++;
+		}
+	}
+	bzero(ses, sizeof(*ses));
+	ses->hs_used = 1;

 	for (c = cri; c != NULL; c = c->cri_next) {
 		switch (c->cri_alg) {
@@ -2154,8 +2375,11 @@
 			break;
 		case CRYPTO_DES_CBC:
 		case CRYPTO_3DES_CBC:
+		case CRYPTO_AES_CBC:
 			/* XXX this may read fewer, does it matter? */
-			read_random(sc->sc_sessions[i].hs_iv, HIFN_IV_LENGTH);
+			read_random(ses->hs_iv,
+				c->cri_alg == CRYPTO_AES_CBC ?
+					HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
 			/*FALLTHROUGH*/
 		case CRYPTO_ARC4:
 			if (cry)
@@ -2169,8 +2393,7 @@
 	if (mac == 0 && cry == 0)
 		return (EINVAL);

-	*sidp = HIFN_SID(device_get_unit(sc->sc_dev), i);
-	sc->sc_sessions[i].hs_state = HS_STATE_USED;
+	*sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);

 	return (0);
 }
@@ -2180,19 +2403,21 @@
  * XXX this routine should run a zero'd mac/encrypt key into context ram.
  * XXX to blow away any keys already stored there.
  */
+#define     CRYPTO_SESID2LID(_sid)  (((u_int32_t) (_sid)) & 0xffffffff)
+
 static int
 hifn_freesession(void *arg, u_int64_t tid)
 {
 	struct hifn_softc *sc = arg;
 	int session;
-	u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
+	u_int32_t sid = CRYPTO_SESID2LID(tid);

 	KASSERT(sc != NULL, ("hifn_freesession: null softc"));
 	if (sc == NULL)
 		return (EINVAL);

 	session = HIFN_SESSION(sid);
-	if (session >= sc->sc_maxses)
+	if (session >= sc->sc_nsessions)
 		return (EINVAL);

 	bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
@@ -2204,7 +2429,7 @@
 {
 	struct hifn_softc *sc = arg;
 	struct hifn_command *cmd = NULL;
-	int session, err;
+	int session, err, ivlen;
 	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;

 	if (crp == NULL || crp->crp_callback == NULL) {
@@ -2213,12 +2438,19 @@
 	}
 	session = HIFN_SESSION(crp->crp_sid);

-	if (sc == NULL || session >= sc->sc_maxses) {
+	if (sc == NULL || session >= sc->sc_nsessions) {
+
 		err = EINVAL;
 		goto errout;
 	}

 	cmd = kmalloc(sizeof(struct hifn_command), M_DEVBUF, M_INTWAIT | M_ZERO);
+	if (cmd == NULL) {
+		hifnstats.hst_nomem++;
+		err = ENOMEM;
+		goto errout;
+	}
+

 	if (crp->crp_flags & CRYPTO_F_IMBUF) {
 		cmd->src_m = (struct mbuf *)crp->crp_buf;
@@ -2247,6 +2479,7 @@
 			enccrd = NULL;
 		} else if (crd1->crd_alg == CRYPTO_DES_CBC ||
 		    crd1->crd_alg == CRYPTO_3DES_CBC ||
+		    crd1->crd_alg == CRYPTO_AES_CBC ||
 		    crd1->crd_alg == CRYPTO_ARC4) {
 			if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
 				cmd->base_masks |= HIFN_BASE_CMD_DECODE;
@@ -2263,6 +2496,7 @@
                      crd1->crd_alg == CRYPTO_SHA1) &&
 		    (crd2->crd_alg == CRYPTO_DES_CBC ||
 		     crd2->crd_alg == CRYPTO_3DES_CBC ||
+		     crd2->crd_alg == CRYPTO_AES_CBC ||
 		     crd2->crd_alg == CRYPTO_ARC4) &&
 		    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
 			cmd->base_masks = HIFN_BASE_CMD_DECODE;
@@ -2270,7 +2504,8 @@
 			enccrd = crd2;
 		} else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
 		     crd1->crd_alg == CRYPTO_ARC4 ||
-		     crd1->crd_alg == CRYPTO_3DES_CBC) &&
+		     crd1->crd_alg == CRYPTO_3DES_CBC ||
+		     crd1->crd_alg == CRYPTO_AES_CBC) &&
 		    (crd2->crd_alg == CRYPTO_MD5_HMAC ||
                      crd2->crd_alg == CRYPTO_SHA1_HMAC ||
                      crd2->crd_alg == CRYPTO_MD5 ||
@@ -2293,10 +2528,6 @@
 		switch (enccrd->crd_alg) {
 		case CRYPTO_ARC4:
 			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
-			if ((enccrd->crd_flags & CRD_F_ENCRYPT)
-			    != sc->sc_sessions[session].hs_prev_op)
-				sc->sc_sessions[session].hs_state =
-				    HS_STATE_USED;
 			break;
 		case CRYPTO_DES_CBC:
 			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
@@ -2308,50 +2539,74 @@
 			    HIFN_CRYPT_CMD_MODE_CBC |
 			    HIFN_CRYPT_CMD_NEW_IV;
 			break;
+		case CRYPTO_AES_CBC:
+			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
+			    HIFN_CRYPT_CMD_MODE_CBC |
+			    HIFN_CRYPT_CMD_NEW_IV;
+			break;
 		default:
 			err = EINVAL;
 			goto errout;
 		}
 		if (enccrd->crd_alg != CRYPTO_ARC4) {
+			ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
+				HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
 			if (enccrd->crd_flags & CRD_F_ENCRYPT) {
 				if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
-					bcopy(enccrd->crd_iv, cmd->iv,
-					    HIFN_IV_LENGTH);
+					bcopy(enccrd->crd_iv, cmd->iv, ivlen);
 				else
 					bcopy(sc->sc_sessions[session].hs_iv,
-					    cmd->iv, HIFN_IV_LENGTH);
+					    cmd->iv, ivlen);

 				if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
 				    == 0) {
 					if (crp->crp_flags & CRYPTO_F_IMBUF)
 						m_copyback(cmd->src_m,
 						    enccrd->crd_inject,
-						    HIFN_IV_LENGTH, cmd->iv);
+						    ivlen, cmd->iv);
 					else if (crp->crp_flags & CRYPTO_F_IOV)
 						cuio_copyback(cmd->src_io,
 						    enccrd->crd_inject,
-						    HIFN_IV_LENGTH, cmd->iv);
+						    ivlen, cmd->iv);
 				}
 			} else {
 				if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
-					bcopy(enccrd->crd_iv, cmd->iv,
-					    HIFN_IV_LENGTH);
+					bcopy(enccrd->crd_iv, cmd->iv, ivlen);
 				else if (crp->crp_flags & CRYPTO_F_IMBUF)
 					m_copydata(cmd->src_m,
-					    enccrd->crd_inject,
-					    HIFN_IV_LENGTH, cmd->iv);
+					    enccrd->crd_inject, ivlen, cmd->iv);
 				else if (crp->crp_flags & CRYPTO_F_IOV)
 					cuio_copydata(cmd->src_io,
-					    enccrd->crd_inject,
-					    HIFN_IV_LENGTH, cmd->iv);
+					    enccrd->crd_inject, ivlen, cmd->iv);
 			}
 		}

+		if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
+			cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
 		cmd->ck = enccrd->crd_key;
 		cmd->cklen = enccrd->crd_klen >> 3;
+		cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;

-		if (sc->sc_sessions[session].hs_state == HS_STATE_USED)
-			cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
+		/*
+		 * Need to specify the size for the AES key in the masks.
+		 */
+		if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
+		    HIFN_CRYPT_CMD_ALG_AES) {
+			switch (cmd->cklen) {
+			case 16:
+				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
+				break;
+			case 24:
+				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
+				break;
+			case 32:
+				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
+				break;
+			default:
+				err = EINVAL;
+				goto errout;
+			}
+		}
 	}

 	if (maccrd) {
@@ -2381,9 +2636,8 @@
 			break;
 		}

-		if ((maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
-		     maccrd->crd_alg == CRYPTO_MD5_HMAC) &&
-		    sc->sc_sessions[session].hs_state == HS_STATE_USED) {
+		if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
+		     maccrd->crd_alg == CRYPTO_MD5_HMAC) {
 			cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
 			bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
 			bzero(cmd->mac + (maccrd->crd_klen >> 3),
@@ -2397,11 +2651,6 @@

 	err = hifn_crypto(sc, cmd, crp, hint);
 	if (!err) {
-		if (enccrd)
-			sc->sc_sessions[session].hs_prev_op =
-				enccrd->crd_flags & CRD_F_ENCRYPT;
-		if (sc->sc_sessions[session].hs_state == HS_STATE_USED)
-			sc->sc_sessions[session].hs_state = HS_STATE_KEY;
 		return 0;
 	} else if (err == ERESTART) {
 		/*
@@ -2498,11 +2747,6 @@
 	}
 	dma->resk = i; dma->resu = u;

-	/* Force upload of key next time */
-	for (i = 0; i < sc->sc_maxses; i++)
-		if (sc->sc_sessions[i].hs_state == HS_STATE_KEY)
-			sc->sc_sessions[i].hs_state = HS_STATE_USED;
-	
 	hifn_reset_board(sc, 1);
 	hifn_init_dma(sc);
 	hifn_init_pci_registers(sc);
@@ -2515,7 +2759,7 @@
 	struct cryptop *crp = cmd->crp;
 	struct cryptodesc *crd;
 	struct mbuf *m;
-	int totlen, i, u;
+	int totlen, i, u, ivlen;

 	if (cmd->src_map == cmd->dst_map) {
 		bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
@@ -2575,17 +2819,18 @@
 	    HIFN_BASE_CMD_CRYPT) {
 		for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
 			if (crd->crd_alg != CRYPTO_DES_CBC &&
-			    crd->crd_alg != CRYPTO_3DES_CBC)
+			    crd->crd_alg != CRYPTO_3DES_CBC &&
+			    crd->crd_alg != CRYPTO_AES_CBC)
 				continue;
+			ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
+				HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
 			if (crp->crp_flags & CRYPTO_F_IMBUF)
 				m_copydata((struct mbuf *)crp->crp_buf,
-				    crd->crd_skip + crd->crd_len - HIFN_IV_LENGTH,
-				    HIFN_IV_LENGTH,
+				    crd->crd_skip + crd->crd_len - ivlen, ivlen,
 				    cmd->softc->sc_sessions[cmd->session_num].hs_iv);
 			else if (crp->crp_flags & CRYPTO_F_IOV) {
 				cuio_copydata((struct uio *)crp->crp_buf,
-				    crd->crd_skip + crd->crd_len - HIFN_IV_LENGTH,
-				    HIFN_IV_LENGTH,
+				    crd->crd_skip + crd->crd_len - ivlen, ivlen,
 				    cmd->softc->sc_sessions[cmd->session_num].hs_iv);
 			}
 			break;
Index: hifn7751reg.h
===================================================================
RCS file: /usr/dfly/repo/src/sys/dev/crypto/hifn/hifn7751reg.h,v
retrieving revision 1.2
diff -u -r1.2 hifn7751reg.h
--- hifn7751reg.h	17 Jun 2003 04:28:27 -0000	1.2
+++ hifn7751reg.h	11 Apr 2007 03:41:10 -0000
@@ -2,7 +2,7 @@
 /* $DragonFly: src/sys/dev/crypto/hifn/hifn7751reg.h,v 1.2 2003/06/17 04:28:27 dillon Exp $ */
 /*	$OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $	*/

-/*
+/*-
  * Invertex AEON / Hifn 7751 driver
  * Copyright (c) 1999 Invertex Inc. All rights reserved.
  * Copyright (c) 1999 Theo de Raadt
@@ -50,8 +50,13 @@
  * Some PCI configuration space offset defines.  The names were made
  * identical to the names used by the Linux kernel.
  */
+#ifdef notyet
 #define	HIFN_BAR0		(PCIR_MAPS+0x0)	/* PUC register map */
 #define	HIFN_BAR1		(PCIR_MAPS+0x4)	/* DMA register map */
+#else
+#define	HIFN_BAR0		PCIR_BAR(0)	/* PUC register map */
+#define	HIFN_BAR1		PCIR_BAR(1)	/* DMA register map */
+#endif
 #define	HIFN_TRDY_TIMEOUT	0x40
 #define	HIFN_RETRY_TIMEOUT	0x41

@@ -64,6 +69,8 @@
 #define	PCI_PRODUCT_HIFN_6500	0x0006		/* 6500 */
 #define	PCI_PRODUCT_HIFN_7811	0x0007		/* 7811 */
 #define	PCI_PRODUCT_HIFN_7951	0x0012		/* 7951 */
+#define	PCI_PRODUCT_HIFN_7955	0x0020		/* 7954/7955 */
+#define	PCI_PRODUCT_HIFN_7956	0x001d		/* 7956 */

 #define	PCI_VENDOR_INVERTEX	0x14e1		/* Invertex */
 #define	PCI_PRODUCT_INVERTEX_AEON 0x0005	/* AEON */
@@ -211,6 +218,7 @@
 #define	HIFN_1_DMA_CSR		0x40	/* DMA Status and Control */
 #define	HIFN_1_DMA_IER		0x44	/* DMA Interrupt Enable */
 #define	HIFN_1_DMA_CNFG		0x48	/* DMA Configuration */
+#define	HIFN_1_PLL		0x4c	/* 7955/7956: PLL config */
 #define	HIFN_1_7811_RNGENA	0x60	/* 7811: rng enable */
 #define	HIFN_1_7811_RNGCFG	0x64	/* 7811: rng config */
 #define	HIFN_1_7811_RNGDAT	0x68	/* 7811: rng data */
@@ -370,6 +378,41 @@
 #define	HIFN_UNLOCK_SECRET1	0xf4
 #define	HIFN_UNLOCK_SECRET2	0xfc

+/*
+ * PLL config register
+ *
+ * This register is present only on 7954/7955/7956 parts. It must be
+ * programmed according to the bus interface method used by the h/w.
+ * Note that the parts require a stable clock.  Since the PCI clock
+ * may vary the reference clock must usually be used.  To avoid
+ * overclocking the core logic, setup must be done carefully, refer
+ * to the driver for details.  The exact multiplier required varies
+ * by part and system configuration; refer to the Hifn documentation.
+ */
+#define	HIFN_PLL_REF_SEL	0x00000001	/* REF/HBI clk selection */
+#define	HIFN_PLL_BP		0x00000002	/* bypass (used during setup) */
+/* bit 2 reserved */
+#define	HIFN_PLL_PK_CLK_SEL	0x00000008	/* public key clk select */
+#define	HIFN_PLL_PE_CLK_SEL	0x00000010	/* packet engine clk select */
+/* bits 5-9 reserved */
+#define	HIFN_PLL_MBSET		0x00000400	/* must be set to 1 */
+#define	HIFN_PLL_ND		0x00003800	/* Fpll_ref multiplier select */
+#define	HIFN_PLL_ND_SHIFT	11
+#define	HIFN_PLL_ND_2		0x00000000	/* 2x */
+#define	HIFN_PLL_ND_4		0x00000800	/* 4x */
+#define	HIFN_PLL_ND_6		0x00001000	/* 6x */
+#define	HIFN_PLL_ND_8		0x00001800	/* 8x */
+#define	HIFN_PLL_ND_10		0x00002000	/* 10x */
+#define	HIFN_PLL_ND_12		0x00002800	/* 12x */
+/* bits 14-15 reserved */
+#define	HIFN_PLL_IS		0x00010000	/* charge pump current select */
+/* bits 17-31 reserved */
+
+/*
+ * Board configuration specifies only these bits.
+ */
+#define	HIFN_PLL_CONFIG		(HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
+
 /*********************************************************************
  * Structs for board commands
  *
@@ -385,6 +428,8 @@
 	volatile u_int16_t total_dest_count;
 } hifn_base_command_t;

+#define	HIFN_BASE_CMD_COMP		0x0100	/* enable compression engine */
+#define	HIFN_BASE_CMD_PAD		0x0200	/* enable padding engine */
 #define	HIFN_BASE_CMD_MAC		0x0400
 #define	HIFN_BASE_CMD_CRYPT		0x0800
 #define	HIFN_BASE_CMD_DECODE		0x2000
@@ -409,7 +454,8 @@
 #define	HIFN_CRYPT_CMD_ALG_DES		0x0000		/*   DES */
 #define	HIFN_CRYPT_CMD_ALG_3DES		0x0001		/*   3DES */
 #define	HIFN_CRYPT_CMD_ALG_RC4		0x0002		/*   RC4 */
-#define	HIFN_CRYPT_CMD_MODE_MASK	0x0018		/* DES mode: */
+#define	HIFN_CRYPT_CMD_ALG_AES		0x0003		/*   AES */
+#define	HIFN_CRYPT_CMD_MODE_MASK	0x0018		/* Encrypt/DES mode: */
 #define	HIFN_CRYPT_CMD_MODE_ECB		0x0000		/*   ECB */
 #define	HIFN_CRYPT_CMD_MODE_CBC		0x0008		/*   CBC */
 #define	HIFN_CRYPT_CMD_MODE_CFB		0x0010		/*   CFB */
@@ -421,6 +467,11 @@
 #define	HIFN_CRYPT_CMD_SRCLEN_M		0xc000
 #define	HIFN_CRYPT_CMD_SRCLEN_S		14

+#define	HIFN_CRYPT_CMD_KSZ_MASK		0x0600		/* AES key size: */
+#define	HIFN_CRYPT_CMD_KSZ_128		0x0000		/*  128 bit */
+#define	HIFN_CRYPT_CMD_KSZ_192		0x0200		/*  192 bit */
+#define	HIFN_CRYPT_CMD_KSZ_256		0x0400		/*  256 bit */
+
 /*
  * Structure to help build up the command data structure.
  */
@@ -452,6 +503,64 @@
 #define	HIFN_MAC_CMD_POS_IPSEC		0x0200
 #define	HIFN_MAC_CMD_NEW_KEY		0x0800

+struct hifn_comp_command {
+	volatile u_int16_t masks;
+	volatile u_int16_t header_skip;
+	volatile u_int16_t source_count;
+	volatile u_int16_t reserved;
+};
+
+#define	HIFN_COMP_CMD_SRCLEN_M		0xc000
+#define	HIFN_COMP_CMD_SRCLEN_S		14
+#define	HIFN_COMP_CMD_ONE		0x0100	/* must be one */
+#define	HIFN_COMP_CMD_CLEARHIST		0x0010	/* clear history */
+#define	HIFN_COMP_CMD_UPDATEHIST	0x0008	/* update history */
+#define	HIFN_COMP_CMD_LZS_STRIP0	0x0004	/* LZS: strip zero */
+#define	HIFN_COMP_CMD_MPPC_RESTART	0x0004	/* MPPC: restart */
+#define	HIFN_COMP_CMD_ALG_MASK		0x0001	/* compression mode: */
+#define	HIFN_COMP_CMD_ALG_MPPC		0x0001	/*   MPPC */
+#define	HIFN_COMP_CMD_ALG_LZS		0x0000	/*   LZS */
+
+struct hifn_base_result {
+	volatile u_int16_t flags;
+	volatile u_int16_t session;
+	volatile u_int16_t src_cnt;		/* 15:0 of source count */
+	volatile u_int16_t dst_cnt;		/* 15:0 of dest count */
+};
+
+#define	HIFN_BASE_RES_DSTOVERRUN	0x0200	/* destination overrun */
+#define	HIFN_BASE_RES_SRCLEN_M		0xc000	/* 17:16 of source count */
+#define	HIFN_BASE_RES_SRCLEN_S		14
+#define	HIFN_BASE_RES_DSTLEN_M		0x3000	/* 17:16 of dest count */
+#define	HIFN_BASE_RES_DSTLEN_S		12
+
+struct hifn_comp_result {
+	volatile u_int16_t flags;
+	volatile u_int16_t crc;
+};
+
+#define	HIFN_COMP_RES_LCB_M		0xff00	/* longitudinal check byte */
+#define	HIFN_COMP_RES_LCB_S		8
+#define	HIFN_COMP_RES_RESTART		0x0004	/* MPPC: restart */
+#define	HIFN_COMP_RES_ENDMARKER		0x0002	/* LZS: end marker seen */
+#define	HIFN_COMP_RES_SRC_NOTZERO	0x0001	/* source expired */
+
+struct hifn_mac_result {
+	volatile u_int16_t flags;
+	volatile u_int16_t reserved;
+	/* followed by 0, 6, 8, or 10 u_int16_t's of the MAC, then crypt */
+};
+
+#define	HIFN_MAC_RES_MISCOMPARE		0x0002	/* compare failed */
+#define	HIFN_MAC_RES_SRC_NOTZERO	0x0001	/* source expired */
+
+struct hifn_crypt_result {
+	volatile u_int16_t flags;
+	volatile u_int16_t reserved;
+};
+
+#define	HIFN_CRYPT_RES_SRC_NOTZERO	0x0001	/* source expired */
+
 /*
  * The poll frequency and poll scalar defines are unshifted values used
  * to set fields in the DMA Configuration Register.
Index: hifn7751var.h
===================================================================
RCS file: /usr/dfly/repo/src/sys/dev/crypto/hifn/hifn7751var.h,v
retrieving revision 1.2
diff -u -r1.2 hifn7751var.h
--- hifn7751var.h	17 Jun 2003 04:28:27 -0000	1.2
+++ hifn7751var.h	11 Apr 2007 03:41:10 -0000
@@ -2,7 +2,7 @@
 /* $DragonFly: src/sys/dev/crypto/hifn/hifn7751var.h,v 1.2 2003/06/17 04:28:27 dillon Exp $ */
 /*	$OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $	*/

-/*
+/*-
  * Invertex AEON / Hifn 7751 driver
  * Copyright (c) 1999 Invertex Inc. All rights reserved.
  * Copyright (c) 1999 Theo de Raadt
@@ -68,6 +68,8 @@
 #define HIFN_3DES_KEY_LENGTH		24
 #define HIFN_MAX_CRYPT_KEY_LENGTH	HIFN_3DES_KEY_LENGTH
 #define HIFN_IV_LENGTH			8
+#define	HIFN_AES_IV_LENGTH		16
+#define HIFN_MAX_IV_LENGTH		HIFN_AES_IV_LENGTH

 /*
  *  Length values for authentication
@@ -110,9 +112,8 @@
 };

 struct hifn_session {
-	int hs_state;
-	int hs_prev_op; /* XXX collapse into hs_flags? */
-	u_int8_t hs_iv[HIFN_IV_LENGTH];
+	int hs_used;
+	u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
 };

 #define	HIFN_RING_SYNC(sc, r, i, f)					\
@@ -137,8 +138,7 @@
 /*
  * Holds data specific to a single HIFN board.
  */
-struct hifn_softc {
-	device_t		sc_dev;		/* device backpointer */
+struct hifn_softc { device_t		sc_dev;		/* device backpointer */
 	bus_dma_tag_t		sc_dmat;	/* parent DMA tag decriptor */
 	struct resource		*sc_bar0res;
 	bus_space_handle_t	sc_sh0;		/* bar0 bus space handle */
@@ -153,7 +153,7 @@

 	u_int32_t		sc_dmaier;
 	u_int32_t		sc_drammodel;	/* 1=dram, 0=sram */
-
+	u_int32_t		sc_pllconfig;	/* 7954/7955/7956 PLL config */

 	struct hifn_dma		*sc_dma;
 	bus_dmamap_t		sc_dmamap;
@@ -162,11 +162,15 @@
 	int			sc_dmansegs;
 	int32_t			sc_cid;
 	int			sc_maxses;
+	int			sc_nsessions;
+	struct hifn_session	*sc_sessions;
 	int			sc_ramsize;
 	int			sc_flags;
 #define	HIFN_HAS_RNG		0x1	/* includes random number generator */
 #define	HIFN_HAS_PUBLIC		0x2	/* includes public key support */
-#define	HIFN_IS_7811		0x4	/* Hifn 7811 part */
+#define	HIFN_HAS_AES		0x4	/* includes AES support */
+#define	HIFN_IS_7811		0x8	/* Hifn 7811 part */
+#define	HIFN_IS_7956		0x10	/* Hifn 7956/7955 don't have SDRAM */
 	struct callout		sc_rngto;	/* for polling RNG */
 	struct callout		sc_tickto;	/* for managing DMA */
 	int			sc_rngfirst;
@@ -182,7 +186,6 @@
 	int			sc_needwakeup;	/* ops q'd wating on resources */
 	int			sc_curbatch;	/* # ops submitted w/o int */
 	int			sc_suspended;
-	struct hifn_session	sc_sessions[2048];
 };

 /*
@@ -263,7 +266,7 @@
 struct hifn_command {
 	u_int16_t session_num;
 	u_int16_t base_masks, cry_masks, mac_masks;
-	u_int8_t iv[HIFN_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
+	u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
 	int cklen;
 	int sloplen, slopidx;







More information about the Submit mailing list