[kernel] update ocf-linux to 20080917
authorGabor Juhos <juhosg@openwrt.org>
Tue, 18 Nov 2008 20:45:28 +0000 (20:45 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Tue, 18 Nov 2008 20:45:28 +0000 (20:45 +0000)
SVN-Revision: 13282

18 files changed:
target/linux/generic-2.6/config-2.6.25
target/linux/generic-2.6/config-2.6.26
target/linux/generic-2.6/config-2.6.27
target/linux/generic-2.6/patches-2.6.25/950-ocf-linux-26-20080704.patch [deleted file]
target/linux/generic-2.6/patches-2.6.25/951-ocf-scatterlist-inc.patch [deleted file]
target/linux/generic-2.6/patches-2.6.25/970-ocf_kbuild_integration.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.25/971-ocf_20080917.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.25/972-ocf_compile_fix.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.26/970-ocf_20080704.patch [deleted file]
target/linux/generic-2.6/patches-2.6.26/970-ocf_kbuild_integration.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.26/971-ocf_20080917.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.26/971-ocf_compile_fix.patch [deleted file]
target/linux/generic-2.6/patches-2.6.26/972-ocf_compile_fix.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.27/970-ocf_20080704.patch [deleted file]
target/linux/generic-2.6/patches-2.6.27/970-ocf_kbuild_integration.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.27/971-ocf_20080917.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.27/971-ocf_compile_fix.patch [deleted file]
target/linux/generic-2.6/patches-2.6.27/972-ocf_compile_fix.patch [new file with mode: 0644]

index aa25b96..2178e96 100644 (file)
@@ -1016,11 +1016,13 @@ CONFIG_NORTEL_HERMES=m
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_OCF_BENCH is not set
+# CONFIG_OCF_EP80579 is not set
 # CONFIG_OCF_IXP4XX is not set
 # CONFIG_OCF_HIFN is not set
 # CONFIG_OCF_HIFNHIPP is not set
 # CONFIG_OCF_SAFE is not set
 # CONFIG_OCF_TALITOS is not set
+# CONFIG_OCF_OCF is not set
 # CONFIG_OCF_OCFNULL is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_OSF_PARTITION is not set
index 72ad1df..99598f4 100644 (file)
@@ -1045,11 +1045,13 @@ CONFIG_NORTEL_HERMES=m
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_OCF_BENCH is not set
+# CONFIG_OCF_EP80579 is not set
 # CONFIG_OCF_IXP4XX is not set
 # CONFIG_OCF_HIFN is not set
 # CONFIG_OCF_HIFNHIPP is not set
 # CONFIG_OCF_SAFE is not set
 # CONFIG_OCF_TALITOS is not set
+# CONFIG_OCF_OCF is not set
 # CONFIG_OCF_OCFNULL is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_OSF_PARTITION is not set
index 5a62a2f..3cfd3ef 100644 (file)
@@ -1094,6 +1094,7 @@ CONFIG_NORTEL_HERMES=m
 # CONFIG_NTFS_RW is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_OCF_BENCH is not set
+# CONFIG_OCF_EP80579 is not set
 # CONFIG_OCF_HIFN is not set
 # CONFIG_OCF_HIFNHIPP is not set
 # CONFIG_OCF_IXP4XX is not set
diff --git a/target/linux/generic-2.6/patches-2.6.25/950-ocf-linux-26-20080704.patch b/target/linux/generic-2.6/patches-2.6.25/950-ocf-linux-26-20080704.patch
deleted file mode 100644 (file)
index 7912a4e..0000000
+++ /dev/null
@@ -1,19465 +0,0 @@
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -593,3 +593,6 @@ config CRYPTO_LZO
- source "drivers/crypto/Kconfig"
- endif # if CRYPTO
-+
-+source "crypto/ocf/Kconfig"
-+
---- a/crypto/Makefile
-+++ b/crypto/Makefile
-@@ -65,6 +65,8 @@ obj-$(CONFIG_CRYPTO_LZO) += lzo.o
- obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
-+obj-$(CONFIG_OCF_OCF) += ocf/
-+
- #
- # generic algorithms and the async_tx api
- #
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -129,6 +129,9 @@
-  *                                unsigned int value);
-  *    void add_interrupt_randomness(int irq);
-  *
-+ *      void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
-+ *      int random_input_wait(void);
-+ *
-  * add_input_randomness() uses the input layer interrupt timing, as well as
-  * the event type information from the hardware.
-  *
-@@ -140,6 +143,13 @@
-  * a better measure, since the timing of the disk interrupts are more
-  * unpredictable.
-  *
-+ * random_input_words() just provides a raw block of entropy to the input
-+ * pool, such as from a hardware entropy generator.
-+ *
-+ * random_input_wait() suspends the caller until such time as the
-+ * entropy pool falls below the write threshold, and returns a count of how
-+ * much entropy (in bits) is needed to sustain the pool.
-+ *
-  * All of these routines try to estimate how many bits of randomness a
-  * particular randomness source.  They do this by keeping track of the
-  * first and second order deltas of the event timings.
-@@ -669,6 +679,61 @@ void add_disk_randomness(struct gendisk 
- }
- #endif
-+/*
-+ * random_input_words - add bulk entropy to pool
-+ *
-+ * @buf: buffer to add
-+ * @wordcount: number of __u32 words to add
-+ * @ent_count: total amount of entropy (in bits) to credit
-+ *
-+ * this provides bulk input of entropy to the input pool
-+ *
-+ */
-+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
-+{
-+      add_entropy_words(&input_pool, buf, wordcount);
-+
-+      credit_entropy_store(&input_pool, ent_count);
-+
-+      DEBUG_ENT("crediting %d bits => %d\n",
-+                ent_count, input_pool.entropy_count);
-+      /*
-+       * Wake up waiting processes if we have enough
-+       * entropy.
-+       */
-+      if (input_pool.entropy_count >= random_read_wakeup_thresh)
-+              wake_up_interruptible(&random_read_wait);
-+}
-+EXPORT_SYMBOL(random_input_words);
-+
-+/*
-+ * random_input_wait - wait until random needs entropy
-+ *
-+ * this function sleeps until the /dev/random subsystem actually
-+ * needs more entropy, and then return the amount of entropy
-+ * that it would be nice to have added to the system.
-+ */
-+int random_input_wait(void)
-+{
-+      int count;
-+
-+      wait_event_interruptible(random_write_wait, 
-+                       input_pool.entropy_count < random_write_wakeup_thresh);
-+
-+      count = random_write_wakeup_thresh - input_pool.entropy_count;
-+
-+        /* likely we got woken up due to a signal */
-+      if (count <= 0) count = random_read_wakeup_thresh; 
-+
-+      DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
-+                count,
-+                input_pool.entropy_count, random_write_wakeup_thresh);
-+
-+      return count;
-+}
-+EXPORT_SYMBOL(random_input_wait);
-+
-+
- #define EXTRACT_SIZE 10
- /*********************************************************************
---- a/fs/fcntl.c
-+++ b/fs/fcntl.c
-@@ -202,6 +202,7 @@ asmlinkage long sys_dup(unsigned int fil
-               ret = dupfd(file, 0, 0);
-       return ret;
- }
-+EXPORT_SYMBOL(sys_dup);
- #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME)
---- a/include/linux/miscdevice.h
-+++ b/include/linux/miscdevice.h
-@@ -12,6 +12,7 @@
- #define APOLLO_MOUSE_MINOR 7
- #define PC110PAD_MINOR 9
- /*#define ADB_MOUSE_MINOR 10  FIXME OBSOLETE */
-+#define CRYPTODEV_MINOR               70      /* /dev/crypto */
- #define WATCHDOG_MINOR                130     /* Watchdog timer     */
- #define TEMP_MINOR            131     /* Temperature Sensor */
- #define RTC_MINOR 135
---- a/include/linux/random.h
-+++ b/include/linux/random.h
-@@ -8,6 +8,7 @@
- #define _LINUX_RANDOM_H
- #include <linux/ioctl.h>
-+#include <linux/types.h> /* for __u32 in user space */
- /* ioctl()'s for the random number generator */
-@@ -32,6 +33,30 @@
- /* Clear the entropy pool and associated counters.  (Superuser only.) */
- #define RNDCLEARPOOL  _IO( 'R', 0x06 )
-+#ifdef CONFIG_FIPS_RNG
-+
-+/* Size of seed value - equal to AES blocksize */
-+#define AES_BLOCK_SIZE_BYTES  16
-+#define SEED_SIZE_BYTES                       AES_BLOCK_SIZE_BYTES
-+/* Size of AES key */
-+#define KEY_SIZE_BYTES                16
-+
-+/* ioctl() structure used by FIPS 140-2 Tests */
-+struct rand_fips_test {
-+      unsigned char key[KEY_SIZE_BYTES];                      /* Input */
-+      unsigned char datetime[SEED_SIZE_BYTES];        /* Input */
-+      unsigned char seed[SEED_SIZE_BYTES];            /* Input */
-+      unsigned char result[SEED_SIZE_BYTES];          /* Output */
-+};
-+
-+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
-+#define RNDFIPSVST    _IOWR('R', 0x10, struct rand_fips_test)
-+
-+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
-+#define RNDFIPSMCT    _IOWR('R', 0x11, struct rand_fips_test)
-+
-+#endif /* #ifdef CONFIG_FIPS_RNG */
-+
- struct rand_pool_info {
-       int     entropy_count;
-       int     buf_size;
-@@ -48,6 +73,10 @@ extern void add_input_randomness(unsigne
-                                unsigned int value);
- extern void add_interrupt_randomness(int irq);
-+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
-+extern int random_input_wait(void);
-+#define HAS_RANDOM_INPUT_WAIT 1
-+
- extern void get_random_bytes(void *buf, int nbytes);
- void generate_random_uuid(unsigned char uuid_out[16]);
---- /dev/null
-+++ b/crypto/ocf/hifn/Makefile
-@@ -0,0 +1,13 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+obj-$(CONFIG_OCF_HIFN)     += hifn7751.o
-+obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
-+
-+obj ?= .
-+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null
-+++ b/crypto/ocf/safe/Makefile
-@@ -0,0 +1,12 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+obj-$(CONFIG_OCF_SAFE) += safe.o
-+
-+obj ?= .
-+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null
-+++ b/crypto/ocf/Makefile
-@@ -0,0 +1,120 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+OCF_OBJS = crypto.o criov.o
-+
-+ifdef CONFIG_OCF_RANDOMHARVEST
-+      OCF_OBJS += random.o
-+endif
-+
-+ifdef CONFIG_OCF_FIPS
-+      OCF_OBJS += rndtest.o
-+endif
-+
-+# Add in autoconf.h to get #defines for CONFIG_xxx
-+AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
-+ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
-+      EXTRA_CFLAGS += -include $(AUTOCONF_H)
-+      export EXTRA_CFLAGS
-+endif
-+
-+ifndef obj
-+      obj ?= .
-+      _obj = subdir
-+      mod-subdirs := safe hifn ixp4xx talitos ocfnull
-+      export-objs += crypto.o criov.o random.o
-+      list-multi += ocf.o
-+      _slash :=
-+else
-+      _obj = obj
-+      _slash := /
-+endif
-+
-+EXTRA_CFLAGS += -I$(obj)/.
-+
-+obj-$(CONFIG_OCF_OCF)         += ocf.o
-+obj-$(CONFIG_OCF_CRYPTODEV)   += cryptodev.o
-+obj-$(CONFIG_OCF_CRYPTOSOFT)  += cryptosoft.o
-+obj-$(CONFIG_OCF_BENCH)       += ocf-bench.o
-+
-+$(_obj)-$(CONFIG_OCF_SAFE)    += safe$(_slash)
-+$(_obj)-$(CONFIG_OCF_HIFN)    += hifn$(_slash)
-+$(_obj)-$(CONFIG_OCF_IXP4XX)  += ixp4xx$(_slash)
-+$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
-+$(_obj)-$(CONFIG_OCF_PASEMI)  += pasemi$(_slash)
-+$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
-+
-+ocf-objs := $(OCF_OBJS)
-+
-+$(list-multi) dummy1: $(ocf-objs)
-+      $(LD) -r -o $@ $(ocf-objs)
-+
-+.PHONY:
-+clean:
-+      rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
-+      rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
-+#
-+# release gen targets
-+#
-+
-+.PHONY: patch
-+patch:
-+      REL=`date +%Y%m%d`; \
-+              patch=ocf-linux-$$REL.patch; \
-+              patch24=ocf-linux-24-$$REL.patch; \
-+              patch26=ocf-linux-26-$$REL.patch; \
-+              ( \
-+                      find . -name Makefile; \
-+                      find . -name Config.in; \
-+                      find . -name Kconfig; \
-+                      find . -name README; \
-+                      find . -name '*.[ch]' | grep -v '.mod.c'; \
-+              ) | while read t; do \
-+                      diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
-+              done > $$patch; \
-+              cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
-+              cat patches/linux-2.6.25-ocf.patch $$patch > $$patch26
-+
-+.PHONY: tarball
-+tarball:
-+      REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
-+              CURDIR=`pwd`; \
-+              rm -rf /tmp/ocf-linux-$$REL*; \
-+              mkdir -p $$RELDIR/tools; \
-+              cp README* $$RELDIR; \
-+              cp patches/openss*.patch $$RELDIR; \
-+              cp patches/crypto-tools.patch $$RELDIR; \
-+              cp tools/[!C]* $$RELDIR/tools; \
-+              cd ..; \
-+              tar cvf $$RELDIR/ocf-linux.tar \
-+                                      --exclude=CVS \
-+                                      --exclude=.* \
-+                                      --exclude=*.o \
-+                                      --exclude=*.ko \
-+                                      --exclude=*.mod.* \
-+                                      --exclude=README* \
-+                                      --exclude=ocf-*.patch \
-+                                      --exclude=ocf/patches/openss*.patch \
-+                                      --exclude=ocf/patches/crypto-tools.patch \
-+                                      --exclude=ocf/tools \
-+                                      ocf; \
-+              gzip -9 $$RELDIR/ocf-linux.tar; \
-+              cd /tmp; \
-+              tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
-+              gzip -9 ocf-linux-$$REL.tar; \
-+              cd $$CURDIR/../../user; \
-+              rm -rf /tmp/crypto-tools-$$REL*; \
-+              tar cvf /tmp/crypto-tools-$$REL.tar \
-+                                      --exclude=CVS \
-+                                      --exclude=.* \
-+                                      --exclude=*.o \
-+                                      --exclude=cryptotest \
-+                                      --exclude=cryptokeytest \
-+                                      crypto-tools; \
-+              gzip -9 /tmp/crypto-tools-$$REL.tar
-+
---- /dev/null
-+++ b/crypto/ocf/talitos/Makefile
-@@ -0,0 +1,12 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+obj-$(CONFIG_OCF_TALITOS) += talitos.o
-+
-+obj ?= .
-+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null
-+++ b/crypto/ocf/ixp4xx/Makefile
-@@ -0,0 +1,104 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+#
-+# You will need to point this at your Intel ixp425 includes,  this portion
-+# of the Makefile only really works under SGLinux with the appropriate libs
-+# installed.  They can be downloaded from http://www.snapgear.org/
-+#
-+ifeq ($(CONFIG_CPU_IXP46X),y)
-+IXPLATFORM = ixp46X
-+else
-+ifeq ($(CONFIG_CPU_IXP43X),y)
-+IXPLATFORM = ixp43X
-+else
-+IXPLATFORM = ixp42X
-+endif
-+endif
-+
-+ifdef CONFIG_IXP400_LIB_2_4
-+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
-+OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
-+endif
-+ifdef CONFIG_IXP400_LIB_2_1
-+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
-+OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
-+endif
-+ifdef CONFIG_IXP400_LIB_2_0
-+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
-+OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
-+endif
-+ifdef IX_XSCALE_SW
-+ifdef CONFIG_IXP400_LIB_2_4
-+IXP_CFLAGS = \
-+      -I$(ROOTDIR)/. \
-+      -I$(IX_XSCALE_SW)/src/include \
-+      -I$(OSAL_DIR)/common/include/ \
-+      -I$(OSAL_DIR)/common/include/modules/ \
-+      -I$(OSAL_DIR)/common/include/modules/ddk/ \
-+      -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
-+      -I$(OSAL_DIR)/common/include/modules/ioMem/ \
-+      -I$(OSAL_DIR)/common/os/linux/include/ \
-+      -I$(OSAL_DIR)/common/os/linux/include/core/  \
-+      -I$(OSAL_DIR)/common/os/linux/include/modules/ \
-+      -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
-+      -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
-+      -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
-+      -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
-+      -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
-+      -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
-+      -DUSE_IXP4XX_CRYPTO
-+else
-+IXP_CFLAGS = \
-+      -I$(ROOTDIR)/. \
-+      -I$(IX_XSCALE_SW)/src/include \
-+      -I$(OSAL_DIR)/ \
-+      -I$(OSAL_DIR)/os/linux/include/ \
-+      -I$(OSAL_DIR)/os/linux/include/modules/ \
-+      -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
-+      -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
-+      -I$(OSAL_DIR)/os/linux/include/core/  \
-+      -I$(OSAL_DIR)/os/linux/include/platforms/ \
-+      -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
-+      -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
-+      -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
-+      -I$(OSAL_DIR)/os/linux/include/core/ \
-+      -I$(OSAL_DIR)/include/ \
-+      -I$(OSAL_DIR)/include/modules/ \
-+      -I$(OSAL_DIR)/include/modules/bufferMgt/ \
-+      -I$(OSAL_DIR)/include/modules/ioMem/ \
-+      -I$(OSAL_DIR)/include/platforms/ \
-+      -I$(OSAL_DIR)/include/platforms/ixp400/ \
-+      -DUSE_IXP4XX_CRYPTO
-+endif
-+endif
-+ifdef CONFIG_IXP400_LIB_1_4
-+IXP_CFLAGS   = \
-+      -I$(ROOTDIR)/. \
-+      -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
-+      -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
-+      -DUSE_IXP4XX_CRYPTO
-+endif
-+ifndef IXPDIR
-+IXPDIR = ixp-version-is-not-supported
-+endif
-+
-+ifeq ($(CONFIG_CPU_IXP46X),y)
-+IXP_CFLAGS += -D__ixp46X
-+else
-+ifeq ($(CONFIG_CPU_IXP43X),y)
-+IXP_CFLAGS += -D__ixp43X
-+else
-+IXP_CFLAGS += -D__ixp42X
-+endif
-+endif
-+
-+obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
-+
-+obj ?= .
-+EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null
-+++ b/crypto/ocf/ocfnull/Makefile
-@@ -0,0 +1,12 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
-+
-+obj ?= .
-+EXTRA_CFLAGS += -I$(obj)/..
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null
-+++ b/crypto/ocf/pasemi/Makefile
-@@ -0,0 +1,12 @@
-+# for SGlinux builds
-+-include $(ROOTDIR)/modules/.config
-+
-+obj-$(CONFIG_OCF_PASEMI) += pasemi.o
-+
-+obj ?= .
-+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
-+
-+ifdef TOPDIR
-+-include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null
-+++ b/crypto/ocf/Config.in
-@@ -0,0 +1,32 @@
-+#############################################################################
-+
-+mainmenu_option next_comment
-+comment 'OCF Configuration'
-+tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
-+dep_mbool '  enable fips RNG checks (fips check on RNG data before use)' \
-+                              CONFIG_OCF_FIPS $CONFIG_OCF_OCF
-+dep_mbool '  enable harvesting entropy for /dev/random' \
-+                              CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
-+dep_tristate '  cryptodev (user space support)' \
-+                              CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
-+dep_tristate '  cryptosoft (software crypto engine)' \
-+                              CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
-+dep_tristate '  safenet (HW crypto engine)' \
-+                              CONFIG_OCF_SAFE $CONFIG_OCF_OCF
-+dep_tristate '  IXP4xx (HW crypto engine)' \
-+                              CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
-+dep_mbool    '  Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
-+                              CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
-+dep_tristate '  hifn (HW crypto engine)' \
-+                              CONFIG_OCF_HIFN $CONFIG_OCF_OCF
-+dep_tristate '  talitos (HW crypto engine)' \
-+                              CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
-+dep_tristate '  pasemi (HW crypto engine)' \
-+                              CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
-+dep_tristate '  ocfnull (does no crypto)' \
-+                              CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
-+dep_tristate '  ocf-bench (HW crypto in-kernel benchmark)' \
-+                              CONFIG_OCF_BENCH $CONFIG_OCF_OCF
-+endmenu
-+
-+#############################################################################
---- /dev/null
-+++ b/crypto/ocf/Kconfig
-@@ -0,0 +1,95 @@
-+menu "OCF Configuration"
-+
-+config OCF_OCF
-+      tristate "OCF (Open Cryptograhic Framework)"
-+      help
-+        A linux port of the OpenBSD/FreeBSD crypto framework.
-+
-+config OCF_RANDOMHARVEST
-+      bool "crypto random --- harvest entropy for /dev/random"
-+      depends on OCF_OCF
-+      help
-+        Includes code to harvest random numbers from devices that support it.
-+
-+config OCF_FIPS
-+      bool "enable fips RNG checks"
-+      depends on OCF_OCF && OCF_RANDOMHARVEST
-+      help
-+        Run all RNG provided data through a fips check before
-+        adding it /dev/random's entropy pool.
-+
-+config OCF_CRYPTODEV
-+      tristate "cryptodev (user space support)"
-+      depends on OCF_OCF
-+      help
-+        The user space API to access crypto hardware.
-+
-+config OCF_CRYPTOSOFT
-+      tristate "cryptosoft (software crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        A software driver for the OCF framework that uses
-+        the kernel CryptoAPI.
-+
-+config OCF_SAFE
-+      tristate "safenet (HW crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        A driver for a number of the safenet Excel crypto accelerators.
-+        Currently tested and working on the 1141 and 1741.
-+
-+config OCF_IXP4XX
-+      tristate "IXP4xx (HW crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        XScale IXP4xx crypto accelerator driver.  Requires the
-+        Intel Access library.
-+
-+config OCF_IXP4XX_SHA1_MD5
-+      bool "IXP4xx SHA1 and MD5 Hashing"
-+      depends on OCF_IXP4XX
-+      help
-+        Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
-+        Note: this is MUCH slower than using cryptosoft (software crypto engine).
-+
-+config OCF_HIFN
-+      tristate "hifn (HW crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        OCF driver for various HIFN based crypto accelerators.
-+        (7951, 7955, 7956, 7751, 7811)
-+
-+config OCF_HIFNHIPP
-+      tristate "Hifn HIPP (HW packet crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        OCF driver for various HIFN (HIPP) based crypto accelerators
-+        (7855)
-+
-+config OCF_TALITOS
-+      tristate "talitos (HW crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        OCF driver for Freescale's security engine (SEC/talitos).
-+
-+config OCF_PASEMI
-+        tristate "pasemi (HW crypto engine)"
-+        depends on OCF_OCF && PPC_PASEMI
-+        help
-+          OCF driver for for PA Semi PWRficient DMA Engine
-+
-+config OCF_OCFNULL
-+      tristate "ocfnull (fake crypto engine)"
-+      depends on OCF_OCF
-+      help
-+        OCF driver for measuring ipsec overheads (does no crypto)
-+
-+config OCF_BENCH
-+      tristate "ocf-bench (HW crypto in-kernel benchmark)"
-+      depends on OCF_OCF
-+      help
-+        A very simple encryption test for the in-kernel interface
-+        of OCF.  Also includes code to benchmark the IXP Access library
-+        for comparison.
-+
-+endmenu
---- /dev/null
-+++ b/crypto/ocf/README
-@@ -0,0 +1,166 @@
-+README - ocf-linux-20071215
-+---------------------------
-+
-+This README provides instructions for getting ocf-linux compiled and
-+operating in a generic linux environment.  For other information you
-+might like to visit the home page for this project:
-+
-+    http://ocf-linux.sourceforge.net/
-+
-+Adding OCF to linux
-+-------------------
-+
-+    Not much in this file for now,  just some notes.  I usually build
-+    the ocf support as modules but it can be built into the kernel as
-+    well.  To use it:
-+
-+    * mknod /dev/crypto c 10 70
-+
-+    * to add OCF to your kernel source,  you have two options.  Apply
-+      the kernel specific patch:
-+
-+          cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
-+          cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
-+    
-+      if you do one of the above,  then you can proceed to the next step,
-+      or you can do the above process by hand with using the patches against
-+      linux-2.4.35 and 2.6.23 to include the ocf code under crypto/ocf.
-+      Here's how to add it:
-+
-+      for 2.4.35 (and later)
-+
-+          cd linux-2.4.35/crypto
-+          tar xvzf ocf-linux.tar.gz
-+          cd ..
-+          patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
-+
-+      for 2.6.23 (and later)
-+
-+          cd linux-2.6.23/crypto
-+          tar xvzf ocf-linux.tar.gz
-+          cd ..
-+          patch -p1 < crypto/ocf/patches/linux-2.6.23-ocf.patch
-+
-+      It should be easy to take this patch and apply it to other more
-+      recent versions of the kernels.  The same patches should also work
-+      relatively easily on kernels as old as 2.6.11 and 2.4.18.
-+      
-+    * under 2.4 if you are on a non-x86 platform,  you may need to:
-+
-+        cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
-+
-+      so that you can build the kernel crypto support needed for the cryptosoft
-+      driver.
-+
-+    * For simplicity you should enable all the crypto support in your kernel
-+      except for the test driver.  Likewise for the OCF options.  Do not
-+      enable OCF crypto drivers for HW that you do not have (for example
-+      ixp4xx will not compile on non-Xscale systems).
-+
-+    * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
-+      crypto/cryptodev.h in an include directory that is used for building
-+      applications for your platform.  For example on a host system that
-+      might be:
-+
-+              /usr/include/crypto/cryptodev.h
-+
-+    * patch your openssl-0.9.8g code with the openssl-0.9.8g.patch.
-+      (NOTE: there is no longer a need to patch ssh). The patch is against:
-+      openssl-0_9_8e
-+
-+      If you need a patch for an older version of openssl,  you should look
-+      to older OCF releases.  This patch is unlikely to work on older
-+      openssl versions.
-+
-+      openssl-0.9.8g.patch
-+                - enables --with-cryptodev for non BSD systems
-+                - adds -cpu option to openssl speed for calculating CPU load
-+                  under linux
-+                - fixes null pointer in openssl speed multi thread output.
-+                - fixes test keys to work with linux crypto's more stringent
-+                  key checking.
-+                - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
-+                  with the --with-cryptodev-digests option
-+                - fixes bug in engine code caching.
-+
-+    * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
-+      tools for testing OCF (ie., cryptotest).
-+
-+How to load the OCF drivers
-+---------------------------
-+
-+    First insert the base modules:
-+
-+        insmod ocf
-+        insmod cryptodev
-+
-+    You can then install the software OCF driver with:
-+
-+        insmod cryptosoft
-+
-+    and one or more of the OCF HW drivers with:
-+
-+        insmod safe
-+        insmod hifn7751
-+        insmod ixp4xx
-+        ...
-+
-+    all the drivers take a debug option to enable verbose debug so that
-+    you can see what is going on.  For debug you load them as:
-+
-+        insmod ocf crypto_debug=1
-+        insmod cryptodev cryptodev_debug=1
-+        insmod cryptosoft swcr_debug=1
-+
-+    You may load more than one OCF crypto driver but then there is no guarantee
-+    as to which will be used.
-+
-+    You can also enable debug at run time on 2.6 systems with the following:
-+
-+        echo 1 > /sys/module/ocf/parameters/crypto_debug
-+        echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
-+        echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
-+        echo 1 > /sys/module/hifn7751/parameters/hifn_debug
-+        echo 1 > /sys/module/safe/parameters/safe_debug
-+        echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
-+        ...
-+
-+Testing the OCF support
-+-----------------------
-+
-+    run "cryptotest",  it should do a short test for a couple of
-+    des packets.  If it does everything is working.
-+
-+    If this works,  then ssh will use the driver when invoked as:
-+
-+        ssh -c 3des username@host
-+
-+    to see for sure that it is operating, enable debug as defined above.
-+
-+    To get a better idea of performance run:
-+
-+        cryptotest 100 4096
-+
-+    There are more options to cryptotest,  see the help.
-+
-+    It is also possible to use openssl to test the speed of the crypto
-+    drivers.
-+
-+        openssl speed -evp des -engine cryptodev -elapsed
-+        openssl speed -evp des3 -engine cryptodev -elapsed
-+        openssl speed -evp aes128 -engine cryptodev -elapsed
-+
-+    and multiple threads (10) with:
-+
-+        openssl speed -evp des -engine cryptodev -elapsed -multi 10
-+        openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
-+        openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
-+
-+    for public key testing you can try:
-+
-+        cryptokeytest
-+        openssl speed -engine cryptodev rsa -elapsed
-+        openssl speed -engine cryptodev dsa -elapsed
-+
-+David McCullough
-+david_mccullough@securecomputing.com
---- /dev/null
-+++ b/crypto/ocf/hifn/hifn7751reg.h
-@@ -0,0 +1,540 @@
-+/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam 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
-+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.
-+ *                    http://www.netsec.net
-+ *
-+ * Please send any comments, feedback, bug-fixes, or feature requests to
-+ * software@invertex.com.
-+ *
-+ * 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.
-+ *
-+ * Effort sponsored in part by the Defense Advanced Research Projects
-+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
-+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
-+ *
-+ */
-+#ifndef __HIFN_H__
-+#define       __HIFN_H__
-+
-+/*
-+ * Some PCI configuration space offset defines.  The names were made
-+ * identical to the names used by the Linux kernel.
-+ */
-+#define       HIFN_BAR0               PCIR_BAR(0)     /* PUC register map */
-+#define       HIFN_BAR1               PCIR_BAR(1)     /* DMA register map */
-+#define       HIFN_TRDY_TIMEOUT       0x40
-+#define       HIFN_RETRY_TIMEOUT      0x41
-+
-+/*
-+ * PCI vendor and device identifiers
-+ * (the names are preserved from their OpenBSD source).
-+ */
-+#define       PCI_VENDOR_HIFN         0x13a3          /* Hifn */
-+#define       PCI_PRODUCT_HIFN_7751   0x0005          /* 7751 */
-+#define       PCI_PRODUCT_HIFN_6500   0x0006          /* 6500 */
-+#define       PCI_PRODUCT_HIFN_7811   0x0007          /* 7811 */
-+#define       PCI_PRODUCT_HIFN_7855   0x001f          /* 7855 */
-+#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 */
-+
-+#define       PCI_VENDOR_NETSEC       0x1660          /* NetSec */
-+#define       PCI_PRODUCT_NETSEC_7751 0x7751          /* 7751 */
-+
-+/*
-+ * The values below should multiple of 4 -- and be large enough to handle
-+ * any command the driver implements.
-+ *
-+ * MAX_COMMAND = base command + mac command + encrypt command +
-+ *                    mac-key + rc4-key
-+ * MAX_RESULT  = base result + mac result + mac + encrypt result
-+ *                    
-+ *
-+ */
-+#define       HIFN_MAX_COMMAND        (8 + 8 + 8 + 64 + 260)
-+#define       HIFN_MAX_RESULT         (8 + 4 + 20 + 4)
-+
-+/*
-+ * hifn_desc_t
-+ *
-+ * Holds an individual descriptor for any of the rings.
-+ */
-+typedef struct hifn_desc {
-+      volatile u_int32_t l;           /* length and status bits */
-+      volatile u_int32_t p;
-+} hifn_desc_t;
-+
-+/*
-+ * Masks for the "length" field of struct hifn_desc.
-+ */
-+#define       HIFN_D_LENGTH           0x0000ffff      /* length bit mask */
-+#define       HIFN_D_MASKDONEIRQ      0x02000000      /* mask the done interrupt */
-+#define       HIFN_D_DESTOVER         0x04000000      /* destination overflow */
-+#define       HIFN_D_OVER             0x08000000      /* overflow */
-+#define       HIFN_D_LAST             0x20000000      /* last descriptor in chain */
-+#define       HIFN_D_JUMP             0x40000000      /* jump descriptor */
-+#define       HIFN_D_VALID            0x80000000      /* valid bit */
-+
-+
-+/*
-+ * Processing Unit Registers (offset from BASEREG0)
-+ */
-+#define       HIFN_0_PUDATA           0x00    /* Processing Unit Data */
-+#define       HIFN_0_PUCTRL           0x04    /* Processing Unit Control */
-+#define       HIFN_0_PUISR            0x08    /* Processing Unit Interrupt Status */
-+#define       HIFN_0_PUCNFG           0x0c    /* Processing Unit Configuration */
-+#define       HIFN_0_PUIER            0x10    /* Processing Unit Interrupt Enable */
-+#define       HIFN_0_PUSTAT           0x14    /* Processing Unit Status/Chip ID */
-+#define       HIFN_0_FIFOSTAT         0x18    /* FIFO Status */
-+#define       HIFN_0_FIFOCNFG         0x1c    /* FIFO Configuration */
-+#define       HIFN_0_PUCTRL2          0x28    /* Processing Unit Control (2nd map) */
-+#define       HIFN_0_MUTE1            0x80
-+#define       HIFN_0_MUTE2            0x90
-+#define       HIFN_0_SPACESIZE        0x100   /* Register space size */
-+
-+/* Processing Unit Control Register (HIFN_0_PUCTRL) */
-+#define       HIFN_PUCTRL_CLRSRCFIFO  0x0010  /* clear source fifo */
-+#define       HIFN_PUCTRL_STOP        0x0008  /* stop pu */
-+#define       HIFN_PUCTRL_LOCKRAM     0x0004  /* lock ram */
-+#define       HIFN_PUCTRL_DMAENA      0x0002  /* enable dma */
-+#define       HIFN_PUCTRL_RESET       0x0001  /* Reset processing unit */
-+
-+/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
-+#define       HIFN_PUISR_CMDINVAL     0x8000  /* Invalid command interrupt */
-+#define       HIFN_PUISR_DATAERR      0x4000  /* Data error interrupt */
-+#define       HIFN_PUISR_SRCFIFO      0x2000  /* Source FIFO ready interrupt */
-+#define       HIFN_PUISR_DSTFIFO      0x1000  /* Destination FIFO ready interrupt */
-+#define       HIFN_PUISR_DSTOVER      0x0200  /* Destination overrun interrupt */
-+#define       HIFN_PUISR_SRCCMD       0x0080  /* Source command interrupt */
-+#define       HIFN_PUISR_SRCCTX       0x0040  /* Source context interrupt */
-+#define       HIFN_PUISR_SRCDATA      0x0020  /* Source data interrupt */
-+#define       HIFN_PUISR_DSTDATA      0x0010  /* Destination data interrupt */
-+#define       HIFN_PUISR_DSTRESULT    0x0004  /* Destination result interrupt */
-+
-+/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
-+#define       HIFN_PUCNFG_DRAMMASK    0xe000  /* DRAM size mask */
-+#define       HIFN_PUCNFG_DSZ_256K    0x0000  /* 256k dram */
-+#define       HIFN_PUCNFG_DSZ_512K    0x2000  /* 512k dram */
-+#define       HIFN_PUCNFG_DSZ_1M      0x4000  /* 1m dram */
-+#define       HIFN_PUCNFG_DSZ_2M      0x6000  /* 2m dram */
-+#define       HIFN_PUCNFG_DSZ_4M      0x8000  /* 4m dram */
-+#define       HIFN_PUCNFG_DSZ_8M      0xa000  /* 8m dram */
-+#define       HIFN_PUNCFG_DSZ_16M     0xc000  /* 16m dram */
-+#define       HIFN_PUCNFG_DSZ_32M     0xe000  /* 32m dram */
-+#define       HIFN_PUCNFG_DRAMREFRESH 0x1800  /* DRAM refresh rate mask */
-+#define       HIFN_PUCNFG_DRFR_512    0x0000  /* 512 divisor of ECLK */
-+#define       HIFN_PUCNFG_DRFR_256    0x0800  /* 256 divisor of ECLK */
-+#define       HIFN_PUCNFG_DRFR_128    0x1000  /* 128 divisor of ECLK */
-+#define       HIFN_PUCNFG_TCALLPHASES 0x0200  /* your guess is as good as mine... */
-+#define       HIFN_PUCNFG_TCDRVTOTEM  0x0100  /* your guess is as good as mine... */
-+#define       HIFN_PUCNFG_BIGENDIAN   0x0080  /* DMA big endian mode */
-+#define       HIFN_PUCNFG_BUS32       0x0040  /* Bus width 32bits */
-+#define       HIFN_PUCNFG_BUS16       0x0000  /* Bus width 16 bits */
-+#define       HIFN_PUCNFG_CHIPID      0x0020  /* Allow chipid from PUSTAT */
-+#define       HIFN_PUCNFG_DRAM        0x0010  /* Context RAM is DRAM */
-+#define       HIFN_PUCNFG_SRAM        0x0000  /* Context RAM is SRAM */
-+#define       HIFN_PUCNFG_COMPSING    0x0004  /* Enable single compression context */
-+#define       HIFN_PUCNFG_ENCCNFG     0x0002  /* Encryption configuration */
-+
-+/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
-+#define       HIFN_PUIER_CMDINVAL     0x8000  /* Invalid command interrupt */
-+#define       HIFN_PUIER_DATAERR      0x4000  /* Data error interrupt */
-+#define       HIFN_PUIER_SRCFIFO      0x2000  /* Source FIFO ready interrupt */
-+#define       HIFN_PUIER_DSTFIFO      0x1000  /* Destination FIFO ready interrupt */
-+#define       HIFN_PUIER_DSTOVER      0x0200  /* Destination overrun interrupt */
-+#define       HIFN_PUIER_SRCCMD       0x0080  /* Source command interrupt */
-+#define       HIFN_PUIER_SRCCTX       0x0040  /* Source context interrupt */
-+#define       HIFN_PUIER_SRCDATA      0x0020  /* Source data interrupt */
-+#define       HIFN_PUIER_DSTDATA      0x0010  /* Destination data interrupt */
-+#define       HIFN_PUIER_DSTRESULT    0x0004  /* Destination result interrupt */
-+
-+/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
-+#define       HIFN_PUSTAT_CMDINVAL    0x8000  /* Invalid command interrupt */
-+#define       HIFN_PUSTAT_DATAERR     0x4000  /* Data error interrupt */
-+#define       HIFN_PUSTAT_SRCFIFO     0x2000  /* Source FIFO ready interrupt */
-+#define       HIFN_PUSTAT_DSTFIFO     0x1000  /* Destination FIFO ready interrupt */
-+#define       HIFN_PUSTAT_DSTOVER     0x0200  /* Destination overrun interrupt */
-+#define       HIFN_PUSTAT_SRCCMD      0x0080  /* Source command interrupt */
-+#define       HIFN_PUSTAT_SRCCTX      0x0040  /* Source context interrupt */
-+#define       HIFN_PUSTAT_SRCDATA     0x0020  /* Source data interrupt */
-+#define       HIFN_PUSTAT_DSTDATA     0x0010  /* Destination data interrupt */
-+#define       HIFN_PUSTAT_DSTRESULT   0x0004  /* Destination result interrupt */
-+#define       HIFN_PUSTAT_CHIPREV     0x00ff  /* Chip revision mask */
-+#define       HIFN_PUSTAT_CHIPENA     0xff00  /* Chip enabled mask */
-+#define       HIFN_PUSTAT_ENA_2       0x1100  /* Level 2 enabled */
-+#define       HIFN_PUSTAT_ENA_1       0x1000  /* Level 1 enabled */
-+#define       HIFN_PUSTAT_ENA_0       0x3000  /* Level 0 enabled */
-+#define       HIFN_PUSTAT_REV_2       0x0020  /* 7751 PT6/2 */
-+#define       HIFN_PUSTAT_REV_3       0x0030  /* 7751 PT6/3 */
-+
-+/* FIFO Status Register (HIFN_0_FIFOSTAT) */
-+#define       HIFN_FIFOSTAT_SRC       0x7f00  /* Source FIFO available */
-+#define       HIFN_FIFOSTAT_DST       0x007f  /* Destination FIFO available */
-+
-+/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
-+#define       HIFN_FIFOCNFG_THRESHOLD 0x0400  /* must be written as this value */
-+
-+/*
-+ * DMA Interface Registers (offset from BASEREG1)
-+ */
-+#define       HIFN_1_DMA_CRAR         0x0c    /* DMA Command Ring Address */
-+#define       HIFN_1_DMA_SRAR         0x1c    /* DMA Source Ring Address */
-+#define       HIFN_1_DMA_RRAR         0x2c    /* DMA Result Ring Address */
-+#define       HIFN_1_DMA_DRAR         0x3c    /* DMA Destination Ring Address */
-+#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 */
-+#define       HIFN_1_7811_RNGSTS      0x6c    /* 7811: rng status */
-+#define       HIFN_1_DMA_CNFG2        0x6c    /* 7955/7956: dma config #2 */
-+#define       HIFN_1_7811_MIPSRST     0x94    /* 7811: MIPS reset */
-+#define       HIFN_1_REVID            0x98    /* Revision ID */
-+
-+#define       HIFN_1_PUB_RESET        0x204   /* Public/RNG Reset */
-+#define       HIFN_1_PUB_BASE         0x300   /* Public Base Address */
-+#define       HIFN_1_PUB_OPLEN        0x304   /* 7951-compat Public Operand Length */
-+#define       HIFN_1_PUB_OP           0x308   /* 7951-compat Public Operand */
-+#define       HIFN_1_PUB_STATUS       0x30c   /* 7951-compat Public Status */
-+#define       HIFN_1_PUB_IEN          0x310   /* Public Interrupt enable */
-+#define       HIFN_1_RNG_CONFIG       0x314   /* RNG config */
-+#define       HIFN_1_RNG_DATA         0x318   /* RNG data */
-+#define       HIFN_1_PUB_MODE         0x320   /* PK mode */
-+#define       HIFN_1_PUB_FIFO_OPLEN   0x380   /* first element of oplen fifo */
-+#define       HIFN_1_PUB_FIFO_OP      0x384   /* first element of op fifo */
-+#define       HIFN_1_PUB_MEM          0x400   /* start of Public key memory */
-+#define       HIFN_1_PUB_MEMEND       0xbff   /* end of Public key memory */
-+
-+/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
-+#define       HIFN_DMACSR_D_CTRLMASK  0xc0000000      /* Destinition Ring Control */
-+#define       HIFN_DMACSR_D_CTRL_NOP  0x00000000      /* Dest. Control: no-op */
-+#define       HIFN_DMACSR_D_CTRL_DIS  0x40000000      /* Dest. Control: disable */
-+#define       HIFN_DMACSR_D_CTRL_ENA  0x80000000      /* Dest. Control: enable */
-+#define       HIFN_DMACSR_D_ABORT     0x20000000      /* Destinition Ring PCIAbort */
-+#define       HIFN_DMACSR_D_DONE      0x10000000      /* Destinition Ring Done */
-+#define       HIFN_DMACSR_D_LAST      0x08000000      /* Destinition Ring Last */
-+#define       HIFN_DMACSR_D_WAIT      0x04000000      /* Destinition Ring Waiting */
-+#define       HIFN_DMACSR_D_OVER      0x02000000      /* Destinition Ring Overflow */
-+#define       HIFN_DMACSR_R_CTRL      0x00c00000      /* Result Ring Control */
-+#define       HIFN_DMACSR_R_CTRL_NOP  0x00000000      /* Result Control: no-op */
-+#define       HIFN_DMACSR_R_CTRL_DIS  0x00400000      /* Result Control: disable */
-+#define       HIFN_DMACSR_R_CTRL_ENA  0x00800000      /* Result Control: enable */
-+#define       HIFN_DMACSR_R_ABORT     0x00200000      /* Result Ring PCI Abort */
-+#define       HIFN_DMACSR_R_DONE      0x00100000      /* Result Ring Done */
-+#define       HIFN_DMACSR_R_LAST      0x00080000      /* Result Ring Last */
-+#define       HIFN_DMACSR_R_WAIT      0x00040000      /* Result Ring Waiting */
-+#define       HIFN_DMACSR_R_OVER      0x00020000      /* Result Ring Overflow */
-+#define       HIFN_DMACSR_S_CTRL      0x0000c000      /* Source Ring Control */
-+#define       HIFN_DMACSR_S_CTRL_NOP  0x00000000      /* Source Control: no-op */
-+#define       HIFN_DMACSR_S_CTRL_DIS  0x00004000      /* Source Control: disable */
-+#define       HIFN_DMACSR_S_CTRL_ENA  0x00008000      /* Source Control: enable */
-+#define       HIFN_DMACSR_S_ABORT     0x00002000      /* Source Ring PCI Abort */
-+#define       HIFN_DMACSR_S_DONE      0x00001000      /* Source Ring Done */
-+#define       HIFN_DMACSR_S_LAST      0x00000800      /* Source Ring Last */
-+#define       HIFN_DMACSR_S_WAIT      0x00000400      /* Source Ring Waiting */
-+#define       HIFN_DMACSR_ILLW        0x00000200      /* Illegal write (7811 only) */
-+#define       HIFN_DMACSR_ILLR        0x00000100      /* Illegal read (7811 only) */
-+#define       HIFN_DMACSR_C_CTRL      0x000000c0      /* Command Ring Control */
-+#define       HIFN_DMACSR_C_CTRL_NOP  0x00000000      /* Command Control: no-op */
-+#define       HIFN_DMACSR_C_CTRL_DIS  0x00000040      /* Command Control: disable */
-+#define       HIFN_DMACSR_C_CTRL_ENA  0x00000080      /* Command Control: enable */
-+#define       HIFN_DMACSR_C_ABORT     0x00000020      /* Command Ring PCI Abort */
-+#define       HIFN_DMACSR_C_DONE      0x00000010      /* Command Ring Done */
-+#define       HIFN_DMACSR_C_LAST      0x00000008      /* Command Ring Last */
-+#define       HIFN_DMACSR_C_WAIT      0x00000004      /* Command Ring Waiting */
-+#define       HIFN_DMACSR_PUBDONE     0x00000002      /* Public op done (7951 only) */
-+#define       HIFN_DMACSR_ENGINE      0x00000001      /* Command Ring Engine IRQ */
-+
-+/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
-+#define       HIFN_DMAIER_D_ABORT     0x20000000      /* Destination Ring PCIAbort */
-+#define       HIFN_DMAIER_D_DONE      0x10000000      /* Destination Ring Done */
-+#define       HIFN_DMAIER_D_LAST      0x08000000      /* Destination Ring Last */
-+#define       HIFN_DMAIER_D_WAIT      0x04000000      /* Destination Ring Waiting */
-+#define       HIFN_DMAIER_D_OVER      0x02000000      /* Destination Ring Overflow */
-+#define       HIFN_DMAIER_R_ABORT     0x00200000      /* Result Ring PCI Abort */
-+#define       HIFN_DMAIER_R_DONE      0x00100000      /* Result Ring Done */
-+#define       HIFN_DMAIER_R_LAST      0x00080000      /* Result Ring Last */
-+#define       HIFN_DMAIER_R_WAIT      0x00040000      /* Result Ring Waiting */
-+#define       HIFN_DMAIER_R_OVER      0x00020000      /* Result Ring Overflow */
-+#define       HIFN_DMAIER_S_ABORT     0x00002000      /* Source Ring PCI Abort */
-+#define       HIFN_DMAIER_S_DONE      0x00001000      /* Source Ring Done */
-+#define       HIFN_DMAIER_S_LAST      0x00000800      /* Source Ring Last */
-+#define       HIFN_DMAIER_S_WAIT      0x00000400      /* Source Ring Waiting */
-+#define       HIFN_DMAIER_ILLW        0x00000200      /* Illegal write (7811 only) */
-+#define       HIFN_DMAIER_ILLR        0x00000100      /* Illegal read (7811 only) */
-+#define       HIFN_DMAIER_C_ABORT     0x00000020      /* Command Ring PCI Abort */
-+#define       HIFN_DMAIER_C_DONE      0x00000010      /* Command Ring Done */
-+#define       HIFN_DMAIER_C_LAST      0x00000008      /* Command Ring Last */
-+#define       HIFN_DMAIER_C_WAIT      0x00000004      /* Command Ring Waiting */
-+#define       HIFN_DMAIER_PUBDONE     0x00000002      /* public op done (7951 only) */
-+#define       HIFN_DMAIER_ENGINE      0x00000001      /* Engine IRQ */
-+
-+/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
-+#define       HIFN_DMACNFG_BIGENDIAN  0x10000000      /* big endian mode */
-+#define       HIFN_DMACNFG_POLLFREQ   0x00ff0000      /* Poll frequency mask */
-+#define       HIFN_DMACNFG_UNLOCK     0x00000800
-+#define       HIFN_DMACNFG_POLLINVAL  0x00000700      /* Invalid Poll Scalar */
-+#define       HIFN_DMACNFG_LAST       0x00000010      /* Host control LAST bit */
-+#define       HIFN_DMACNFG_MODE       0x00000004      /* DMA mode */
-+#define       HIFN_DMACNFG_DMARESET   0x00000002      /* DMA Reset # */
-+#define       HIFN_DMACNFG_MSTRESET   0x00000001      /* Master Reset # */
-+
-+/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
-+#define       HIFN_DMACNFG2_PKSWAP32  (1 << 19)       /* swap the OPLEN/OP reg */
-+#define       HIFN_DMACNFG2_PKSWAP8   (1 << 18)       /* swap the bits of OPLEN/OP */
-+#define       HIFN_DMACNFG2_BAR0_SWAP32 (1<<17)       /* swap the bytes of BAR0 */
-+#define       HIFN_DMACNFG2_BAR1_SWAP8 (1<<16)        /* swap the bits  of BAR0 */
-+#define       HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
-+#define       HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
-+#define       HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
-+#define       HIFN_DMACNFG2_TGT_READ_BURST_SHIFT  0
-+
-+/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
-+#define       HIFN_7811_RNGENA_ENA    0x00000001      /* enable RNG */
-+
-+/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
-+#define       HIFN_7811_RNGCFG_PRE1   0x00000f00      /* first prescalar */
-+#define       HIFN_7811_RNGCFG_OPRE   0x00000080      /* output prescalar */
-+#define       HIFN_7811_RNGCFG_DEFL   0x00000f80      /* 2 words/ 1/100 sec */
-+
-+/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
-+#define       HIFN_7811_RNGSTS_RDY    0x00004000      /* two numbers in FIFO */
-+#define       HIFN_7811_RNGSTS_UFL    0x00001000      /* rng underflow */
-+
-+/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
-+#define       HIFN_MIPSRST_BAR2SIZE   0xffff0000      /* sdram size */
-+#define       HIFN_MIPSRST_GPRAMINIT  0x00008000      /* gpram can be accessed */
-+#define       HIFN_MIPSRST_CRAMINIT   0x00004000      /* ctxram can be accessed */
-+#define       HIFN_MIPSRST_LED2       0x00000400      /* external LED2 */
-+#define       HIFN_MIPSRST_LED1       0x00000200      /* external LED1 */
-+#define       HIFN_MIPSRST_LED0       0x00000100      /* external LED0 */
-+#define       HIFN_MIPSRST_MIPSDIS    0x00000004      /* disable MIPS */
-+#define       HIFN_MIPSRST_MIPSRST    0x00000002      /* warm reset MIPS */
-+#define       HIFN_MIPSRST_MIPSCOLD   0x00000001      /* cold reset MIPS */
-+
-+/* Public key reset register (HIFN_1_PUB_RESET) */
-+#define       HIFN_PUBRST_RESET       0x00000001      /* reset public/rng unit */
-+
-+/* Public operation register (HIFN_1_PUB_OP) */
-+#define       HIFN_PUBOP_AOFFSET      0x0000003e      /* A offset */
-+#define       HIFN_PUBOP_BOFFSET      0x00000fc0      /* B offset */
-+#define       HIFN_PUBOP_MOFFSET      0x0003f000      /* M offset */
-+#define       HIFN_PUBOP_OP_MASK      0x003c0000      /* Opcode: */
-+#define       HIFN_PUBOP_OP_NOP       0x00000000      /*  NOP */
-+#define       HIFN_PUBOP_OP_ADD       0x00040000      /*  ADD */
-+#define       HIFN_PUBOP_OP_ADDC      0x00080000      /*  ADD w/carry */
-+#define       HIFN_PUBOP_OP_SUB       0x000c0000      /*  SUB */
-+#define       HIFN_PUBOP_OP_SUBC      0x00100000      /*  SUB w/carry */
-+#define       HIFN_PUBOP_OP_MODADD    0x00140000      /*  Modular ADD */
-+#define       HIFN_PUBOP_OP_MODSUB    0x00180000      /*  Modular SUB */
-+#define       HIFN_PUBOP_OP_INCA      0x001c0000      /*  INC A */
-+#define       HIFN_PUBOP_OP_DECA      0x00200000      /*  DEC A */
-+#define       HIFN_PUBOP_OP_MULT      0x00240000      /*  MULT */
-+#define       HIFN_PUBOP_OP_MODMULT   0x00280000      /*  Modular MULT */
-+#define       HIFN_PUBOP_OP_MODRED    0x002c0000      /*  Modular Red */
-+#define       HIFN_PUBOP_OP_MODEXP    0x00300000      /*  Modular Exp */
-+
-+/* Public operand length register (HIFN_1_PUB_OPLEN) */
-+#define       HIFN_PUBOPLEN_MODLEN    0x0000007f
-+#define       HIFN_PUBOPLEN_EXPLEN    0x0003ff80
-+#define       HIFN_PUBOPLEN_REDLEN    0x003c0000
-+
-+/* Public status register (HIFN_1_PUB_STATUS) */
-+#define       HIFN_PUBSTS_DONE        0x00000001      /* operation done */
-+#define       HIFN_PUBSTS_CARRY       0x00000002      /* carry */
-+#define       HIFN_PUBSTS_FIFO_EMPTY  0x00000100      /* fifo empty */
-+#define       HIFN_PUBSTS_FIFO_FULL   0x00000200      /* fifo full */
-+#define       HIFN_PUBSTS_FIFO_OVFL   0x00000400      /* fifo overflow */
-+#define       HIFN_PUBSTS_FIFO_WRITE  0x000f0000      /* fifo write */
-+#define       HIFN_PUBSTS_FIFO_READ   0x0f000000      /* fifo read */
-+
-+/* Public interrupt enable register (HIFN_1_PUB_IEN) */
-+#define       HIFN_PUBIEN_DONE        0x00000001      /* operation done interrupt */
-+
-+/* Random number generator config register (HIFN_1_RNG_CONFIG) */
-+#define       HIFN_RNGCFG_ENA         0x00000001      /* enable rng */
-+
-+/*
-+ * Register offsets in register set 1
-+ */
-+
-+#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)
-+
-+/*
-+ * Public Key Engine Mode Register
-+ */
-+#define       HIFN_PKMODE_HOSTINVERT  (1 << 0)        /* HOST INVERT */
-+#define       HIFN_PKMODE_ENHANCED    (1 << 1)        /* Enable enhanced mode */
-+
-+
-+/*********************************************************************
-+ * Structs for board commands 
-+ *
-+ *********************************************************************/
-+
-+/*
-+ * Structure to help build up the command data structure.
-+ */
-+typedef struct hifn_base_command {
-+      volatile u_int16_t masks;
-+      volatile u_int16_t session_num;
-+      volatile u_int16_t total_source_count;
-+      volatile u_int16_t total_dest_count;
-+} hifn_base_command_t;
-+
-+#define       HIFN_BASE_CMD_MAC               0x0400
-+#define       HIFN_BASE_CMD_CRYPT             0x0800
-+#define       HIFN_BASE_CMD_DECODE            0x2000
-+#define       HIFN_BASE_CMD_SRCLEN_M          0xc000
-+#define       HIFN_BASE_CMD_SRCLEN_S          14
-+#define       HIFN_BASE_CMD_DSTLEN_M          0x3000
-+#define       HIFN_BASE_CMD_DSTLEN_S          12
-+#define       HIFN_BASE_CMD_LENMASK_HI        0x30000
-+#define       HIFN_BASE_CMD_LENMASK_LO        0x0ffff
-+
-+/*
-+ * Structure to help build up the command data structure.
-+ */
-+typedef struct hifn_crypt_command {
-+      volatile u_int16_t masks;
-+      volatile u_int16_t header_skip;
-+      volatile u_int16_t source_count;
-+      volatile u_int16_t reserved;
-+} hifn_crypt_command_t;
-+
-+#define       HIFN_CRYPT_CMD_ALG_MASK         0x0003          /* algorithm: */
-+#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_ALG_AES          0x0003          /*   AES */
-+#define       HIFN_CRYPT_CMD_MODE_MASK        0x0018          /* Encrypt 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 */
-+#define       HIFN_CRYPT_CMD_MODE_OFB         0x0018          /*   OFB */
-+#define       HIFN_CRYPT_CMD_CLR_CTX          0x0040          /* clear context */
-+#define       HIFN_CRYPT_CMD_NEW_KEY          0x0800          /* expect new key */
-+#define       HIFN_CRYPT_CMD_NEW_IV           0x1000          /* expect new iv */
-+
-+#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.
-+ */
-+typedef struct hifn_mac_command {
-+      volatile u_int16_t masks;
-+      volatile u_int16_t header_skip;
-+      volatile u_int16_t source_count;
-+      volatile u_int16_t reserved;
-+} hifn_mac_command_t;
-+
-+#define       HIFN_MAC_CMD_ALG_MASK           0x0001
-+#define       HIFN_MAC_CMD_ALG_SHA1           0x0000
-+#define       HIFN_MAC_CMD_ALG_MD5            0x0001
-+#define       HIFN_MAC_CMD_MODE_MASK          0x000c
-+#define       HIFN_MAC_CMD_MODE_HMAC          0x0000
-+#define       HIFN_MAC_CMD_MODE_SSL_MAC       0x0004
-+#define       HIFN_MAC_CMD_MODE_HASH          0x0008
-+#define       HIFN_MAC_CMD_MODE_FULL          0x0004
-+#define       HIFN_MAC_CMD_TRUNC              0x0010
-+#define       HIFN_MAC_CMD_RESULT             0x0020
-+#define       HIFN_MAC_CMD_APPEND             0x0040
-+#define       HIFN_MAC_CMD_SRCLEN_M           0xc000
-+#define       HIFN_MAC_CMD_SRCLEN_S           14
-+
-+/*
-+ * MAC POS IPsec initiates authentication after encryption on encodes
-+ * and before decryption on decodes.
-+ */
-+#define       HIFN_MAC_CMD_POS_IPSEC          0x0200
-+#define       HIFN_MAC_CMD_NEW_KEY            0x0800
-+
-+/*
-+ * The poll frequency and poll scalar defines are unshifted values used
-+ * to set fields in the DMA Configuration Register.
-+ */
-+#ifndef HIFN_POLL_FREQUENCY
-+#define       HIFN_POLL_FREQUENCY     0x1
-+#endif
-+
-+#ifndef HIFN_POLL_SCALAR
-+#define       HIFN_POLL_SCALAR        0x0
-+#endif
-+
-+#define       HIFN_MAX_SEGLEN         0xffff          /* maximum dma segment len */
-+#define       HIFN_MAX_DMALEN         0x3ffff         /* maximum dma length */
-+#endif /* __HIFN_H__ */
---- /dev/null
-+++ b/crypto/ocf/hifn/hifn7751var.h
-@@ -0,0 +1,369 @@
-+/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam 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
-+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.
-+ *                    http://www.netsec.net
-+ *
-+ * Please send any comments, feedback, bug-fixes, or feature requests to
-+ * software@invertex.com.
-+ *
-+ * 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.
-+ *
-+ * Effort sponsored in part by the Defense Advanced Research Projects
-+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
-+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
-+ *
-+ */
-+
-+#ifndef __HIFN7751VAR_H__
-+#define __HIFN7751VAR_H__
-+
-+#ifdef __KERNEL__
-+
-+/*
-+ * Some configurable values for the driver.  By default command+result
-+ * descriptor rings are the same size.  The src+dst descriptor rings
-+ * are sized at 3.5x the number of potential commands.  Slower parts
-+ * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
-+ * src+cmd/result descriptors.  It's not clear that increasing the size
-+ * of the descriptor rings helps performance significantly as other
-+ * factors tend to come into play (e.g. copying misaligned packets).
-+ */
-+#define       HIFN_D_CMD_RSIZE        24      /* command descriptors */
-+#define       HIFN_D_SRC_RSIZE        ((HIFN_D_CMD_RSIZE * 7) / 2)    /* source descriptors */
-+#define       HIFN_D_RES_RSIZE        HIFN_D_CMD_RSIZE        /* result descriptors */
-+#define       HIFN_D_DST_RSIZE        HIFN_D_SRC_RSIZE        /* destination descriptors */
-+
-+/*
-+ *  Length values for cryptography
-+ */
-+#define HIFN_DES_KEY_LENGTH           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
-+ */
-+#define HIFN_MAC_KEY_LENGTH           64
-+#define HIFN_MD5_LENGTH                       16
-+#define HIFN_SHA1_LENGTH              20
-+#define HIFN_MAC_TRUNC_LENGTH         12
-+
-+#define MAX_SCATTER 64
-+
-+/*
-+ * Data structure to hold all 4 rings and any other ring related data.
-+ */
-+struct hifn_dma {
-+      /*
-+       *  Descriptor rings.  We add +1 to the size to accomidate the
-+       *  jump descriptor.
-+       */
-+      struct hifn_desc        cmdr[HIFN_D_CMD_RSIZE+1];
-+      struct hifn_desc        srcr[HIFN_D_SRC_RSIZE+1];
-+      struct hifn_desc        dstr[HIFN_D_DST_RSIZE+1];
-+      struct hifn_desc        resr[HIFN_D_RES_RSIZE+1];
-+
-+      struct hifn_command     *hifn_commands[HIFN_D_RES_RSIZE];
-+
-+      u_char                  command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
-+      u_char                  result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
-+      u_int32_t               slop[HIFN_D_CMD_RSIZE];
-+
-+      u_int64_t               test_src, test_dst;
-+
-+      /*
-+       *  Our current positions for insertion and removal from the desriptor
-+       *  rings. 
-+       */
-+      int                     cmdi, srci, dsti, resi;
-+      volatile int            cmdu, srcu, dstu, resu;
-+      int                     cmdk, srck, dstk, resk;
-+};
-+
-+struct hifn_session {
-+      int hs_used;
-+      int hs_mlen;
-+      u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
-+};
-+
-+#define       HIFN_RING_SYNC(sc, r, i, f)                                     \
-+      /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
-+
-+#define       HIFN_CMDR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), cmdr, (i), (f))
-+#define       HIFN_RESR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), resr, (i), (f))
-+#define       HIFN_SRCR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), srcr, (i), (f))
-+#define       HIFN_DSTR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), dstr, (i), (f))
-+
-+#define       HIFN_CMD_SYNC(sc, i, f)                                         \
-+      /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
-+
-+#define       HIFN_RES_SYNC(sc, i, f)                                         \
-+      /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
-+
-+typedef int bus_size_t;
-+
-+/*
-+ * Holds data specific to a single HIFN board.
-+ */
-+struct hifn_softc {
-+      softc_device_decl                sc_dev;
-+
-+      struct pci_dev          *sc_pcidev;     /* PCI device pointer */
-+      spinlock_t              sc_mtx;         /* per-instance lock */
-+
-+      int                     sc_num;         /* for multiple devs */
-+
-+      ocf_iomem_t             sc_bar0;
-+      bus_size_t              sc_bar0_lastreg;/* bar0 last reg written */
-+      ocf_iomem_t             sc_bar1;
-+      bus_size_t              sc_bar1_lastreg;/* bar1 last reg written */
-+
-+      int                     sc_irq;
-+
-+      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;
-+      dma_addr_t              sc_dma_physaddr;/* physical address of sc_dma */
-+
-+      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_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 timer_list       sc_tickto;      /* for managing DMA */
-+
-+      int                     sc_rngfirst;
-+      int                     sc_rnghz;       /* RNG polling frequency */
-+
-+      int                     sc_c_busy;      /* command ring busy */
-+      int                     sc_s_busy;      /* source data ring busy */
-+      int                     sc_d_busy;      /* destination data ring busy */
-+      int                     sc_r_busy;      /* result ring busy */
-+      int                     sc_active;      /* for initial countdown */
-+      int                     sc_needwakeup;  /* ops q'd wating on resources */
-+      int                     sc_curbatch;    /* # ops submitted w/o int */
-+      int                     sc_suspended;
-+#ifdef HIFN_VULCANDEV
-+      struct cdev            *sc_pkdev;
-+#endif
-+};
-+
-+#define       HIFN_LOCK(_sc)          spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
-+#define       HIFN_UNLOCK(_sc)        spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
-+
-+/*
-+ *  hifn_command_t
-+ *
-+ *  This is the control structure used to pass commands to hifn_encrypt().
-+ *
-+ *  flags
-+ *  -----
-+ *  Flags is the bitwise "or" values for command configuration.  A single
-+ *  encrypt direction needs to be set:
-+ *
-+ *    HIFN_ENCODE or HIFN_DECODE
-+ *
-+ *  To use cryptography, a single crypto algorithm must be included:
-+ *
-+ *    HIFN_CRYPT_3DES or HIFN_CRYPT_DES
-+ *
-+ *  To use authentication is used, a single MAC algorithm must be included:
-+ *
-+ *    HIFN_MAC_MD5 or HIFN_MAC_SHA1
-+ *
-+ *  By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
-+ *  If the value below is set, hash values are truncated or assumed
-+ *  truncated to 12 bytes:
-+ *
-+ *    HIFN_MAC_TRUNC
-+ *
-+ *  Keys for encryption and authentication can be sent as part of a command,
-+ *  or the last key value used with a particular session can be retrieved
-+ *  and used again if either of these flags are not specified.
-+ *
-+ *    HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
-+ *
-+ *  session_num
-+ *  -----------
-+ *  A number between 0 and 2048 (for DRAM models) or a number between 
-+ *  0 and 768 (for SRAM models).  Those who don't want to use session
-+ *  numbers should leave value at zero and send a new crypt key and/or
-+ *  new MAC key on every command.  If you use session numbers and
-+ *  don't send a key with a command, the last key sent for that same
-+ *  session number will be used.
-+ *
-+ *  Warning:  Using session numbers and multiboard at the same time
-+ *            is currently broken.
-+ *
-+ *  mbuf
-+ *  ----
-+ *  Either fill in the mbuf pointer and npa=0 or
-+ *     fill packp[] and packl[] and set npa to > 0
-+ * 
-+ *  mac_header_skip
-+ *  ---------------
-+ *  The number of bytes of the source_buf that are skipped over before
-+ *  authentication begins.  This must be a number between 0 and 2^16-1
-+ *  and can be used by IPsec implementers to skip over IP headers.
-+ *  *** Value ignored if authentication not used ***
-+ *
-+ *  crypt_header_skip
-+ *  -----------------
-+ *  The number of bytes of the source_buf that are skipped over before
-+ *  the cryptographic operation begins.  This must be a number between 0
-+ *  and 2^16-1.  For IPsec, this number will always be 8 bytes larger
-+ *  than the auth_header_skip (to skip over the ESP header).
-+ *  *** Value ignored if cryptography not used ***
-+ *
-+ */
-+struct hifn_operand {
-+      union {
-+              struct sk_buff *skb;
-+              struct uio *io;
-+              unsigned char *buf;
-+      } u;
-+      void            *map;
-+      bus_size_t      mapsize;
-+      int             nsegs;
-+      struct {
-+          dma_addr_t  ds_addr;
-+          int         ds_len;
-+      } segs[MAX_SCATTER];
-+};
-+
-+struct hifn_command {
-+      u_int16_t session_num;
-+      u_int16_t base_masks, cry_masks, mac_masks;
-+      u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
-+      int cklen;
-+      int sloplen, slopidx;
-+
-+      struct hifn_operand src;
-+      struct hifn_operand dst;
-+
-+      struct hifn_softc *softc;
-+      struct cryptop *crp;
-+      struct cryptodesc *enccrd, *maccrd;
-+};
-+
-+#define       src_skb         src.u.skb
-+#define       src_io          src.u.io
-+#define       src_map         src.map
-+#define       src_mapsize     src.mapsize
-+#define       src_segs        src.segs
-+#define       src_nsegs       src.nsegs
-+#define       src_buf         src.u.buf
-+
-+#define       dst_skb         dst.u.skb
-+#define       dst_io          dst.u.io
-+#define       dst_map         dst.map
-+#define       dst_mapsize     dst.mapsize
-+#define       dst_segs        dst.segs
-+#define       dst_nsegs       dst.nsegs
-+#define       dst_buf         dst.u.buf
-+
-+/*
-+ *  Return values for hifn_crypto()
-+ */
-+#define HIFN_CRYPTO_SUCCESS   0
-+#define HIFN_CRYPTO_BAD_INPUT (-1)
-+#define HIFN_CRYPTO_RINGS_FULL        (-2)
-+
-+/**************************************************************************
-+ *
-+ *  Function:  hifn_crypto
-+ *
-+ *  Purpose:   Called by external drivers to begin an encryption on the
-+ *             HIFN board.
-+ *
-+ *  Blocking/Non-blocking Issues
-+ *  ============================
-+ *  The driver cannot block in hifn_crypto (no calls to tsleep) currently.
-+ *  hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
-+ *  room in any of the rings for the request to proceed.
-+ *
-+ *  Return Values
-+ *  =============
-+ *  0 for success, negative values on error
-+ *
-+ *  Defines for negative error codes are:
-+ *  
-+ *    HIFN_CRYPTO_BAD_INPUT  :  The passed in command had invalid settings.
-+ *    HIFN_CRYPTO_RINGS_FULL :  All DMA rings were full and non-blocking
-+ *                              behaviour was requested.
-+ *
-+ *************************************************************************/
-+
-+/*
-+ * Convert back and forth from 'sid' to 'card' and 'session'
-+ */
-+#define HIFN_CARD(sid)                (((sid) & 0xf0000000) >> 28)
-+#define HIFN_SESSION(sid)     ((sid) & 0x000007ff)
-+#define HIFN_SID(crd,ses)     (((crd) << 28) | ((ses) & 0x7ff))
-+
-+#endif /* _KERNEL */
-+
-+struct hifn_stats {
-+      u_int64_t hst_ibytes;
-+      u_int64_t hst_obytes;
-+      u_int32_t hst_ipackets;
-+      u_int32_t hst_opackets;
-+      u_int32_t hst_invalid;
-+      u_int32_t hst_nomem;            /* malloc or one of hst_nomem_* */
-+      u_int32_t hst_abort;
-+      u_int32_t hst_noirq;            /* IRQ for no reason */
-+      u_int32_t hst_totbatch;         /* ops submitted w/o interrupt */
-+      u_int32_t hst_maxbatch;         /* max ops submitted together */
-+      u_int32_t hst_unaligned;        /* unaligned src caused copy */
-+      /*
-+       * The following divides hst_nomem into more specific buckets.
-+       */
-+      u_int32_t hst_nomem_map;        /* bus_dmamap_create failed */
-+      u_int32_t hst_nomem_load;       /* bus_dmamap_load_* failed */
-+      u_int32_t hst_nomem_mbuf;       /* MGET* failed */
-+      u_int32_t hst_nomem_mcl;        /* MCLGET* failed */
-+      u_int32_t hst_nomem_cr;         /* out of command/result descriptor */
-+      u_int32_t hst_nomem_sd;         /* out of src/dst descriptors */
-+};
-+
-+#endif /* __HIFN7751VAR_H__ */
---- /dev/null
-+++ b/crypto/ocf/hifn/hifn7751.c
-@@ -0,0 +1,2970 @@
-+/*    $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
-+ * requests to software@invertex.com.
-+ *
-+ * 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.
-+ *
-+ * Effort sponsored in part by the Defense Advanced Research Projects
-+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
-+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
-+ *
-+ *
-+__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
-+ */
-+
-+/*
-+ * Driver for various Hifn encryption processors.
-+ */
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+#include <linux/wait.h>
-+#include <linux/sched.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+#include <linux/random.h>
-+#include <linux/version.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+
-+#include <cryptodev.h>
-+#include <uio.h>
-+#include <hifn/hifn7751reg.h>
-+#include <hifn/hifn7751var.h>
-+
-+#if 1
-+#define       DPRINTF(a...)   if (hifn_debug) { \
-+                                                      printk("%s: ", sc ? \
-+                                                              device_get_nameunit(sc->sc_dev) : "hifn"); \
-+                                                      printk(a); \
-+                                              } else
-+#else
-+#define       DPRINTF(a...)
-+#endif
-+
-+static inline int
-+pci_get_revid(struct pci_dev *dev)
-+{
-+      u8 rid = 0;
-+      pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
-+      return rid;
-+}
-+
-+static        struct hifn_stats hifnstats;
-+
-+#define       debug hifn_debug
-+int hifn_debug = 0;
-+module_param(hifn_debug, int, 0644);
-+MODULE_PARM_DESC(hifn_debug, "Enable debug");
-+
-+int hifn_maxbatch = 1;
-+module_param(hifn_maxbatch, int, 0644);
-+MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
-+
-+#ifdef MODULE_PARM
-+char *hifn_pllconfig = NULL;
-+MODULE_PARM(hifn_pllconfig, "s");
-+#else
-+char hifn_pllconfig[32]; /* This setting is RO after loading */
-+module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
-+#endif
-+MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
-+
-+#ifdef HIFN_VULCANDEV
-+#include <sys/conf.h>
-+#include <sys/uio.h>
-+
-+static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
-+#endif
-+
-+/*
-+ * Prototypes and count for the pci_device structure
-+ */
-+static        int  hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
-+static        void hifn_remove(struct pci_dev *dev);
-+
-+static        int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
-+static        int hifn_freesession(device_t, u_int64_t);
-+static        int hifn_process(device_t, struct cryptop *, int);
-+
-+static device_method_t hifn_methods = {
-+      /* crypto device methods */
-+      DEVMETHOD(cryptodev_newsession, hifn_newsession),
-+      DEVMETHOD(cryptodev_freesession,hifn_freesession),
-+      DEVMETHOD(cryptodev_process,    hifn_process),
-+};
-+
-+static        void hifn_reset_board(struct hifn_softc *, int);
-+static        void hifn_reset_puc(struct hifn_softc *);
-+static        void hifn_puc_wait(struct hifn_softc *);
-+static        int hifn_enable_crypto(struct hifn_softc *);
-+static        void hifn_set_retry(struct hifn_softc *sc);
-+static        void hifn_init_dma(struct hifn_softc *);
-+static        void hifn_init_pci_registers(struct hifn_softc *);
-+static        int hifn_sramsize(struct hifn_softc *);
-+static        int hifn_dramsize(struct hifn_softc *);
-+static        int hifn_ramtype(struct hifn_softc *);
-+static        void hifn_sessions(struct hifn_softc *);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-+static irqreturn_t hifn_intr(int irq, void *arg);
-+#else
-+static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
-+#endif
-+static        u_int hifn_write_command(struct hifn_command *, u_int8_t *);
-+static        u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
-+static        void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
-+static        int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
-+static        int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
-+static        int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
-+static        int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
-+static        int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
-+static        int hifn_init_pubrng(struct hifn_softc *);
-+static        void hifn_tick(unsigned long arg);
-+static        void hifn_abort(struct hifn_softc *);
-+static        void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
-+
-+static        void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
-+static        void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
-+
-+#ifdef CONFIG_OCF_RANDOMHARVEST
-+static        int hifn_read_random(void *arg, u_int32_t *buf, int len);
-+#endif
-+
-+#define HIFN_MAX_CHIPS        8
-+static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
-+
-+static __inline u_int32_t
-+READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
-+{
-+      u_int32_t v = readl(sc->sc_bar0 + reg);
-+      sc->sc_bar0_lastreg = (bus_size_t) -1;
-+      return (v);
-+}
-+#define       WRITE_REG_0(sc, reg, val)       hifn_write_reg_0(sc, reg, val)
-+
-+static __inline u_int32_t
-+READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
-+{
-+      u_int32_t v = readl(sc->sc_bar1 + reg);
-+      sc->sc_bar1_lastreg = (bus_size_t) -1;
-+      return (v);
-+}
-+#define       WRITE_REG_1(sc, reg, val)       hifn_write_reg_1(sc, reg, val)
-+
-+/*
-+ * map in a given buffer (great on some arches :-)
-+ */
-+
-+static int
-+pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
-+{
-+      struct iovec *iov = uio->uio_iov;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      buf->mapsize = 0;
-+      for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
-+              buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
-+                              iov->iov_base, iov->iov_len,
-+                              PCI_DMA_BIDIRECTIONAL);
-+              buf->segs[buf->nsegs].ds_len = iov->iov_len;
-+              buf->mapsize += iov->iov_len;
-+              iov++;
-+              buf->nsegs++;
-+      }
-+      /* identify this buffer by the first segment */
-+      buf->map = (void *) buf->segs[0].ds_addr;
-+      return(0);
-+}
-+
-+/*
-+ * map in a given sk_buff
-+ */
-+
-+static int
-+pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
-+{
-+      int i;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      buf->mapsize = 0;
-+
-+      buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
-+                      skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
-+      buf->segs[0].ds_len = skb_headlen(skb);
-+      buf->mapsize += buf->segs[0].ds_len;
-+
-+      buf->nsegs = 1;
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
-+              buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
-+              buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
-+                              page_address(skb_shinfo(skb)->frags[i].page) +
-+                                      skb_shinfo(skb)->frags[i].page_offset,
-+                              buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
-+              buf->mapsize += buf->segs[buf->nsegs].ds_len;
-+              buf->nsegs++;
-+      }
-+
-+      /* identify this buffer by the first segment */
-+      buf->map = (void *) buf->segs[0].ds_addr;
-+      return(0);
-+}
-+
-+/*
-+ * map in a given contiguous buffer
-+ */
-+
-+static int
-+pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
-+{
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      buf->mapsize = 0;
-+      buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
-+                      b, len, PCI_DMA_BIDIRECTIONAL);
-+      buf->segs[0].ds_len = len;
-+      buf->mapsize += buf->segs[0].ds_len;
-+      buf->nsegs = 1;
-+
-+      /* identify this buffer by the first segment */
-+      buf->map = (void *) buf->segs[0].ds_addr;
-+      return(0);
-+}
-+
-+#if 0 /* not needed at this time */
-+static void
-+pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
-+{
-+      int i;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+      for (i = 0; i < buf->nsegs; i++)
-+              pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
-+                              buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
-+}
-+#endif
-+
-+static void
-+pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
-+{
-+      int i;
-+      DPRINTF("%s()\n", __FUNCTION__);
-+      for (i = 0; i < buf->nsegs; i++) {
-+              pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
-+                              buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
-+              buf->segs[i].ds_addr = 0;
-+              buf->segs[i].ds_len = 0;
-+      }
-+      buf->nsegs = 0;
-+      buf->mapsize = 0;
-+      buf->map = 0;
-+}
-+
-+static const char*
-+hifn_partname(struct hifn_softc *sc)
-+{
-+      /* XXX sprintf numbers when not decoded */
-+      switch (pci_get_vendor(sc->sc_pcidev)) {
-+      case PCI_VENDOR_HIFN:
-+              switch (pci_get_device(sc->sc_pcidev)) {
-+              case PCI_PRODUCT_HIFN_6500:     return "Hifn 6500";
-+              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:
-+              switch (pci_get_device(sc->sc_pcidev)) {
-+              case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
-+              }
-+              return "Invertex unknown-part";
-+      case PCI_VENDOR_NETSEC:
-+              switch (pci_get_device(sc->sc_pcidev)) {
-+              case PCI_PRODUCT_NETSEC_7751:   return "NetSec 7751";
-+              }
-+              return "NetSec unknown-part";
-+      }
-+      return "Unknown-vendor unknown-part";
-+}
-+
-+static u_int
-+checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
-+{
-+      struct hifn_softc *sc = pci_get_drvdata(dev);
-+      if (v > max) {
-+              device_printf(sc->sc_dev, "Warning, %s %u out of range, "
-+                      "using max %u\n", what, v, max);
-+              v = max;
-+      } else if (v < min) {
-+              device_printf(sc->sc_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.
-+ *
-+ * We use a default setting of "ext66" because according to Mike Ham
-+ * of HiFn, almost every board in existence has an external crystal
-+ * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
-+ * because PCI33 can have clocks from 0 to 33Mhz, and some have
-+ * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
-+ */
-+static void
-+hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
-+{
-+      const char *pllspec = hifn_pllconfig;
-+      u_int freq, mul, fl, fh;
-+      u_int32_t pllconfig;
-+      char *nxt;
-+
-+      if (pllspec == NULL)
-+              pllspec = "ext66";
-+      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.
-+ */
-+static int
-+hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
-+{
-+      struct hifn_softc *sc = NULL;
-+      char rbase;
-+      u_int16_t ena, rev;
-+      int rseg, rc;
-+      unsigned long mem_start, mem_len;
-+      static int num_chips = 0;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      if (pci_enable_device(dev) < 0)
-+              return(-ENODEV);
-+
-+      if (pci_set_mwi(dev))
-+              return(-ENODEV);
-+
-+      if (!dev->irq) {
-+              printk("hifn: found device with no IRQ assigned. check BIOS settings!");
-+              pci_disable_device(dev);
-+              return(-ENODEV);
-+      }
-+
-+      sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
-+      if (!sc)
-+              return(-ENOMEM);
-+      memset(sc, 0, sizeof(*sc));
-+
-+      softc_device_init(sc, "hifn", num_chips, hifn_methods);
-+
-+      sc->sc_pcidev = dev;
-+      sc->sc_irq = -1;
-+      sc->sc_cid = -1;
-+      sc->sc_num = num_chips++;
-+      if (sc->sc_num < HIFN_MAX_CHIPS)
-+              hifn_chip_idx[sc->sc_num] = sc;
-+
-+      pci_set_drvdata(sc->sc_pcidev, sc);
-+
-+      spin_lock_init(&sc->sc_mtx);
-+
-+      /* XXX handle power management */
-+
-+      /*
-+       * 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_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
-+       * we also note it's identity 'cuz of some quirks.
-+       */
-+      if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
-+          pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
-+              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);
-+      }
-+
-+      /*
-+       * Setup PCI resources. Note that we record the bus
-+       * tag and handle for each register mapping, this is
-+       * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
-+       * and WRITE_REG_1 macros throughout the driver.
-+       */
-+      mem_start = pci_resource_start(sc->sc_pcidev, 0);
-+      mem_len   = pci_resource_len(sc->sc_pcidev, 0);
-+      sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
-+      if (!sc->sc_bar0) {
-+              device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
-+              goto fail;
-+      }
-+      sc->sc_bar0_lastreg = (bus_size_t) -1;
-+
-+      mem_start = pci_resource_start(sc->sc_pcidev, 1);
-+      mem_len   = pci_resource_len(sc->sc_pcidev, 1);
-+      sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
-+      if (!sc->sc_bar1) {
-+              device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
-+              goto fail;
-+      }
-+      sc->sc_bar1_lastreg = (bus_size_t) -1;
-+
-+      /* fix up the bus size */
-+      if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
-+              device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
-+              goto fail;
-+      }
-+      if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
-+              device_printf(sc->sc_dev,
-+                              "No usable consistent DMA configuration, aborting.\n");
-+              goto fail;
-+      }
-+
-+      hifn_set_retry(sc);
-+
-+      /*
-+       * Setup the area where the Hifn DMA's descriptors
-+       * and associated data structures.
-+       */
-+      sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
-+                      sizeof(*sc->sc_dma),
-+                      &sc->sc_dma_physaddr);
-+      if (!sc->sc_dma) {
-+              device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
-+              goto fail;
-+      }
-+      bzero(sc->sc_dma, sizeof(*sc->sc_dma));
-+
-+      /*
-+       * Reset the board and do the ``secret handshake''
-+       * to enable the crypto support.  Then complete the
-+       * initialization procedure by setting up the interrupt
-+       * and hooking in to the system crypto support so we'll
-+       * get used for system services like the crypto device,
-+       * IPsec, RNG device, etc.
-+       */
-+      hifn_reset_board(sc, 0);
-+
-+      if (hifn_enable_crypto(sc) != 0) {
-+              device_printf(sc->sc_dev, "crypto enabling failed\n");
-+              goto fail;
-+      }
-+      hifn_reset_puc(sc);
-+
-+      hifn_init_dma(sc);
-+      hifn_init_pci_registers(sc);
-+
-+      pci_set_master(sc->sc_pcidev);
-+
-+      /* 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;
-+
-+      if (sc->sc_drammodel == 0)
-+              hifn_sramsize(sc);
-+      else
-+              hifn_dramsize(sc);
-+
-+      /*
-+       * Workaround for NetSec 7751 rev A: half ram size because two
-+       * of the address lines were left floating
-+       */
-+      if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
-+          pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
-+          pci_get_revid(dev) == 0x61) /*XXX???*/
-+              sc->sc_ramsize >>= 1;
-+
-+      /*
-+       * Arrange the interrupt line.
-+       */
-+      rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
-+      if (rc) {
-+              device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
-+              goto fail;
-+      }
-+      sc->sc_irq = dev->irq;
-+
-+      hifn_sessions(sc);
-+
-+      /*
-+       * NB: Keep only the low 16 bits; this masks the chip id
-+       *     from the 7951.
-+       */
-+      rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
-+
-+      rseg = sc->sc_ramsize / 1024;
-+      rbase = 'K';
-+      if (sc->sc_ramsize >= (1024 * 1024)) {
-+              rbase = 'M';
-+              rseg /= 1024;
-+      }
-+      device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
-+              hifn_partname(sc), rev,
-+              rseg, rbase, sc->sc_drammodel ? 'd' : 's');
-+      if (sc->sc_flags & HIFN_IS_7956)
-+              printf(", 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));
-+      printf("\n");
-+
-+      sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
-+      if (sc->sc_cid < 0) {
-+              device_printf(sc->sc_dev, "could not get crypto driver id\n");
-+              goto fail;
-+      }
-+
-+      WRITE_REG_0(sc, HIFN_0_PUCNFG,
-+          READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
-+      ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
-+
-+      switch (ena) {
-+      case HIFN_PUSTAT_ENA_2:
-+              crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
-+              crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
-+              if (sc->sc_flags & HIFN_HAS_AES)
-+                      crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
-+              /*FALLTHROUGH*/
-+      case HIFN_PUSTAT_ENA_1:
-+              crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
-+              crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
-+              crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
-+              crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
-+              crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
-+              break;
-+      }
-+
-+      if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
-+              hifn_init_pubrng(sc);
-+
-+      init_timer(&sc->sc_tickto);
-+      sc->sc_tickto.function = hifn_tick;
-+      sc->sc_tickto.data = (unsigned long) sc->sc_num;
-+      mod_timer(&sc->sc_tickto, jiffies + HZ);
-+
-+      return (0);
-+
-+fail:
-+    if (sc->sc_cid >= 0)
-+        crypto_unregister_all(sc->sc_cid);
-+    if (sc->sc_irq != -1)
-+        free_irq(sc->sc_irq, sc);
-+    if (sc->sc_dma) {
-+              /* Turn off DMA polling */
-+              WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
-+                      HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+
-+        pci_free_consistent(sc->sc_pcidev,
-+                              sizeof(*sc->sc_dma),
-+                sc->sc_dma, sc->sc_dma_physaddr);
-+      }
-+    kfree(sc);
-+      return (-ENXIO);
-+}
-+
-+/*
-+ * Detach an interface that successfully probed.
-+ */
-+static void
-+hifn_remove(struct pci_dev *dev)
-+{
-+      struct hifn_softc *sc = pci_get_drvdata(dev);
-+      unsigned long l_flags;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
-+
-+      /* disable interrupts */
-+      HIFN_LOCK(sc);
-+      WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
-+      HIFN_UNLOCK(sc);
-+
-+      /*XXX other resources */
-+      del_timer_sync(&sc->sc_tickto);
-+
-+      /* Turn off DMA polling */
-+      WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
-+          HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+
-+      crypto_unregister_all(sc->sc_cid);
-+
-+      free_irq(sc->sc_irq, sc);
-+
-+      pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
-+                sc->sc_dma, sc->sc_dma_physaddr);
-+}
-+
-+
-+static int
-+hifn_init_pubrng(struct hifn_softc *sc)
-+{
-+      int i;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      if ((sc->sc_flags & HIFN_IS_7811) == 0) {
-+              /* Reset 7951 public key/rng engine */
-+              WRITE_REG_1(sc, HIFN_1_PUB_RESET,
-+                  READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
-+
-+              for (i = 0; i < 100; i++) {
-+                      DELAY(1000);
-+                      if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
-+                          HIFN_PUBRST_RESET) == 0)
-+                              break;
-+              }
-+
-+              if (i == 100) {
-+                      device_printf(sc->sc_dev, "public key init failed\n");
-+                      return (1);
-+              }
-+      }
-+
-+      /* Enable the rng, if available */
-+#ifdef CONFIG_OCF_RANDOMHARVEST
-+      if (sc->sc_flags & HIFN_HAS_RNG) {
-+              if (sc->sc_flags & HIFN_IS_7811) {
-+                      u_int32_t r;
-+                      r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
-+                      if (r & HIFN_7811_RNGENA_ENA) {
-+                              r &= ~HIFN_7811_RNGENA_ENA;
-+                              WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
-+                      }
-+                      WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
-+                          HIFN_7811_RNGCFG_DEFL);
-+                      r |= HIFN_7811_RNGENA_ENA;
-+                      WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
-+              } else
-+                      WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
-+                          READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
-+                          HIFN_RNGCFG_ENA);
-+
-+              sc->sc_rngfirst = 1;
-+              crypto_rregister(sc->sc_cid, hifn_read_random, sc);
-+      }
-+#endif
-+
-+      /* Enable public key engine, if available */
-+      if (sc->sc_flags & HIFN_HAS_PUBLIC) {
-+              WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
-+              sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
-+              WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
-+#ifdef HIFN_VULCANDEV
-+              sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0, 
-+                                      UID_ROOT, GID_WHEEL, 0666,
-+                                      "vulcanpk");
-+              sc->sc_pkdev->si_drv1 = sc;
-+#endif
-+      }
-+
-+      return (0);
-+}
-+
-+#ifdef CONFIG_OCF_RANDOMHARVEST
-+static int
-+hifn_read_random(void *arg, u_int32_t *buf, int len)
-+{
-+      struct hifn_softc *sc = (struct hifn_softc *) arg;
-+      u_int32_t sts;
-+      int i, rc = 0;
-+
-+      if (len <= 0)
-+              return rc;
-+
-+      if (sc->sc_flags & HIFN_IS_7811) {
-+              /* ONLY VALID ON 7811!!!! */
-+              for (i = 0; i < 5; i++) {
-+                      sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
-+                      if (sts & HIFN_7811_RNGSTS_UFL) {
-+                              device_printf(sc->sc_dev,
-+                                            "RNG underflow: disabling\n");
-+                              /* DAVIDM perhaps return -1 */
-+                              break;
-+                      }
-+                      if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
-+                              break;
-+
-+                      /*
-+                       * There are at least two words in the RNG FIFO
-+                       * at this point.
-+                       */
-+                      if (rc < len)
-+                              buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
-+                      if (rc < len)
-+                              buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
-+              }
-+      } else
-+              buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
-+
-+      /* NB: discard first data read */
-+      if (sc->sc_rngfirst) {
-+              sc->sc_rngfirst = 0;
-+              rc = 0;
-+      }
-+
-+      return(rc);
-+}
-+#endif /* CONFIG_OCF_RANDOMHARVEST */
-+
-+static void
-+hifn_puc_wait(struct hifn_softc *sc)
-+{
-+      int i;
-+      int reg = HIFN_0_PUCTRL;
-+
-+      if (sc->sc_flags & HIFN_IS_7956) {
-+              reg = HIFN_0_PUCTRL2;
-+      }
-+
-+      for (i = 5000; i > 0; i--) {
-+              DELAY(1);
-+              if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
-+                      break;
-+      }
-+      if (!i)
-+              device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
-+                              READ_REG_0(sc, HIFN_0_PUCTRL));
-+}
-+
-+/*
-+ * Reset the processing unit.
-+ */
-+static void
-+hifn_reset_puc(struct hifn_softc *sc)
-+{
-+      /* Reset processing unit */
-+      int reg = HIFN_0_PUCTRL;
-+
-+      if (sc->sc_flags & HIFN_IS_7956) {
-+              reg = HIFN_0_PUCTRL2;
-+      }
-+      WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
-+
-+      hifn_puc_wait(sc);
-+}
-+
-+/*
-+ * Set the Retry and TRDY registers; note that we set them to
-+ * zero because the 7811 locks up when forced to retry (section
-+ * 3.6 of "Specification Update SU-0014-04".  Not clear if we
-+ * should do this for all Hifn parts, but it doesn't seem to hurt.
-+ */
-+static void
-+hifn_set_retry(struct hifn_softc *sc)
-+{
-+      DPRINTF("%s()\n", __FUNCTION__);
-+      /* NB: RETRY only responds to 8-bit reads/writes */
-+      pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
-+      pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
-+}
-+
-+/*
-+ * Resets the board.  Values in the regesters are left as is
-+ * from the reset (i.e. initial values are assigned elsewhere).
-+ */
-+static void
-+hifn_reset_board(struct hifn_softc *sc, int full)
-+{
-+      u_int32_t reg;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+      /*
-+       * Set polling in the DMA configuration register to zero.  0x7 avoids
-+       * resetting the board and zeros out the other fields.
-+       */
-+      WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
-+          HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+
-+      /*
-+       * Now that polling has been disabled, we have to wait 1 ms
-+       * before resetting the board.
-+       */
-+      DELAY(1000);
-+
-+      /* Reset the DMA unit */
-+      if (full) {
-+              WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
-+              DELAY(1000);
-+      } else {
-+              WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
-+                  HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
-+              hifn_reset_puc(sc);
-+      }
-+
-+      KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
-+      bzero(sc->sc_dma, sizeof(*sc->sc_dma));
-+
-+      /* Bring dma unit out of reset */
-+      WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
-+          HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+
-+      hifn_puc_wait(sc);
-+      hifn_set_retry(sc);
-+
-+      if (sc->sc_flags & HIFN_IS_7811) {
-+              for (reg = 0; reg < 1000; reg++) {
-+                      if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
-+                          HIFN_MIPSRST_CRAMINIT)
-+                              break;
-+                      DELAY(1000);
-+              }
-+              if (reg == 1000)
-+                      device_printf(sc->sc_dev, ": cram init timeout\n");
-+      } else {
-+        /* set up DMA configuration register #2 */
-+        /* turn off all PK and BAR0 swaps */
-+        WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
-+                    (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
-+                    (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
-+                    (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
-+                    (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
-+      }
-+}
-+
-+static u_int32_t
-+hifn_next_signature(u_int32_t a, u_int cnt)
-+{
-+      int i;
-+      u_int32_t v;
-+
-+      for (i = 0; i < cnt; i++) {
-+
-+              /* get the parity */
-+              v = a & 0x80080125;
-+              v ^= v >> 16;
-+              v ^= v >> 8;
-+              v ^= v >> 4;
-+              v ^= v >> 2;
-+              v ^= v >> 1;
-+
-+              a = (v & 1) ^ (a << 1);
-+      }
-+
-+      return a;
-+}
-+
-+
-+/*
-+ * Checks to see if crypto is already enabled.  If crypto isn't enable,
-+ * "hifn_enable_crypto" is called to enable it.  The check is important,
-+ * as enabling crypto twice will lock the board.
-+ */
-+static int 
-+hifn_enable_crypto(struct hifn_softc *sc)
-+{
-+      u_int32_t dmacfg, ramcfg, encl, addr, i;
-+      char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+                                        0x00, 0x00, 0x00, 0x00 };
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
-+      dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
-+
-+      /*
-+       * The RAM config register's encrypt level bit needs to be set before
-+       * every read performed on the encryption level register.
-+       */
-+      WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
-+
-+      encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
-+
-+      /*
-+       * Make sure we don't re-unlock.  Two unlocks kills chip until the
-+       * next reboot.
-+       */
-+      if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
-+#ifdef HIFN_DEBUG
-+              if (hifn_debug)
-+                      device_printf(sc->sc_dev,
-+                          "Strong crypto already enabled!\n");
-+#endif
-+              goto report;
-+      }
-+
-+      if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
-+#ifdef HIFN_DEBUG
-+              if (hifn_debug)
-+                      device_printf(sc->sc_dev,
-+                            "Unknown encryption level 0x%x\n", encl);
-+#endif
-+              return 1;
-+      }
-+
-+      WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
-+          HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+      DELAY(1000);
-+      addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
-+      DELAY(1000);
-+      WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
-+      DELAY(1000);
-+
-+      for (i = 0; i <= 12; i++) {
-+              addr = hifn_next_signature(addr, offtbl[i] + 0x101);
-+              WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
-+
-+              DELAY(1000);
-+      }
-+
-+      WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
-+      encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
-+
-+#ifdef HIFN_DEBUG
-+      if (hifn_debug) {
-+              if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
-+                      device_printf(sc->sc_dev, "Engine is permanently "
-+                              "locked until next system reset!\n");
-+              else
-+                      device_printf(sc->sc_dev, "Engine enabled "
-+                              "successfully!\n");
-+      }
-+#endif
-+
-+report:
-+      WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
-+      WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
-+
-+      switch (encl) {
-+      case HIFN_PUSTAT_ENA_1:
-+      case HIFN_PUSTAT_ENA_2:
-+              break;
-+      case HIFN_PUSTAT_ENA_0:
-+      default:
-+              device_printf(sc->sc_dev, "disabled\n");
-+              break;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-+ * Give initial values to the registers listed in the "Register Space"
-+ * section of the HIFN Software Development reference manual.
-+ */
-+static void 
-+hifn_init_pci_registers(struct hifn_softc *sc)
-+{
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      /* write fixed values needed by the Initialization registers */
-+      WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
-+      WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
-+      WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
-+
-+      /* write all 4 ring address registers */
-+      WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
-+          offsetof(struct hifn_dma, cmdr[0]));
-+      WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
-+          offsetof(struct hifn_dma, srcr[0]));
-+      WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
-+          offsetof(struct hifn_dma, dstr[0]));
-+      WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
-+          offsetof(struct hifn_dma, resr[0]));
-+
-+      DELAY(2000);
-+
-+      /* write status register */
-+      WRITE_REG_1(sc, HIFN_1_DMA_CSR,
-+          HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
-+          HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
-+          HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
-+          HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
-+          HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
-+          HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
-+          HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
-+          HIFN_DMACSR_S_WAIT |
-+          HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
-+          HIFN_DMACSR_C_WAIT |
-+          HIFN_DMACSR_ENGINE |
-+          ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
-+              HIFN_DMACSR_PUBDONE : 0) |
-+          ((sc->sc_flags & HIFN_IS_7811) ?
-+              HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
-+
-+      sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
-+      sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
-+          HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
-+          HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
-+          ((sc->sc_flags & HIFN_IS_7811) ?
-+              HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
-+      sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
-+      WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
-+
-+
-+      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 | HIFN_PLL_MBSET;
-+              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 |
-+          HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
-+          ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
-+          ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
-+}
-+
-+/*
-+ * The maximum number of sessions supported by the card
-+ * is dependent on the amount of context ram, which
-+ * encryption algorithms are enabled, and how compression
-+ * is configured.  This should be configured before this
-+ * routine is called.
-+ */
-+static void
-+hifn_sessions(struct hifn_softc *sc)
-+{
-+      u_int32_t pucnfg;
-+      int ctxsize;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
-+
-+      if (pucnfg & HIFN_PUCNFG_COMPSING) {
-+              if (pucnfg & HIFN_PUCNFG_ENCCNFG)
-+                      ctxsize = 128;
-+              else
-+                      ctxsize = 512;
-+              /*
-+               * 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;
-+
-+      if (sc->sc_maxses > 2048)
-+              sc->sc_maxses = 2048;
-+}
-+
-+/*
-+ * Determine ram type (sram or dram).  Board should be just out of a reset
-+ * state when this is called.
-+ */
-+static int
-+hifn_ramtype(struct hifn_softc *sc)
-+{
-+      u_int8_t data[8], dataexpect[8];
-+      int i;
-+
-+      for (i = 0; i < sizeof(data); i++)
-+              data[i] = dataexpect[i] = 0x55;
-+      if (hifn_writeramaddr(sc, 0, data))
-+              return (-1);
-+      if (hifn_readramaddr(sc, 0, data))
-+              return (-1);
-+      if (bcmp(data, dataexpect, sizeof(data)) != 0) {
-+              sc->sc_drammodel = 1;
-+              return (0);
-+      }
-+
-+      for (i = 0; i < sizeof(data); i++)
-+              data[i] = dataexpect[i] = 0xaa;
-+      if (hifn_writeramaddr(sc, 0, data))
-+              return (-1);
-+      if (hifn_readramaddr(sc, 0, data))
-+              return (-1);
-+      if (bcmp(data, dataexpect, sizeof(data)) != 0) {
-+              sc->sc_drammodel = 1;
-+              return (0);
-+      }
-+
-+      return (0);
-+}
-+
-+#define       HIFN_SRAM_MAX           (32 << 20)
-+#define       HIFN_SRAM_STEP_SIZE     16384
-+#define       HIFN_SRAM_GRANULARITY   (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
-+
-+static int
-+hifn_sramsize(struct hifn_softc *sc)
-+{
-+      u_int32_t a;
-+      u_int8_t data[8];
-+      u_int8_t dataexpect[sizeof(data)];
-+      int32_t i;
-+
-+      for (i = 0; i < sizeof(data); i++)
-+              data[i] = dataexpect[i] = i ^ 0x5a;
-+
-+      for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
-+              a = i * HIFN_SRAM_STEP_SIZE;
-+              bcopy(&i, data, sizeof(i));
-+              hifn_writeramaddr(sc, a, data);
-+      }
-+
-+      for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
-+              a = i * HIFN_SRAM_STEP_SIZE;
-+              bcopy(&i, dataexpect, sizeof(i));
-+              if (hifn_readramaddr(sc, a, data) < 0)
-+                      return (0);
-+              if (bcmp(data, dataexpect, sizeof(data)) != 0)
-+                      return (0);
-+              sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
-+      }
-+
-+      return (0);
-+}
-+
-+/*
-+ * XXX For dram boards, one should really try all of the
-+ * HIFN_PUCNFG_DSZ_*'s.  This just assumes that PUCNFG
-+ * is already set up correctly.
-+ */
-+static int
-+hifn_dramsize(struct hifn_softc *sc)
-+{
-+      u_int32_t cnfg;
-+
-+      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);
-+}
-+
-+static void
-+hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      if (dma->cmdi == HIFN_D_CMD_RSIZE) {
-+              dma->cmdi = 0;
-+              dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
-+              HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+      }
-+      *cmdp = dma->cmdi++;
-+      dma->cmdk = dma->cmdi;
-+
-+      if (dma->srci == HIFN_D_SRC_RSIZE) {
-+              dma->srci = 0;
-+              dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
-+              HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+      }
-+      *srcp = dma->srci++;
-+      dma->srck = dma->srci;
-+
-+      if (dma->dsti == HIFN_D_DST_RSIZE) {
-+              dma->dsti = 0;
-+              dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
-+              HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+      }
-+      *dstp = dma->dsti++;
-+      dma->dstk = dma->dsti;
-+
-+      if (dma->resi == HIFN_D_RES_RSIZE) {
-+              dma->resi = 0;
-+              dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
-+              HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+      }
-+      *resp = dma->resi++;
-+      dma->resk = dma->resi;
-+}
-+
-+static int
-+hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      hifn_base_command_t wc;
-+      const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
-+      int r, cmdi, resi, srci, dsti;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      wc.masks = htole16(3 << 13);
-+      wc.session_num = htole16(addr >> 14);
-+      wc.total_source_count = htole16(8);
-+      wc.total_dest_count = htole16(addr & 0x3fff);
-+
-+      hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
-+
-+      WRITE_REG_1(sc, HIFN_1_DMA_CSR,
-+          HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
-+          HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
-+
-+      /* build write command */
-+      bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
-+      *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
-+      bcopy(data, &dma->test_src, sizeof(dma->test_src));
-+
-+      dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
-+          + offsetof(struct hifn_dma, test_src));
-+      dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
-+          + offsetof(struct hifn_dma, test_dst));
-+
-+      dma->cmdr[cmdi].l = htole32(16 | masks);
-+      dma->srcr[srci].l = htole32(8 | masks);
-+      dma->dstr[dsti].l = htole32(4 | masks);
-+      dma->resr[resi].l = htole32(4 | masks);
-+
-+      for (r = 10000; r >= 0; r--) {
-+              DELAY(10);
-+              if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
-+                      break;
-+      }
-+      if (r == 0) {
-+              device_printf(sc->sc_dev, "writeramaddr -- "
-+                  "result[%d](addr %d) still valid\n", resi, addr);
-+              r = -1;
-+              return (-1);
-+      } else
-+              r = 0;
-+
-+      WRITE_REG_1(sc, HIFN_1_DMA_CSR,
-+          HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
-+          HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
-+
-+      return (r);
-+}
-+
-+static int
-+hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      hifn_base_command_t rc;
-+      const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
-+      int r, cmdi, srci, dsti, resi;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      rc.masks = htole16(2 << 13);
-+      rc.session_num = htole16(addr >> 14);
-+      rc.total_source_count = htole16(addr & 0x3fff);
-+      rc.total_dest_count = htole16(8);
-+
-+      hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
-+
-+      WRITE_REG_1(sc, HIFN_1_DMA_CSR,
-+          HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
-+          HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
-+
-+      bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
-+      *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
-+
-+      dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
-+          offsetof(struct hifn_dma, test_src));
-+      dma->test_src = 0;
-+      dma->dstr[dsti].p =  htole32(sc->sc_dma_physaddr +
-+          offsetof(struct hifn_dma, test_dst));
-+      dma->test_dst = 0;
-+      dma->cmdr[cmdi].l = htole32(8 | masks);
-+      dma->srcr[srci].l = htole32(8 | masks);
-+      dma->dstr[dsti].l = htole32(8 | masks);
-+      dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
-+
-+      for (r = 10000; r >= 0; r--) {
-+              DELAY(10);
-+              if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
-+                      break;
-+      }
-+      if (r == 0) {
-+              device_printf(sc->sc_dev, "readramaddr -- "
-+                  "result[%d](addr %d) still valid\n", resi, addr);
-+              r = -1;
-+      } else {
-+              r = 0;
-+              bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
-+      }
-+
-+      WRITE_REG_1(sc, HIFN_1_DMA_CSR,
-+          HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
-+          HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
-+
-+      return (r);
-+}
-+
-+/*
-+ * Initialize the descriptor rings.
-+ */
-+static void 
-+hifn_init_dma(struct hifn_softc *sc)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      int i;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      hifn_set_retry(sc);
-+
-+      /* initialize static pointer values */
-+      for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
-+              dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
-+                  offsetof(struct hifn_dma, command_bufs[i][0]));
-+      for (i = 0; i < HIFN_D_RES_RSIZE; i++)
-+              dma->resr[i].p = htole32(sc->sc_dma_physaddr +
-+                  offsetof(struct hifn_dma, result_bufs[i][0]));
-+
-+      dma->cmdr[HIFN_D_CMD_RSIZE].p =
-+          htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
-+      dma->srcr[HIFN_D_SRC_RSIZE].p =
-+          htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
-+      dma->dstr[HIFN_D_DST_RSIZE].p =
-+          htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
-+      dma->resr[HIFN_D_RES_RSIZE].p =
-+          htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
-+
-+      dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
-+      dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
-+      dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
-+}
-+
-+/*
-+ * Writes out the raw command buffer space.  Returns the
-+ * command buffer size.
-+ */
-+static u_int
-+hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
-+{
-+      struct hifn_softc *sc = NULL;
-+      u_int8_t *buf_pos;
-+      hifn_base_command_t *base_cmd;
-+      hifn_mac_command_t *mac_cmd;
-+      hifn_crypt_command_t *cry_cmd;
-+      int using_mac, using_crypt, len, ivlen;
-+      u_int32_t dlen, slen;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      buf_pos = buf;
-+      using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
-+      using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
-+
-+      base_cmd = (hifn_base_command_t *)buf_pos;
-+      base_cmd->masks = htole16(cmd->base_masks);
-+      slen = cmd->src_mapsize;
-+      if (cmd->sloplen)
-+              dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
-+      else
-+              dlen = cmd->dst_mapsize;
-+      base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
-+      base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
-+      dlen >>= 16;
-+      slen >>= 16;
-+      base_cmd->session_num = htole16(
-+          ((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);
-+
-+      if (using_mac) {
-+              mac_cmd = (hifn_mac_command_t *)buf_pos;
-+              dlen = cmd->maccrd->crd_len;
-+              mac_cmd->source_count = htole16(dlen & 0xffff);
-+              dlen >>= 16;
-+              mac_cmd->masks = htole16(cmd->mac_masks |
-+                  ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
-+              mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
-+              mac_cmd->reserved = 0;
-+              buf_pos += sizeof(hifn_mac_command_t);
-+      }
-+
-+      if (using_crypt) {
-+              cry_cmd = (hifn_crypt_command_t *)buf_pos;
-+              dlen = cmd->enccrd->crd_len;
-+              cry_cmd->source_count = htole16(dlen & 0xffff);
-+              dlen >>= 16;
-+              cry_cmd->masks = htole16(cmd->cry_masks |
-+                  ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
-+              cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
-+              cry_cmd->reserved = 0;
-+              buf_pos += sizeof(hifn_crypt_command_t);
-+      }
-+
-+      if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
-+              bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
-+              buf_pos += HIFN_MAC_KEY_LENGTH;
-+      }
-+
-+      if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
-+              switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
-+              case HIFN_CRYPT_CMD_ALG_3DES:
-+                      bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
-+                      buf_pos += HIFN_3DES_KEY_LENGTH;
-+                      break;
-+              case HIFN_CRYPT_CMD_ALG_DES:
-+                      bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
-+                      buf_pos += HIFN_DES_KEY_LENGTH;
-+                      break;
-+              case HIFN_CRYPT_CMD_ALG_RC4:
-+                      len = 256;
-+                      do {
-+                              int clen;
-+
-+                              clen = MIN(cmd->cklen, len);
-+                              bcopy(cmd->ck, buf_pos, clen);
-+                              len -= clen;
-+                              buf_pos += clen;
-+                      } while (len > 0);
-+                      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) {
-+              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) {
-+              bzero(buf_pos, 8);
-+              buf_pos += 8;
-+      }
-+
-+      return (buf_pos - buf);
-+}
-+
-+static int
-+hifn_dmamap_aligned(struct hifn_operand *op)
-+{
-+      struct hifn_softc *sc = NULL;
-+      int i;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      for (i = 0; i < op->nsegs; i++) {
-+              if (op->segs[i].ds_addr & 3)
-+                      return (0);
-+              if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
-+                      return (0);
-+      }
-+      return (1);
-+}
-+
-+static __inline int
-+hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+
-+      if (++idx == HIFN_D_DST_RSIZE) {
-+              dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
-+                  HIFN_D_MASKDONEIRQ);
-+              HIFN_DSTR_SYNC(sc, idx,
-+                  BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+              idx = 0;
-+      }
-+      return (idx);
-+}
-+
-+static int
-+hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      struct hifn_operand *dst = &cmd->dst;
-+      u_int32_t p, l;
-+      int idx, used = 0, i;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      idx = dma->dsti;
-+      for (i = 0; i < dst->nsegs - 1; i++) {
-+              dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
-+              dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
-+              wmb();
-+              dma->dstr[idx].l |= htole32(HIFN_D_VALID);
-+              HIFN_DSTR_SYNC(sc, idx,
-+                  BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+              used++;
-+
-+              idx = hifn_dmamap_dstwrap(sc, idx);
-+      }
-+
-+      if (cmd->sloplen == 0) {
-+              p = dst->segs[i].ds_addr;
-+              l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
-+                  dst->segs[i].ds_len;
-+      } else {
-+              p = sc->sc_dma_physaddr +
-+                  offsetof(struct hifn_dma, slop[cmd->slopidx]);
-+              l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
-+                  sizeof(u_int32_t);
-+
-+              if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
-+                      dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
-+                      dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
-+                          (dst->segs[i].ds_len - cmd->sloplen));
-+                      wmb();
-+                      dma->dstr[idx].l |= htole32(HIFN_D_VALID);
-+                      HIFN_DSTR_SYNC(sc, idx,
-+                          BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+                      used++;
-+
-+                      idx = hifn_dmamap_dstwrap(sc, idx);
-+              }
-+      }
-+      dma->dstr[idx].p = htole32(p);
-+      dma->dstr[idx].l = htole32(l);
-+      wmb();
-+      dma->dstr[idx].l |= htole32(HIFN_D_VALID);
-+      HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+      used++;
-+
-+      idx = hifn_dmamap_dstwrap(sc, idx);
-+
-+      dma->dsti = idx;
-+      dma->dstu += used;
-+      return (idx);
-+}
-+
-+static __inline int
-+hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+
-+      if (++idx == HIFN_D_SRC_RSIZE) {
-+              dma->srcr[idx].l = htole32(HIFN_D_VALID |
-+                  HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
-+              HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+              idx = 0;
-+      }
-+      return (idx);
-+}
-+
-+static int
-+hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      struct hifn_operand *src = &cmd->src;
-+      int idx, i;
-+      u_int32_t last = 0;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      idx = dma->srci;
-+      for (i = 0; i < src->nsegs; i++) {
-+              if (i == src->nsegs - 1)
-+                      last = HIFN_D_LAST;
-+
-+              dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
-+              dma->srcr[idx].l = htole32(src->segs[i].ds_len |
-+                  HIFN_D_MASKDONEIRQ | last);
-+              wmb();
-+              dma->srcr[idx].l |= htole32(HIFN_D_VALID);
-+              HIFN_SRCR_SYNC(sc, idx,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+
-+              idx = hifn_dmamap_srcwrap(sc, idx);
-+      }
-+      dma->srci = idx;
-+      dma->srcu += src->nsegs;
-+      return (idx);
-+} 
-+
-+
-+static int 
-+hifn_crypto(
-+      struct hifn_softc *sc,
-+      struct hifn_command *cmd,
-+      struct cryptop *crp,
-+      int hint)
-+{
-+      struct  hifn_dma *dma = sc->sc_dma;
-+      u_int32_t cmdlen, csr;
-+      int cmdi, resi, err = 0;
-+      unsigned long l_flags;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      /*
-+       * need 1 cmd, and 1 res
-+       *
-+       * NB: check this first since it's easy.
-+       */
-+      HIFN_LOCK(sc);
-+      if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
-+          (dma->resu + 1) > HIFN_D_RES_RSIZE) {
-+#ifdef HIFN_DEBUG
-+              if (hifn_debug) {
-+                      device_printf(sc->sc_dev,
-+                              "cmd/result exhaustion, cmdu %u resu %u\n",
-+                              dma->cmdu, dma->resu);
-+              }
-+#endif
-+              hifnstats.hst_nomem_cr++;
-+              sc->sc_needwakeup |= CRYPTO_SYMQ;
-+              HIFN_UNLOCK(sc);
-+              return (ERESTART);
-+      }
-+
-+      if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+              if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
-+                      hifnstats.hst_nomem_load++;
-+                      err = ENOMEM;
-+                      goto err_srcmap1;
-+              }
-+      } else if (crp->crp_flags & CRYPTO_F_IOV) {
-+              if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
-+                      hifnstats.hst_nomem_load++;
-+                      err = ENOMEM;
-+                      goto err_srcmap1;
-+              }
-+      } else {
-+              if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
-+                      hifnstats.hst_nomem_load++;
-+                      err = ENOMEM;
-+                      goto err_srcmap1;
-+              }
-+      }
-+
-+      if (hifn_dmamap_aligned(&cmd->src)) {
-+              cmd->sloplen = cmd->src_mapsize & 3;
-+              cmd->dst = cmd->src;
-+      } else {
-+              if (crp->crp_flags & CRYPTO_F_IOV) {
-+                      DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                      err = EINVAL;
-+                      goto err_srcmap;
-+              } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+#ifdef NOTYET
-+                      int totlen, len;
-+                      struct mbuf *m, *m0, *mlast;
-+
-+                      KASSERT(cmd->dst_m == cmd->src_m,
-+                              ("hifn_crypto: dst_m initialized improperly"));
-+                      hifnstats.hst_unaligned++;
-+                      /*
-+                       * Source is not aligned on a longword boundary.
-+                       * Copy the data to insure alignment.  If we fail
-+                       * to allocate mbufs or clusters while doing this
-+                       * we return ERESTART so the operation is requeued
-+                       * at the crypto later, but only if there are
-+                       * ops already posted to the hardware; otherwise we
-+                       * have no guarantee that we'll be re-entered.
-+                       */
-+                      totlen = cmd->src_mapsize;
-+                      if (cmd->src_m->m_flags & M_PKTHDR) {
-+                              len = MHLEN;
-+                              MGETHDR(m0, M_DONTWAIT, MT_DATA);
-+                              if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
-+                                      m_free(m0);
-+                                      m0 = NULL;
-+                              }
-+                      } else {
-+                              len = MLEN;
-+                              MGET(m0, M_DONTWAIT, MT_DATA);
-+                      }
-+                      if (m0 == NULL) {
-+                              hifnstats.hst_nomem_mbuf++;
-+                              err = dma->cmdu ? ERESTART : ENOMEM;
-+                              goto err_srcmap;
-+                      }
-+                      if (totlen >= MINCLSIZE) {
-+                              MCLGET(m0, M_DONTWAIT);
-+                              if ((m0->m_flags & M_EXT) == 0) {
-+                                      hifnstats.hst_nomem_mcl++;
-+                                      err = dma->cmdu ? ERESTART : ENOMEM;
-+                                      m_freem(m0);
-+                                      goto err_srcmap;
-+                              }
-+                              len = MCLBYTES;
-+                      }
-+                      totlen -= len;
-+                      m0->m_pkthdr.len = m0->m_len = len;
-+                      mlast = m0;
-+
-+                      while (totlen > 0) {
-+                              MGET(m, M_DONTWAIT, MT_DATA);
-+                              if (m == NULL) {
-+                                      hifnstats.hst_nomem_mbuf++;
-+                                      err = dma->cmdu ? ERESTART : ENOMEM;
-+                                      m_freem(m0);
-+                                      goto err_srcmap;
-+                              }
-+                              len = MLEN;
-+                              if (totlen >= MINCLSIZE) {
-+                                      MCLGET(m, M_DONTWAIT);
-+                                      if ((m->m_flags & M_EXT) == 0) {
-+                                              hifnstats.hst_nomem_mcl++;
-+                                              err = dma->cmdu ? ERESTART : ENOMEM;
-+                                              mlast->m_next = m;
-+                                              m_freem(m0);
-+                                              goto err_srcmap;
-+                                      }
-+                                      len = MCLBYTES;
-+                              }
-+
-+                              m->m_len = len;
-+                              m0->m_pkthdr.len += len;
-+                              totlen -= len;
-+
-+                              mlast->m_next = m;
-+                              mlast = m;
-+                      }
-+                      cmd->dst_m = m0;
-+#else
-+                      device_printf(sc->sc_dev,
-+                                      "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
-+                                      __FILE__, __LINE__);
-+                      err = EINVAL;
-+                      goto err_srcmap;
-+#endif
-+              } else {
-+                      device_printf(sc->sc_dev,
-+                                      "%s,%d: unaligned contig buffers not implemented\n",
-+                                      __FILE__, __LINE__);
-+                      err = EINVAL;
-+                      goto err_srcmap;
-+              }
-+      }
-+
-+      if (cmd->dst_map == NULL) {
-+              if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+                      if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
-+                              hifnstats.hst_nomem_map++;
-+                              err = ENOMEM;
-+                              goto err_dstmap1;
-+                      }
-+              } else if (crp->crp_flags & CRYPTO_F_IOV) {
-+                      if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
-+                              hifnstats.hst_nomem_load++;
-+                              err = ENOMEM;
-+                              goto err_dstmap1;
-+                      }
-+              } else {
-+                      if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
-+                              hifnstats.hst_nomem_load++;
-+                              err = ENOMEM;
-+                              goto err_dstmap1;
-+                      }
-+              }
-+      }
-+
-+#ifdef HIFN_DEBUG
-+      if (hifn_debug) {
-+              device_printf(sc->sc_dev,
-+                  "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
-+                  READ_REG_1(sc, HIFN_1_DMA_CSR),
-+                  READ_REG_1(sc, HIFN_1_DMA_IER),
-+                  dma->cmdu, dma->srcu, dma->dstu, dma->resu,
-+                  cmd->src_nsegs, cmd->dst_nsegs);
-+      }
-+#endif
-+
-+#if 0
-+      if (cmd->src_map == cmd->dst_map) {
-+              bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
-+                  BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
-+      } else {
-+              bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
-+                  BUS_DMASYNC_PREWRITE);
-+              bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
-+                  BUS_DMASYNC_PREREAD);
-+      }
-+#endif
-+
-+      /*
-+       * need N src, and N dst
-+       */
-+      if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
-+          (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
-+#ifdef HIFN_DEBUG
-+              if (hifn_debug) {
-+                      device_printf(sc->sc_dev,
-+                              "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
-+                              dma->srcu, cmd->src_nsegs,
-+                              dma->dstu, cmd->dst_nsegs);
-+              }
-+#endif
-+              hifnstats.hst_nomem_sd++;
-+              err = ERESTART;
-+              goto err_dstmap;
-+      }
-+
-+      if (dma->cmdi == HIFN_D_CMD_RSIZE) {
-+              dma->cmdi = 0;
-+              dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
-+              HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
-+                  BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+      }
-+      cmdi = dma->cmdi++;
-+      cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
-+      HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
-+
-+      /* .p for command/result already set */
-+      dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
-+          HIFN_D_MASKDONEIRQ);
-+      wmb();
-+      dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
-+      HIFN_CMDR_SYNC(sc, cmdi,
-+          BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-+      dma->cmdu++;
-+
-+      /*
-+       * We don't worry about missing an interrupt (which a "command wait"
-+       * interrupt salvages us from), unless there is more than one command
-+       * in the queue.
-+       */
-+      if (dma->cmdu > 1) {
-+              sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
-+              WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
-+      }
-+
-+      hifnstats.hst_ipackets++;
-+      hifnstats.hst_ibytes += cmd->src_mapsize;
-+
-+      hifn_dmamap_load_src(sc, cmd);
-+
-+      /*
-+       * Unlike other descriptors, we don't mask done interrupt from
-+       * result descriptor.
-+       */
-+#ifdef HIFN_DEBUG
-+      if (hifn_debug)
-+              device_printf(sc->sc_dev, "load res\n");
-+#endif
-+      if (dma->resi == HIFN_D_RES_RSIZE) {
-+              dma->resi = 0;
-+              dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
-+              HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
-+                  BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+      }
-+      resi = dma->resi++;
-+      KASSERT(dma->hifn_commands[resi] == NULL,
-+              ("hifn_crypto: command slot %u busy", resi));
-+      dma->hifn_commands[resi] = cmd;
-+      HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
-+      if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
-+              dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
-+                  HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
-+              wmb();
-+              dma->resr[resi].l |= htole32(HIFN_D_VALID);
-+              sc->sc_curbatch++;
-+              if (sc->sc_curbatch > hifnstats.hst_maxbatch)
-+                      hifnstats.hst_maxbatch = sc->sc_curbatch;
-+              hifnstats.hst_totbatch++;
-+      } else {
-+              dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
-+              wmb();
-+              dma->resr[resi].l |= htole32(HIFN_D_VALID);
-+              sc->sc_curbatch = 0;
-+      }
-+      HIFN_RESR_SYNC(sc, resi,
-+          BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+      dma->resu++;
-+
-+      if (cmd->sloplen)
-+              cmd->slopidx = resi;
-+
-+      hifn_dmamap_load_dst(sc, cmd);
-+
-+      csr = 0;
-+      if (sc->sc_c_busy == 0) {
-+              csr |= HIFN_DMACSR_C_CTRL_ENA;
-+              sc->sc_c_busy = 1;
-+      }
-+      if (sc->sc_s_busy == 0) {
-+              csr |= HIFN_DMACSR_S_CTRL_ENA;
-+              sc->sc_s_busy = 1;
-+      }
-+      if (sc->sc_r_busy == 0) {
-+              csr |= HIFN_DMACSR_R_CTRL_ENA;
-+              sc->sc_r_busy = 1;
-+      }
-+      if (sc->sc_d_busy == 0) {
-+              csr |= HIFN_DMACSR_D_CTRL_ENA;
-+              sc->sc_d_busy = 1;
-+      }
-+      if (csr)
-+              WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
-+
-+#ifdef HIFN_DEBUG
-+      if (hifn_debug) {
-+              device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
-+                  READ_REG_1(sc, HIFN_1_DMA_CSR),
-+                  READ_REG_1(sc, HIFN_1_DMA_IER));
-+      }
-+#endif
-+
-+      sc->sc_active = 5;
-+      HIFN_UNLOCK(sc);
-+      KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
-+      return (err);           /* success */
-+
-+err_dstmap:
-+      if (cmd->src_map != cmd->dst_map)
-+              pci_unmap_buf(sc, &cmd->dst);
-+err_dstmap1:
-+err_srcmap:
-+      if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+              if (cmd->src_skb != cmd->dst_skb)
-+#ifdef NOTYET
-+                      m_freem(cmd->dst_m);
-+#else
-+                      device_printf(sc->sc_dev,
-+                                      "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
-+                                      __FILE__, __LINE__);
-+#endif
-+      }
-+      pci_unmap_buf(sc, &cmd->src);
-+err_srcmap1:
-+      HIFN_UNLOCK(sc);
-+      return (err);
-+}
-+
-+static void
-+hifn_tick(unsigned long arg)
-+{
-+      struct hifn_softc *sc;
-+      unsigned long l_flags;
-+
-+      if (arg >= HIFN_MAX_CHIPS)
-+              return;
-+      sc = hifn_chip_idx[arg];
-+      if (!sc)
-+              return;
-+
-+      HIFN_LOCK(sc);
-+      if (sc->sc_active == 0) {
-+              struct hifn_dma *dma = sc->sc_dma;
-+              u_int32_t r = 0;
-+
-+              if (dma->cmdu == 0 && sc->sc_c_busy) {
-+                      sc->sc_c_busy = 0;
-+                      r |= HIFN_DMACSR_C_CTRL_DIS;
-+              }
-+              if (dma->srcu == 0 && sc->sc_s_busy) {
-+                      sc->sc_s_busy = 0;
-+                      r |= HIFN_DMACSR_S_CTRL_DIS;
-+              }
-+              if (dma->dstu == 0 && sc->sc_d_busy) {
-+                      sc->sc_d_busy = 0;
-+                      r |= HIFN_DMACSR_D_CTRL_DIS;
-+              }
-+              if (dma->resu == 0 && sc->sc_r_busy) {
-+                      sc->sc_r_busy = 0;
-+                      r |= HIFN_DMACSR_R_CTRL_DIS;
-+              }
-+              if (r)
-+                      WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
-+      } else
-+              sc->sc_active--;
-+      HIFN_UNLOCK(sc);
-+      mod_timer(&sc->sc_tickto, jiffies + HZ);
-+}
-+
-+static irqreturn_t
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-+hifn_intr(int irq, void *arg)
-+#else
-+hifn_intr(int irq, void *arg, struct pt_regs *regs)
-+#endif
-+{
-+      struct hifn_softc *sc = arg;
-+      struct hifn_dma *dma;
-+      u_int32_t dmacsr, restart;
-+      int i, u;
-+      unsigned long l_flags;
-+
-+      dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
-+
-+      /* Nothing in the DMA unit interrupted */
-+      if ((dmacsr & sc->sc_dmaier) == 0)
-+              return IRQ_NONE;
-+
-+      HIFN_LOCK(sc);
-+
-+      dma = sc->sc_dma;
-+
-+#ifdef HIFN_DEBUG
-+      if (hifn_debug) {
-+              device_printf(sc->sc_dev,
-+                  "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
-+                  dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
-+                  dma->cmdi, dma->srci, dma->dsti, dma->resi,
-+                  dma->cmdk, dma->srck, dma->dstk, dma->resk,
-+                  dma->cmdu, dma->srcu, dma->dstu, dma->resu);
-+      }
-+#endif
-+
-+      WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
-+
-+      if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
-+          (dmacsr & HIFN_DMACSR_PUBDONE))
-+              WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
-+                  READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
-+
-+      restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
-+      if (restart)
-+              device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
-+
-+      if (sc->sc_flags & HIFN_IS_7811) {
-+              if (dmacsr & HIFN_DMACSR_ILLR)
-+                      device_printf(sc->sc_dev, "illegal read\n");
-+              if (dmacsr & HIFN_DMACSR_ILLW)
-+                      device_printf(sc->sc_dev, "illegal write\n");
-+      }
-+
-+      restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
-+          HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
-+      if (restart) {
-+              device_printf(sc->sc_dev, "abort, resetting.\n");
-+              hifnstats.hst_abort++;
-+              hifn_abort(sc);
-+              HIFN_UNLOCK(sc);
-+              return IRQ_HANDLED;
-+      }
-+
-+      if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
-+              /*
-+               * If no slots to process and we receive a "waiting on
-+               * command" interrupt, we disable the "waiting on command"
-+               * (by clearing it).
-+               */
-+              sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
-+              WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
-+      }
-+
-+      /* clear the rings */
-+      i = dma->resk; u = dma->resu;
-+      while (u != 0) {
-+              HIFN_RESR_SYNC(sc, i,
-+                  BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-+              if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
-+                      HIFN_RESR_SYNC(sc, i,
-+                          BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+                      break;
-+              }
-+
-+              if (i != HIFN_D_RES_RSIZE) {
-+                      struct hifn_command *cmd;
-+                      u_int8_t *macbuf = NULL;
-+
-+                      HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
-+                      cmd = dma->hifn_commands[i];
-+                      KASSERT(cmd != NULL,
-+                              ("hifn_intr: null command slot %u", i));
-+                      dma->hifn_commands[i] = NULL;
-+
-+                      if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
-+                              macbuf = dma->result_bufs[i];
-+                              macbuf += 12;
-+                      }
-+
-+                      hifn_callback(sc, cmd, macbuf);
-+                      hifnstats.hst_opackets++;
-+                      u--;
-+              }
-+
-+              if (++i == (HIFN_D_RES_RSIZE + 1))
-+                      i = 0;
-+      }
-+      dma->resk = i; dma->resu = u;
-+
-+      i = dma->srck; u = dma->srcu;
-+      while (u != 0) {
-+              if (i == HIFN_D_SRC_RSIZE)
-+                      i = 0;
-+              HIFN_SRCR_SYNC(sc, i,
-+                  BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-+              if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
-+                      HIFN_SRCR_SYNC(sc, i,
-+                          BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+                      break;
-+              }
-+              i++, u--;
-+      }
-+      dma->srck = i; dma->srcu = u;
-+
-+      i = dma->cmdk; u = dma->cmdu;
-+      while (u != 0) {
-+              HIFN_CMDR_SYNC(sc, i,
-+                  BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-+              if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
-+                      HIFN_CMDR_SYNC(sc, i,
-+                          BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+                      break;
-+              }
-+              if (i != HIFN_D_CMD_RSIZE) {
-+                      u--;
-+                      HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
-+              }
-+              if (++i == (HIFN_D_CMD_RSIZE + 1))
-+                      i = 0;
-+      }
-+      dma->cmdk = i; dma->cmdu = u;
-+
-+      HIFN_UNLOCK(sc);
-+
-+      if (sc->sc_needwakeup) {                /* XXX check high watermark */
-+              int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
-+#ifdef HIFN_DEBUG
-+              if (hifn_debug)
-+                      device_printf(sc->sc_dev,
-+                              "wakeup crypto (%x) u %d/%d/%d/%d\n",
-+                              sc->sc_needwakeup,
-+                              dma->cmdu, dma->srcu, dma->dstu, dma->resu);
-+#endif
-+              sc->sc_needwakeup &= ~wakeup;
-+              crypto_unblock(sc->sc_cid, wakeup);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
-+/*
-+ * 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.
-+ */
-+static int
-+hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
-+{
-+      struct hifn_softc *sc = device_get_softc(dev);
-+      struct cryptoini *c;
-+      int mac = 0, cry = 0, sesn;
-+      struct hifn_session *ses = NULL;
-+      unsigned long l_flags;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      KASSERT(sc != NULL, ("hifn_newsession: null softc"));
-+      if (sidp == NULL || cri == NULL || sc == NULL) {
-+              DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
-+              return (EINVAL);
-+      }
-+
-+      HIFN_LOCK(sc);
-+      if (sc->sc_sessions == NULL) {
-+              ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
-+                              SLAB_ATOMIC);
-+              if (ses == NULL) {
-+                      HIFN_UNLOCK(sc);
-+                      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),
-+                                      SLAB_ATOMIC);
-+                      if (ses == NULL) {
-+                              HIFN_UNLOCK(sc);
-+                              return (ENOMEM);
-+                      }
-+                      bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
-+                      bzero(sc->sc_sessions, sesn * sizeof(*ses));
-+                      kfree(sc->sc_sessions);
-+                      sc->sc_sessions = ses;
-+                      ses = &sc->sc_sessions[sesn];
-+                      sc->sc_nsessions++;
-+              }
-+      }
-+      HIFN_UNLOCK(sc);
-+
-+      bzero(ses, sizeof(*ses));
-+      ses->hs_used = 1;
-+
-+      for (c = cri; c != NULL; c = c->cri_next) {
-+              switch (c->cri_alg) {
-+              case CRYPTO_MD5:
-+              case CRYPTO_SHA1:
-+              case CRYPTO_MD5_HMAC:
-+              case CRYPTO_SHA1_HMAC:
-+                      if (mac) {
-+                              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                              return (EINVAL);
-+                      }
-+                      mac = 1;
-+                      ses->hs_mlen = c->cri_mlen;
-+                      if (ses->hs_mlen == 0) {
-+                              switch (c->cri_alg) {
-+                              case CRYPTO_MD5:
-+                              case CRYPTO_MD5_HMAC:
-+                                      ses->hs_mlen = 16;
-+                                      break;
-+                              case CRYPTO_SHA1:
-+                              case CRYPTO_SHA1_HMAC:
-+                                      ses->hs_mlen = 20;
-+                                      break;
-+                              }
-+                      }
-+                      break;
-+              case CRYPTO_DES_CBC:
-+              case CRYPTO_3DES_CBC:
-+              case CRYPTO_AES_CBC:
-+                      /* XXX this may read fewer, does it matter? */
-+                      read_random(ses->hs_iv,
-+                              c->cri_alg == CRYPTO_AES_CBC ?
-+                                      HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
-+                      /*FALLTHROUGH*/
-+              case CRYPTO_ARC4:
-+                      if (cry) {
-+                              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                              return (EINVAL);
-+                      }
-+                      cry = 1;
-+                      break;
-+              default:
-+                      DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                      return (EINVAL);
-+              }
-+      }
-+      if (mac == 0 && cry == 0) {
-+              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+              return (EINVAL);
-+      }
-+
-+      *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
-+
-+      return (0);
-+}
-+
-+/*
-+ * Deallocate a session.
-+ * XXX this routine should run a zero'd mac/encrypt key into context ram.
-+ * XXX to blow away any keys already stored there.
-+ */
-+static int
-+hifn_freesession(device_t dev, u_int64_t tid)
-+{
-+      struct hifn_softc *sc = device_get_softc(dev);
-+      int session, error;
-+      u_int32_t sid = CRYPTO_SESID2LID(tid);
-+      unsigned long l_flags;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      KASSERT(sc != NULL, ("hifn_freesession: null softc"));
-+      if (sc == NULL) {
-+              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+              return (EINVAL);
-+      }
-+
-+      HIFN_LOCK(sc);
-+      session = HIFN_SESSION(sid);
-+      if (session < sc->sc_nsessions) {
-+              bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
-+              error = 0;
-+      } else {
-+              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+              error = EINVAL;
-+      }
-+      HIFN_UNLOCK(sc);
-+
-+      return (error);
-+}
-+
-+static int
-+hifn_process(device_t dev, struct cryptop *crp, int hint)
-+{
-+      struct hifn_softc *sc = device_get_softc(dev);
-+      struct hifn_command *cmd = NULL;
-+      int session, err, ivlen;
-+      struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      if (crp == NULL || crp->crp_callback == NULL) {
-+              hifnstats.hst_invalid++;
-+              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+              return (EINVAL);
-+      }
-+      session = HIFN_SESSION(crp->crp_sid);
-+
-+      if (sc == NULL || session >= sc->sc_nsessions) {
-+              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+              err = EINVAL;
-+              goto errout;
-+      }
-+
-+      cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
-+      if (cmd == NULL) {
-+              hifnstats.hst_nomem++;
-+              err = ENOMEM;
-+              goto errout;
-+      }
-+      memset(cmd, 0, sizeof(*cmd));
-+
-+      if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+              cmd->src_skb = (struct sk_buff *)crp->crp_buf;
-+              cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
-+      } else if (crp->crp_flags & CRYPTO_F_IOV) {
-+              cmd->src_io = (struct uio *)crp->crp_buf;
-+              cmd->dst_io = (struct uio *)crp->crp_buf;
-+      } else {
-+              cmd->src_buf = crp->crp_buf;
-+              cmd->dst_buf = crp->crp_buf;
-+      }
-+
-+      crd1 = crp->crp_desc;
-+      if (crd1 == NULL) {
-+              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+              err = EINVAL;
-+              goto errout;
-+      }
-+      crd2 = crd1->crd_next;
-+
-+      if (crd2 == NULL) {
-+              if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
-+                  crd1->crd_alg == CRYPTO_SHA1_HMAC ||
-+                  crd1->crd_alg == CRYPTO_SHA1 ||
-+                  crd1->crd_alg == CRYPTO_MD5) {
-+                      maccrd = crd1;
-+                      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;
-+                      maccrd = NULL;
-+                      enccrd = crd1;
-+              } else {
-+                      DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+      } else {
-+              if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
-+                     crd1->crd_alg == CRYPTO_SHA1_HMAC ||
-+                     crd1->crd_alg == CRYPTO_MD5 ||
-+                     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;
-+                      maccrd = crd1;
-+                      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_AES_CBC) &&
-+                  (crd2->crd_alg == CRYPTO_MD5_HMAC ||
-+                     crd2->crd_alg == CRYPTO_SHA1_HMAC ||
-+                     crd2->crd_alg == CRYPTO_MD5 ||
-+                     crd2->crd_alg == CRYPTO_SHA1) &&
-+                  (crd1->crd_flags & CRD_F_ENCRYPT)) {
-+                      enccrd = crd1;
-+                      maccrd = crd2;
-+              } else {
-+                      /*
-+                       * We cannot order the 7751 as requested
-+                       */
-+                      DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+      }
-+
-+      if (enccrd) {
-+              cmd->enccrd = enccrd;
-+              cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
-+              switch (enccrd->crd_alg) {
-+              case CRYPTO_ARC4:
-+                      cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
-+                      break;
-+              case CRYPTO_DES_CBC:
-+                      cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
-+                          HIFN_CRYPT_CMD_MODE_CBC |
-+                          HIFN_CRYPT_CMD_NEW_IV;
-+                      break;
-+              case CRYPTO_3DES_CBC:
-+                      cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
-+                          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:
-+                      DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                      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, ivlen);
-+                              else
-+                                      bcopy(sc->sc_sessions[session].hs_iv,
-+                                          cmd->iv, ivlen);
-+
-+                              if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
-+                                  == 0) {
-+                                      crypto_copyback(crp->crp_flags,
-+                                          crp->crp_buf, enccrd->crd_inject,
-+                                          ivlen, cmd->iv);
-+                              }
-+                      } else {
-+                              if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
-+                                      bcopy(enccrd->crd_iv, cmd->iv, ivlen);
-+                              else {
-+                                      crypto_copydata(crp->crp_flags,
-+                                          crp->crp_buf, 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;
-+
-+              /* 
-+               * 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:
-+                              DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
-+                              err = EINVAL;
-+                              goto errout;
-+                      }
-+              }
-+      }
-+
-+      if (maccrd) {
-+              cmd->maccrd = maccrd;
-+              cmd->base_masks |= HIFN_BASE_CMD_MAC;
-+
-+              switch (maccrd->crd_alg) {
-+              case CRYPTO_MD5:
-+                      cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
-+                          HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
-+                          HIFN_MAC_CMD_POS_IPSEC;
-+                       break;
-+              case CRYPTO_MD5_HMAC:
-+                      cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
-+                          HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
-+                          HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
-+                      break;
-+              case CRYPTO_SHA1:
-+                      cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
-+                          HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
-+                          HIFN_MAC_CMD_POS_IPSEC;
-+                      break;
-+              case CRYPTO_SHA1_HMAC:
-+                      cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
-+                          HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
-+                          HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
-+                      break;
-+              }
-+
-+              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),
-+                          HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
-+              }
-+      }
-+
-+      cmd->crp = crp;
-+      cmd->session_num = session;
-+      cmd->softc = sc;
-+
-+      err = hifn_crypto(sc, cmd, crp, hint);
-+      if (!err) {
-+              return 0;
-+      } else if (err == ERESTART) {
-+              /*
-+               * There weren't enough resources to dispatch the request
-+               * to the part.  Notify the caller so they'll requeue this
-+               * request and resubmit it again soon.
-+               */
-+#ifdef HIFN_DEBUG
-+              if (hifn_debug)
-+                      device_printf(sc->sc_dev, "requeue request\n");
-+#endif
-+              kfree(cmd);
-+              sc->sc_needwakeup |= CRYPTO_SYMQ;
-+              return (err);
-+      }
-+
-+errout:
-+      if (cmd != NULL)
-+              kfree(cmd);
-+      if (err == EINVAL)
-+              hifnstats.hst_invalid++;
-+      else
-+              hifnstats.hst_nomem++;
-+      crp->crp_etype = err;
-+      crypto_done(crp);
-+      return (err);
-+}
-+
-+static void
-+hifn_abort(struct hifn_softc *sc)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      struct hifn_command *cmd;
-+      struct cryptop *crp;
-+      int i, u;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      i = dma->resk; u = dma->resu;
-+      while (u != 0) {
-+              cmd = dma->hifn_commands[i];
-+              KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
-+              dma->hifn_commands[i] = NULL;
-+              crp = cmd->crp;
-+
-+              if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
-+                      /* Salvage what we can. */
-+                      u_int8_t *macbuf;
-+
-+                      if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
-+                              macbuf = dma->result_bufs[i];
-+                              macbuf += 12;
-+                      } else
-+                              macbuf = NULL;
-+                      hifnstats.hst_opackets++;
-+                      hifn_callback(sc, cmd, macbuf);
-+              } else {
-+#if 0
-+                      if (cmd->src_map == cmd->dst_map) {
-+                              bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
-+                                  BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-+                      } else {
-+                              bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
-+                                  BUS_DMASYNC_POSTWRITE);
-+                              bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
-+                                  BUS_DMASYNC_POSTREAD);
-+                      }
-+#endif
-+
-+                      if (cmd->src_skb != cmd->dst_skb) {
-+#ifdef NOTYET
-+                              m_freem(cmd->src_m);
-+                              crp->crp_buf = (caddr_t)cmd->dst_m;
-+#else
-+                              device_printf(sc->sc_dev,
-+                                              "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
-+                                              __FILE__, __LINE__);
-+#endif
-+                      }
-+
-+                      /* non-shared buffers cannot be restarted */
-+                      if (cmd->src_map != cmd->dst_map) {
-+                              /*
-+                               * XXX should be EAGAIN, delayed until
-+                               * after the reset.
-+                               */
-+                              crp->crp_etype = ENOMEM;
-+                              pci_unmap_buf(sc, &cmd->dst);
-+                      } else
-+                              crp->crp_etype = ENOMEM;
-+
-+                      pci_unmap_buf(sc, &cmd->src);
-+
-+                      kfree(cmd);
-+                      if (crp->crp_etype != EAGAIN)
-+                              crypto_done(crp);
-+              }
-+
-+              if (++i == HIFN_D_RES_RSIZE)
-+                      i = 0;
-+              u--;
-+      }
-+      dma->resk = i; dma->resu = u;
-+
-+      hifn_reset_board(sc, 1);
-+      hifn_init_dma(sc);
-+      hifn_init_pci_registers(sc);
-+}
-+
-+static void
-+hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
-+{
-+      struct hifn_dma *dma = sc->sc_dma;
-+      struct cryptop *crp = cmd->crp;
-+      struct cryptodesc *crd;
-+      int i, u, ivlen;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+#if 0
-+      if (cmd->src_map == cmd->dst_map) {
-+              bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
-+                  BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-+      } else {
-+              bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
-+                  BUS_DMASYNC_POSTWRITE);
-+              bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
-+                  BUS_DMASYNC_POSTREAD);
-+      }
-+#endif
-+
-+      if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+              if (cmd->src_skb != cmd->dst_skb) {
-+#ifdef NOTYET
-+                      crp->crp_buf = (caddr_t)cmd->dst_m;
-+                      totlen = cmd->src_mapsize;
-+                      for (m = cmd->dst_m; m != NULL; m = m->m_next) {
-+                              if (totlen < m->m_len) {
-+                                      m->m_len = totlen;
-+                                      totlen = 0;
-+                              } else
-+                                      totlen -= m->m_len;
-+                      }
-+                      cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
-+                      m_freem(cmd->src_m);
-+#else
-+                      device_printf(sc->sc_dev,
-+                                      "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
-+                                      __FILE__, __LINE__);
-+#endif
-+              }
-+      }
-+
-+      if (cmd->sloplen != 0) {
-+              crypto_copyback(crp->crp_flags, crp->crp_buf,
-+                  cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
-+                  (caddr_t)&dma->slop[cmd->slopidx]);
-+      }
-+
-+      i = dma->dstk; u = dma->dstu;
-+      while (u != 0) {
-+              if (i == HIFN_D_DST_RSIZE)
-+                      i = 0;
-+#if 0
-+              bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
-+                  BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-+#endif
-+              if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
-+#if 0
-+                      bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
-+                          BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-+#endif
-+                      break;
-+              }
-+              i++, u--;
-+      }
-+      dma->dstk = i; dma->dstu = u;
-+
-+      hifnstats.hst_obytes += cmd->dst_mapsize;
-+
-+      if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
-+          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_AES_CBC)
-+                              continue;
-+                      ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
-+                              HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
-+                      crypto_copydata(crp->crp_flags, crp->crp_buf,
-+                          crd->crd_skip + crd->crd_len - ivlen, ivlen,
-+                          cmd->softc->sc_sessions[cmd->session_num].hs_iv);
-+                      break;
-+              }
-+      }
-+
-+      if (macbuf != NULL) {
-+              for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
-+                        int len;
-+
-+                      if (crd->crd_alg != CRYPTO_MD5 &&
-+                          crd->crd_alg != CRYPTO_SHA1 &&
-+                          crd->crd_alg != CRYPTO_MD5_HMAC &&
-+                          crd->crd_alg != CRYPTO_SHA1_HMAC) {
-+                              continue;
-+                      }
-+                      len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
-+                      crypto_copyback(crp->crp_flags, crp->crp_buf,
-+                          crd->crd_inject, len, macbuf);
-+                      break;
-+              }
-+      }
-+
-+      if (cmd->src_map != cmd->dst_map)
-+              pci_unmap_buf(sc, &cmd->dst);
-+      pci_unmap_buf(sc, &cmd->src);
-+      kfree(cmd);
-+      crypto_done(crp);
-+}
-+
-+/*
-+ * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
-+ * and Group 1 registers; avoid conditions that could create
-+ * burst writes by doing a read in between the writes.
-+ *
-+ * NB: The read we interpose is always to the same register;
-+ *     we do this because reading from an arbitrary (e.g. last)
-+ *     register may not always work.
-+ */
-+static void
-+hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
-+{
-+      if (sc->sc_flags & HIFN_IS_7811) {
-+              if (sc->sc_bar0_lastreg == reg - 4)
-+                      readl(sc->sc_bar0 + HIFN_0_PUCNFG);
-+              sc->sc_bar0_lastreg = reg;
-+      }
-+      writel(val, sc->sc_bar0 + reg);
-+}
-+
-+static void
-+hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
-+{
-+      if (sc->sc_flags & HIFN_IS_7811) {
-+              if (sc->sc_bar1_lastreg == reg - 4)
-+                      readl(sc->sc_bar1 + HIFN_1_REVID);
-+              sc->sc_bar1_lastreg = reg;
-+      }
-+      writel(val, sc->sc_bar1 + reg);
-+}
-+
-+
-+static struct pci_device_id hifn_pci_tbl[] = {
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      /*
-+       * Other vendors share this PCI ID as well, such as
-+       * http://www.powercrypt.com, and obviously they also
-+       * use the same key.
-+       */
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { 0, 0, 0, 0, 0, 0, }
-+};
-+MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
-+
-+static struct pci_driver hifn_driver = {
-+      .name         = "hifn",
-+      .id_table     = hifn_pci_tbl,
-+      .probe        = hifn_probe,
-+      .remove       = hifn_remove,
-+      /* add PM stuff here one day */
-+};
-+
-+static int __init hifn_init (void)
-+{
-+      struct hifn_softc *sc = NULL;
-+      int rc;
-+
-+      DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
-+
-+      rc = pci_register_driver(&hifn_driver);
-+      pci_register_driver_compat(&hifn_driver, rc);
-+
-+      return rc;
-+}
-+
-+static void __exit hifn_exit (void)
-+{
-+      pci_unregister_driver(&hifn_driver);
-+}
-+
-+module_init(hifn_init);
-+module_exit(hifn_exit);
-+
-+MODULE_LICENSE("BSD");
-+MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
-+MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
---- /dev/null
-+++ b/crypto/ocf/hifn/hifnHIPP.c
-@@ -0,0 +1,420 @@
-+/*-
-+ * Driver for Hifn HIPP-I/II chipset
-+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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.
-+ *
-+ * Effort sponsored by Hifn Inc.
-+ *
-+ */
-+
-+/*
-+ * Driver for various Hifn encryption processors.
-+ */
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+#include <linux/wait.h>
-+#include <linux/sched.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+#include <linux/random.h>
-+#include <linux/version.h>
-+#include <linux/skbuff.h>
-+#include <linux/uio.h>
-+#include <linux/sysfs.h>
-+#include <linux/miscdevice.h>
-+#include <asm/io.h>
-+
-+#include <cryptodev.h>
-+
-+#include "hifnHIPPreg.h"
-+#include "hifnHIPPvar.h"
-+
-+#if 1
-+#define       DPRINTF(a...)   if (hipp_debug) { \
-+                                                      printk("%s: ", sc ? \
-+                                                              device_get_nameunit(sc->sc_dev) : "hifn"); \
-+                                                      printk(a); \
-+                                              } else
-+#else
-+#define       DPRINTF(a...)
-+#endif
-+
-+typedef int bus_size_t;
-+
-+static inline int
-+pci_get_revid(struct pci_dev *dev)
-+{
-+      u8 rid = 0;
-+      pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
-+      return rid;
-+}
-+
-+#define debug hipp_debug
-+int hipp_debug = 0;
-+module_param(hipp_debug, int, 0644);
-+MODULE_PARM_DESC(hipp_debug, "Enable debug");
-+
-+int hipp_maxbatch = 1;
-+module_param(hipp_maxbatch, int, 0644);
-+MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
-+
-+static        int  hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
-+static        void hipp_remove(struct pci_dev *dev);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-+static irqreturn_t hipp_intr(int irq, void *arg);
-+#else
-+static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
-+#endif
-+
-+static int hipp_num_chips = 0;
-+static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
-+
-+static        int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
-+static        int hipp_freesession(device_t, u_int64_t);
-+static        int hipp_process(device_t, struct cryptop *, int);
-+
-+static device_method_t hipp_methods = {
-+      /* crypto device methods */
-+      DEVMETHOD(cryptodev_newsession, hipp_newsession),
-+      DEVMETHOD(cryptodev_freesession,hipp_freesession),
-+      DEVMETHOD(cryptodev_process,    hipp_process),
-+};
-+
-+static __inline u_int32_t
-+READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
-+{
-+      u_int32_t v = readl(sc->sc_bar[barno] + reg);
-+      //sc->sc_bar0_lastreg = (bus_size_t) -1;
-+      return (v);
-+}
-+static __inline void
-+WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
-+{
-+      writel(val, sc->sc_bar[barno] + reg);
-+}
-+
-+#define READ_REG_0(sc, reg)         READ_REG(sc, 0, reg)
-+#define WRITE_REG_0(sc, reg, val)   WRITE_REG(sc,0, reg, val)
-+#define READ_REG_1(sc, reg)         READ_REG(sc, 1, reg)
-+#define WRITE_REG_1(sc, reg, val)   WRITE_REG(sc,1, reg, val)
-+
-+static int
-+hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
-+{
-+      return EINVAL;
-+}
-+
-+static int
-+hipp_freesession(device_t dev, u_int64_t tid)
-+{
-+      return EINVAL;
-+}
-+
-+static int
-+hipp_process(device_t dev, struct cryptop *crp, int hint)
-+{
-+      return EINVAL;
-+}
-+
-+static const char*
-+hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
-+{
-+      char *n = NULL;
-+
-+      switch (pci_get_vendor(sc->sc_pcidev)) {
-+      case PCI_VENDOR_HIFN:
-+              switch (pci_get_device(sc->sc_pcidev)) {
-+              case PCI_PRODUCT_HIFN_7855:     n = "Hifn 7855";
-+              case PCI_PRODUCT_HIFN_8155:     n = "Hifn 8155";
-+              case PCI_PRODUCT_HIFN_6500:     n = "Hifn 6500";
-+              }
-+      }
-+
-+      if(n==NULL) {
-+              snprintf(buf, blen, "VID=%02x,PID=%02x",
-+                       pci_get_vendor(sc->sc_pcidev),
-+                       pci_get_device(sc->sc_pcidev));
-+      } else {
-+              buf[0]='\0';
-+              strncat(buf, n, blen);
-+      }
-+      return buf;
-+}
-+
-+struct hipp_fs_entry {
-+      struct attribute attr;
-+      /* other stuff */
-+};
-+
-+
-+static ssize_t
-+cryptoid_show(struct device *dev,
-+            struct device_attribute *attr,
-+            char *buf)                                                
-+{                                                             
-+      struct hipp_softc *sc;                                  
-+
-+      sc = pci_get_drvdata(to_pci_dev (dev));
-+      return sprintf (buf, "%d\n", sc->sc_cid);
-+}
-+
-+struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
-+
-+/*
-+ * Attach an interface that successfully probed.
-+ */
-+static int
-+hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
-+{
-+      struct hipp_softc *sc = NULL;
-+      int i;
-+      //char rbase;
-+      //u_int16_t ena;
-+      int rev;
-+      //int rseg;
-+      int rc;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      if (pci_enable_device(dev) < 0)
-+              return(-ENODEV);
-+
-+      if (pci_set_mwi(dev))
-+              return(-ENODEV);
-+
-+      if (!dev->irq) {
-+              printk("hifn: found device with no IRQ assigned. check BIOS settings!");
-+              pci_disable_device(dev);
-+              return(-ENODEV);
-+      }
-+
-+      sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
-+      if (!sc)
-+              return(-ENOMEM);
-+      memset(sc, 0, sizeof(*sc));
-+
-+      softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
-+
-+      sc->sc_pcidev = dev;
-+      sc->sc_irq = -1;
-+      sc->sc_cid = -1;
-+      sc->sc_num = hipp_num_chips++;
-+
-+      if (sc->sc_num < HIPP_MAX_CHIPS)
-+              hipp_chip_idx[sc->sc_num] = sc;
-+
-+      pci_set_drvdata(sc->sc_pcidev, sc);
-+
-+      spin_lock_init(&sc->sc_mtx);
-+
-+      /*
-+       * Setup PCI resources.
-+       * The READ_REG_0, WRITE_REG_0, READ_REG_1,
-+       * and WRITE_REG_1 macros throughout the driver are used
-+       * to permit better debugging.
-+       */
-+      for(i=0; i<4; i++) {
-+              unsigned long mem_start, mem_len;
-+              mem_start = pci_resource_start(sc->sc_pcidev, i);
-+              mem_len   = pci_resource_len(sc->sc_pcidev, i);
-+              sc->sc_barphy[i] = (caddr_t)mem_start;
-+              sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
-+              if (!sc->sc_bar[i]) {
-+                      device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
-+                      goto fail;
-+              }
-+      }
-+
-+      //hipp_reset_board(sc, 0);
-+      pci_set_master(sc->sc_pcidev);
-+
-+      /*
-+       * Arrange the interrupt line.
-+       */
-+      rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
-+      if (rc) {
-+              device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
-+              goto fail;
-+      }
-+      sc->sc_irq = dev->irq;
-+
-+      rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
-+
-+      {
-+              char b[32];
-+              device_printf(sc->sc_dev, "%s, rev %u",
-+                            hipp_partname(sc, b, sizeof(b)), rev);
-+      }
-+
-+#if 0
-+      if (sc->sc_flags & HIFN_IS_7956)
-+              printf(", 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));
-+#endif
-+      printf("\n");
-+
-+      sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
-+      if (sc->sc_cid < 0) {
-+              device_printf(sc->sc_dev, "could not get crypto driver id\n");
-+              goto fail;
-+      }
-+
-+#if 0 /* cannot work with a non-GPL module */
-+      /* make a sysfs entry to let the world know what entry we got */
-+      sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
-+#endif
-+
-+#if 0
-+      init_timer(&sc->sc_tickto);
-+      sc->sc_tickto.function = hifn_tick;
-+      sc->sc_tickto.data = (unsigned long) sc->sc_num;
-+      mod_timer(&sc->sc_tickto, jiffies + HZ);
-+#endif
-+
-+#if 0 /* no code here yet ?? */
-+      crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
-+#endif
-+
-+      return (0);
-+
-+fail:
-+      if (sc->sc_cid >= 0)
-+              crypto_unregister_all(sc->sc_cid);
-+      if (sc->sc_irq != -1)
-+              free_irq(sc->sc_irq, sc);
-+      
-+#if 0
-+      if (sc->sc_dma) {
-+              /* Turn off DMA polling */
-+              WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
-+                          HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+              
-+              pci_free_consistent(sc->sc_pcidev,
-+                                  sizeof(*sc->sc_dma),
-+                                  sc->sc_dma, sc->sc_dma_physaddr);
-+      }
-+#endif
-+      kfree(sc);
-+      return (-ENXIO);
-+}
-+
-+/*
-+ * Detach an interface that successfully probed.
-+ */
-+static void
-+hipp_remove(struct pci_dev *dev)
-+{
-+      struct hipp_softc *sc = pci_get_drvdata(dev);
-+      unsigned long l_flags;
-+
-+      DPRINTF("%s()\n", __FUNCTION__);
-+
-+      /* disable interrupts */
-+      HIPP_LOCK(sc);
-+
-+#if 0
-+      WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
-+      HIFN_UNLOCK(sc);
-+
-+      /*XXX other resources */
-+      del_timer_sync(&sc->sc_tickto);
-+
-+      /* Turn off DMA polling */
-+      WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
-+          HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
-+#endif
-+
-+      crypto_unregister_all(sc->sc_cid);
-+
-+      free_irq(sc->sc_irq, sc);
-+
-+#if 0
-+      pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
-+                sc->sc_dma, sc->sc_dma_physaddr);
-+#endif
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-+static irqreturn_t hipp_intr(int irq, void *arg)
-+#else
-+static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
-+#endif
-+{
-+      struct hipp_softc *sc = arg;
-+
-+      sc = sc; /* shut up compiler */
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static struct pci_device_id hipp_pci_tbl[] = {
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+};
-+MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
-+
-+static struct pci_driver hipp_driver = {
-+      .name         = "hipp",
-+      .id_table     = hipp_pci_tbl,
-+      .probe        = hipp_probe,
-+      .remove       = hipp_remove,
-+      /* add PM stuff here one day */
-+};
-+
-+static int __init hipp_init (void)
-+{
-+      struct hipp_softc *sc = NULL;
-+      int rc;
-+
-+      DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
-+
-+      rc = pci_register_driver(&hipp_driver);
-+      pci_register_driver_compat(&hipp_driver, rc);
-+
-+      return rc;
-+}
-+
-+static void __exit hipp_exit (void)
-+{
-+      pci_unregister_driver(&hipp_driver);
-+}
-+
-+module_init(hipp_init);
-+module_exit(hipp_exit);
-+
-+MODULE_LICENSE("BSD");
-+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
-+MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
---- /dev/null
-+++ b/crypto/ocf/hifn/hifnHIPPreg.h
-@@ -0,0 +1,46 @@
-+/*-
-+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.
-+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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.
-+ *
-+ * Effort sponsored by Hifn inc.
-+ *
-+ */
-+
-+#ifndef __HIFNHIPP_H__
-+#define       __HIFNHIPP_H__
-+
-+/*
-+ * PCI vendor and device identifiers
-+ */
-+#define       PCI_VENDOR_HIFN         0x13a3          /* Hifn */
-+#define       PCI_PRODUCT_HIFN_6500   0x0006          /* 6500 */
-+#define       PCI_PRODUCT_HIFN_7855   0x001f          /* 7855 */
-+#define       PCI_PRODUCT_HIFN_8155   0x999           /* XXX 8155 */
-+
-+#define HIPP_1_REVID            0x01 /* BOGUS */
-+
-+#endif /* __HIPP_H__ */
---- /dev/null
-+++ b/crypto/ocf/hifn/hifnHIPPvar.h
-@@ -0,0 +1,93 @@
-+/*
-+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.
-+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> * 
-+ *
-+ * 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.
-+ *
-+ * Effort sponsored by Hifn inc.
-+ *
-+ */
-+
-+#ifndef __HIFNHIPPVAR_H__
-+#define __HIFNHIPPVAR_H__
-+
-+#define HIPP_MAX_CHIPS 8
-+
-+/*
-+ * Holds data specific to a single Hifn HIPP-I board.
-+ */
-+struct hipp_softc {
-+      softc_device_decl                sc_dev;
-+
-+      struct pci_dev          *sc_pcidev;     /* device backpointer */
-+      ocf_iomem_t             sc_bar[5];
-+      caddr_t                 sc_barphy[5];   /* physical address */
-+      int                     sc_num;         /* for multiple devs */
-+      spinlock_t              sc_mtx;         /* per-instance lock */
-+      int32_t                 sc_cid;
-+      int                     sc_irq;
-+
-+#if 0
-+
-+      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;
-+      dma_addr_t              sc_dma_physaddr;/* physical address of sc_dma */
-+
-+      int                     sc_dmansegs;
-+      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_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 timer_list       sc_tickto;      /* for managing DMA */
-+
-+      int                     sc_rngfirst;
-+      int                     sc_rnghz;       /* RNG polling frequency */
-+
-+      int                     sc_c_busy;      /* command ring busy */
-+      int                     sc_s_busy;      /* source data ring busy */
-+      int                     sc_d_busy;      /* destination data ring busy */
-+      int                     sc_r_busy;      /* result ring busy */
-+      int                     sc_active;      /* for initial countdown */
-+      int                     sc_needwakeup;  /* ops q'd wating on resources */
-+      int                     sc_curbatch;    /* # ops submitted w/o int */
-+      int                     sc_suspended;
-+      struct miscdevice       sc_miscdev;
-+#endif
-+};
-+
-+#define       HIPP_LOCK(_sc)          spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
-+#define       HIPP_UNLOCK(_sc)        spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
-+
-+#endif /* __HIFNHIPPVAR_H__ */
---- /dev/null
-+++ b/crypto/ocf/safe/md5.c
-@@ -0,0 +1,308 @@
-+/*    $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $     */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
-+ * 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. Neither the name of the project nor the names of its contributors
-+ *    may be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
-+ */
-+
-+#if 0
-+#include <sys/cdefs.h>
-+__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
-+
-+#include <sys/types.h>
-+#include <sys/cdefs.h>
-+#include <sys/time.h>
-+#include <sys/systm.h>
-+#include <crypto/md5.h>
-+#endif
-+
-+#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
-+
-+#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
-+#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
-+#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
-+#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
-+
-+#define ROUND1(a, b, c, d, k, s, i) { \
-+      (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
-+      (a) = SHIFT((a), (s)); \
-+      (a) = (b) + (a); \
-+}
-+
-+#define ROUND2(a, b, c, d, k, s, i) { \
-+      (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
-+      (a) = SHIFT((a), (s)); \
-+      (a) = (b) + (a); \
-+}
-+
-+#define ROUND3(a, b, c, d, k, s, i) { \
-+      (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
-+      (a) = SHIFT((a), (s)); \
-+      (a) = (b) + (a); \
-+}
-+
-+#define ROUND4(a, b, c, d, k, s, i) { \
-+      (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
-+      (a) = SHIFT((a), (s)); \
-+      (a) = (b) + (a); \
-+}
-+
-+#define Sa     7
-+#define Sb    12
-+#define Sc    17
-+#define Sd    22
-+
-+#define Se     5
-+#define Sf     9
-+#define Sg    14
-+#define Sh    20
-+
-+#define Si     4
-+#define Sj    11
-+#define Sk    16
-+#define Sl    23
-+
-+#define Sm     6
-+#define Sn    10
-+#define So    15
-+#define Sp    21
-+
-+#define MD5_A0        0x67452301
-+#define MD5_B0        0xefcdab89
-+#define MD5_C0        0x98badcfe
-+#define MD5_D0        0x10325476
-+
-+/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
-+static const u_int32_t T[65] = {
-+      0,
-+      0xd76aa478,     0xe8c7b756,     0x242070db,     0xc1bdceee,
-+      0xf57c0faf,     0x4787c62a,     0xa8304613,     0xfd469501,
-+      0x698098d8,     0x8b44f7af,     0xffff5bb1,     0x895cd7be,
-+      0x6b901122,     0xfd987193,     0xa679438e,     0x49b40821,
-+
-+      0xf61e2562,     0xc040b340,     0x265e5a51,     0xe9b6c7aa,
-+      0xd62f105d,     0x2441453,      0xd8a1e681,     0xe7d3fbc8,
-+      0x21e1cde6,     0xc33707d6,     0xf4d50d87,     0x455a14ed,
-+      0xa9e3e905,     0xfcefa3f8,     0x676f02d9,     0x8d2a4c8a,
-+
-+      0xfffa3942,     0x8771f681,     0x6d9d6122,     0xfde5380c,
-+      0xa4beea44,     0x4bdecfa9,     0xf6bb4b60,     0xbebfbc70,
-+      0x289b7ec6,     0xeaa127fa,     0xd4ef3085,     0x4881d05,
-+      0xd9d4d039,     0xe6db99e5,     0x1fa27cf8,     0xc4ac5665,
-+
-+      0xf4292244,     0x432aff97,     0xab9423a7,     0xfc93a039,
-+      0x655b59c3,     0x8f0ccc92,     0xffeff47d,     0x85845dd1,
-+      0x6fa87e4f,     0xfe2ce6e0,     0xa3014314,     0x4e0811a1,
-+      0xf7537e82,     0xbd3af235,     0x2ad7d2bb,     0xeb86d391,
-+};
-+
-+static const u_int8_t md5_paddat[MD5_BUFLEN] = {
-+      0x80,   0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,
-+      0,      0,      0,      0,      0,      0,      0,      0,      
-+};
-+
-+static void md5_calc(u_int8_t *, md5_ctxt *);
-+
-+void md5_init(ctxt)
-+      md5_ctxt *ctxt;
-+{
-+      ctxt->md5_n = 0;
-+      ctxt->md5_i = 0;
-+      ctxt->md5_sta = MD5_A0;
-+      ctxt->md5_stb = MD5_B0;
-+      ctxt->md5_stc = MD5_C0;
-+      ctxt->md5_std = MD5_D0;
-+      bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
-+}
-+
-+void md5_loop(ctxt, input, len)
-+      md5_ctxt *ctxt;
-+      u_int8_t *input;
-+      u_int len; /* number of bytes */
-+{
-+      u_int gap, i;
-+
-+      ctxt->md5_n += len * 8; /* byte to bit */
-+      gap = MD5_BUFLEN - ctxt->md5_i;
-+
-+      if (len >= gap) {
-+              bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
-+                      gap);
-+              md5_calc(ctxt->md5_buf, ctxt);
-+
-+              for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
-+                      md5_calc((u_int8_t *)(input + i), ctxt);
-+              }
-+              
-+              ctxt->md5_i = len - i;
-+              bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
-+      } else {
-+              bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
-+                      len);
-+              ctxt->md5_i += len;
-+      }
-+}
-+
-+void md5_pad(ctxt)
-+      md5_ctxt *ctxt;
-+{
-+      u_int gap;
-+
-+      /* Don't count up padding. Keep md5_n. */       
-+      gap = MD5_BUFLEN - ctxt->md5_i;
-+      if (gap > 8) {
-+              bcopy(md5_paddat,
-+                    (void *)(ctxt->md5_buf + ctxt->md5_i),
-+                    gap - sizeof(ctxt->md5_n));
-+      } else {
-+              /* including gap == 8 */
-+              bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
-+                      gap);
-+              md5_calc(ctxt->md5_buf, ctxt);
-+              bcopy((md5_paddat + gap),
-+                    (void *)ctxt->md5_buf,
-+                    MD5_BUFLEN - sizeof(ctxt->md5_n));
-+      }
-+
-+      /* 8 byte word */       
-+#if BYTE_ORDER == LITTLE_ENDIAN
-+      bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
-+#endif
-+#if BYTE_ORDER == BIG_ENDIAN
-+      ctxt->md5_buf[56] = ctxt->md5_n8[7];
-+      ctxt->md5_buf[57] = ctxt->md5_n8[6];
-+      ctxt->md5_buf[58] = ctxt->md5_n8[5];
-+      ctxt->md5_buf[59] = ctxt->md5_n8[4];
-+      ctxt->md5_buf[60] = ctxt->md5_n8[3];
-+      ctxt->md5_buf[61] = ctxt->md5_n8[2];
-+      ctxt->md5_buf[62] = ctxt->md5_n8[1];
-+      ctxt->md5_buf[63] = ctxt->md5_n8[0];
-+#endif
-+
-+      md5_calc(ctxt->md5_buf, ctxt);
-+}
-+
-+void md5_result(digest, ctxt)
-+      u_int8_t *digest;
-+      md5_ctxt *ctxt;
-+{
-+      /* 4 byte words */
-+#if BYTE_ORDER == LITTLE_ENDIAN
-+      bcopy(&ctxt->md5_st8[0], digest, 16);
-+#endif
-+#if BYTE_ORDER == BIG_ENDIAN
-+      digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
-+      digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
-+      digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
-+      digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
-+      digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
-+      digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
-+      digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
-+      digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
-+#endif
-+}
-+
-+static void md5_calc(b64, ctxt)
-+      u_int8_t *b64;
-+      md5_ctxt *ctxt;
-+{
-+      u_int32_t A = ctxt->md5_sta;
-+      u_int32_t B = ctxt->md5_stb;
-+      u_int32_t C = ctxt->md5_stc;
-+      u_int32_t D = ctxt->md5_std;
-+#if BYTE_ORDER == LITTLE_ENDIAN
-+      u_int32_t *X = (u_int32_t *)b64;
-+#endif        
-+#if BYTE_ORDER == BIG_ENDIAN
-+      /* 4 byte words */
-+      /* what a brute force but fast! */
-+      u_int32_t X[16];
-+      u_int8_t *y = (u_int8_t *)X;
-+      y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
-+      y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
-+      y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
-+      y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
-+      y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
-+      y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
-+      y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
-+      y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
-+      y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
-+      y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
-+      y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
-+      y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
-+      y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
-+      y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
-+      y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
-+      y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
-+#endif
-+
-+      ROUND1(A, B, C, D,  0, Sa,  1); ROUND1(D, A, B, C,  1, Sb,  2);
-+      ROUND1(C, D, A, B,  2, Sc,  3); ROUND1(B, C, D, A,  3, Sd,  4);
-+      ROUND1(A, B, C, D,  4, Sa,  5); ROUND1(D, A, B, C,  5, Sb,  6);
-+      ROUND1(C, D, A, B,  6, Sc,  7); ROUND1(B, C, D, A,  7, Sd,  8);
-+      ROUND1(A, B, C, D,  8, Sa,  9); ROUND1(D, A, B, C,  9, Sb, 10);
-+      ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
-+      ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
-+      ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
-+      
-+      ROUND2(A, B, C, D,  1, Se, 17); ROUND2(D, A, B, C,  6, Sf, 18);
-+      ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A,  0, Sh, 20);
-+      ROUND2(A, B, C, D,  5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
-+      ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A,  4, Sh, 24);
-+      ROUND2(A, B, C, D,  9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
-+      ROUND2(C, D, A, B,  3, Sg, 27); ROUND2(B, C, D, A,  8, Sh, 28);
-+      ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C,  2, Sf, 30);
-+      ROUND2(C, D, A, B,  7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
-+
-+      ROUND3(A, B, C, D,  5, Si, 33); ROUND3(D, A, B, C,  8, Sj, 34);
-+      ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
-+      ROUND3(A, B, C, D,  1, Si, 37); ROUND3(D, A, B, C,  4, Sj, 38);
-+      ROUND3(C, D, A, B,  7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
-+      ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C,  0, Sj, 42);
-+      ROUND3(C, D, A, B,  3, Sk, 43); ROUND3(B, C, D, A,  6, Sl, 44);
-+      ROUND3(A, B, C, D,  9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
-+      ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A,  2, Sl, 48);
-+      
-+      ROUND4(A, B, C, D,  0, Sm, 49); ROUND4(D, A, B, C,  7, Sn, 50); 
-+      ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A,  5, Sp, 52); 
-+      ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C,  3, Sn, 54); 
-+      ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A,  1, Sp, 56); 
-+      ROUND4(A, B, C, D,  8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58); 
-+      ROUND4(C, D, A, B,  6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60); 
-+      ROUND4(A, B, C, D,  4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62); 
-+      ROUND4(C, D, A, B,  2, So, 63); ROUND4(B, C, D, A,  9, Sp, 64);
-+
-+      ctxt->md5_sta += A;
-+      ctxt->md5_stb += B;
-+      ctxt->md5_stc += C;
-+      ctxt->md5_std += D;
-+}
---- /dev/null
-+++ b/crypto/ocf/safe/md5.h
-@@ -0,0 +1,76 @@
-+/*    $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $   */
-+/*    $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $   */
-+
-+/*
-+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
-+ * 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. Neither the name of the project nor the names of its contributors
-+ *    may be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
-+ */
-+
-+#ifndef _NETINET6_MD5_H_
-+#define _NETINET6_MD5_H_
-+
-+#define MD5_BUFLEN    64
-+
-+typedef struct {
-+      union {
-+              u_int32_t       md5_state32[4];
-+              u_int8_t        md5_state8[16];
-+      } md5_st;
-+
-+#define md5_sta               md5_st.md5_state32[0]
-+#define md5_stb               md5_st.md5_state32[1]
-+#define md5_stc               md5_st.md5_state32[2]
-+#define md5_std               md5_st.md5_state32[3]
-+#define md5_st8               md5_st.md5_state8
-+
-+      union {
-+              u_int64_t       md5_count64;
-+              u_int8_t        md5_count8[8];
-+      } md5_count;
-+#define md5_n md5_count.md5_count64
-+#define md5_n8        md5_count.md5_count8
-+
-+      u_int   md5_i;
-+      u_int8_t        md5_buf[MD5_BUFLEN];
-+} md5_ctxt;
-+
-+extern void md5_init(md5_ctxt *);
-+extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
-+extern void md5_pad(md5_ctxt *);
-+extern void md5_result(u_int8_t *, md5_ctxt *);
-+
-+/* compatibility */
-+#define MD5_CTX               md5_ctxt
-+#define MD5Init(x)    md5_init((x))
-+#define MD5Update(x, y, z)    md5_loop((x), (y), (z))
-+#define MD5Final(x, y) \
-+do {                          \
-+      md5_pad((y));           \
-+      md5_result((x), (y));   \
-+} while (0)
-+
-+#endif /* ! _NETINET6_MD5_H_*/
---- /dev/null
-+++ b/crypto/ocf/safe/safe.c
-@@ -0,0 +1,2288 @@
-+/*-
-+ * Linux port done by David McCullough <david_mccullough@securecomputing.com>
-+ * Copyright (C) 2004-2007 David McCullough
-+ * The license and original author are listed below.
-+ *
-+ * Copyright (c) 2003 Sam Leffler, Errno Consulting
-+ * Copyright (c) 2003 Global Technology Associates, Inc.
-+ * 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.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-+ *
-+__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
-+ */
-+
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+#include <linux/wait.h>
-+#include <linux/sched.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+#include <linux/random.h>
-+#include <linux/version.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+
-+/*
-+ * SafeNet SafeXcel-1141 hardware crypto accelerator
-+ */
-+
-+#include <cryptodev.h>
-+#include <uio.h>
-+#include <safe/safereg.h>
-+#include <safe/safevar.h>
-+
-+#if 1
-+#define       DPRINTF(a)      do { \
-+                                              if (debug) { \
-+                                                      printk("%s: ", sc ? \
-+                                                              device_get_nameunit(sc->sc_dev) : "safe"); \
-+                                                      printk a; \
-+                                              } \
-+                                      } while (0)
-+#else
-+#define       DPRINTF(a)
-+#endif
-+
-+/*
-+ * until we find a cleaner way, include the BSD md5/sha1 code
-+ * here
-+ */
-+#define HMAC_HACK 1
-+#ifdef HMAC_HACK
-+#define LITTLE_ENDIAN 1234
-+#define BIG_ENDIAN 4321
-+#ifdef __LITTLE_ENDIAN
-+#define BYTE_ORDER LITTLE_ENDIAN
-+#endif
-+#ifdef __BIG_ENDIAN
-+#define BYTE_ORDER BIG_ENDIAN
-+#endif
-+#include <safe/md5.h>
-+#include <safe/md5.c>
-+#include <safe/sha1.h>
-+#include <safe/sha1.c>
-+
-+u_int8_t hmac_ipad_buffer[64] = {
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
-+};
-+
-+u_int8_t hmac_opad_buffer[64] = {
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
-+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
-+};
-+#endif /* HMAC_HACK */
-+
-+/* add proc entry for this */
-+struct safe_stats safestats;
-+
-+#define debug safe_debug
-+int safe_debug = 0;
-+module_param(safe_debug, int, 0644);
-+MODULE_PARM_DESC(safe_debug, "Enable debug");
-+
-+static        void safe_callback(struct safe_softc *, struct safe_ringentry *);
-+static        void safe_feed(struct safe_softc *, struct safe_ringentry *);
-+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
-+static        void safe_rng_init(struct safe_softc *);
-+int safe_rngbufsize = 8;              /* 32 bytes each read  */
-+module_param(safe_rngbufsize, int, 0644);
-+MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
-+int safe_rngmaxalarm = 8;             /* max alarms before reset */
-+module_param(safe_rngmaxalarm, int, 0644);
-+MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
-+#endif /* SAFE_NO_RNG */
-+
-+static void safe_totalreset(struct safe_softc *sc);
-+static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
-+static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
-+static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
-+static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
-+static int safe_kstart(struct safe_softc *sc);
-+static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
-+static void safe_kfeed(struct safe_softc *sc);
-+static void safe_kpoll(unsigned long arg);
-+static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
-+                                                              u_int32_t len, struct crparam *n);
-+
-+static        int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
-+static        int safe_freesession(device_t, u_int64_t);
-+static        int safe_process(device_t, struct cryptop *, int);
-+
-+static device_method_t safe_methods = {
-+      /* crypto device methods */
-+      DEVMETHOD(cryptodev_newsession, safe_newsession),
-+      DEVMETHOD(cryptodev_freesession,safe_freesession),
-+      DEVMETHOD(cryptodev_process,    safe_process),
-+      DEVMETHOD(cryptodev_kprocess,   safe_kprocess),
-+};
-+
-+#define       READ_REG(sc,r)                  readl((sc)->sc_base_addr + (r))
-+#define WRITE_REG(sc,r,val)           writel((val), (sc)->sc_base_addr + (r))
-+
-+#define SAFE_MAX_CHIPS 8
-+static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
-+
-+/*
-+ * split our buffers up into safe DMAable byte fragments to avoid lockup
-+ * bug in 1141 HW on rev 1.0.
-+ */
-+
-+static int
-+pci_map_linear(
-+      struct safe_softc *sc,
-+      struct safe_operand *buf,
-+      void *addr,
-+      int len)
-+{
-+      dma_addr_t tmp;
-+      int chunk, tlen = len;
-+
-+      tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
-+
-+      buf->mapsize += len;
-+      while (len > 0) {
-+              chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
-+              buf->segs[buf->nsegs].ds_addr = tmp;
-+              buf->segs[buf->nsegs].ds_len  = chunk;
-+              buf->segs[buf->nsegs].ds_tlen = tlen;
-+              buf->nsegs++;
-+              tmp  += chunk;
-+              len  -= chunk;
-+              tlen = 0;
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * map in a given uio buffer (great on some arches :-)
-+ */
-+
-+static int
-+pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
-+{
-+      struct iovec *iov = uio->uio_iov;
-+      int n;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      buf->mapsize = 0;
-+      buf->nsegs = 0;
-+
-+      for (n = 0; n < uio->uio_iovcnt; n++) {
-+              pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
-+              iov++;
-+      }
-+
-+      /* identify this buffer by the first segment */
-+      buf->map = (void *) buf->segs[0].ds_addr;
-+      return(0);
-+}
-+
-+/*
-+ * map in a given sk_buff
-+ */
-+
-+static int
-+pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
-+{
-+      int i;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      buf->mapsize = 0;
-+      buf->nsegs = 0;
-+
-+      pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              pci_map_linear(sc, buf,
-+                              page_address(skb_shinfo(skb)->frags[i].page) +
-+                                                      skb_shinfo(skb)->frags[i].page_offset,
-+                              skb_shinfo(skb)->frags[i].size);
-+      }
-+
-+      /* identify this buffer by the first segment */
-+      buf->map = (void *) buf->segs[0].ds_addr;
-+      return(0);
-+}
-+
-+
-+#if 0 /* not needed at this time */
-+static void
-+pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
-+{
-+      int i;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+      for (i = 0; i < buf->nsegs; i++)
-+              pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
-+                              buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
-+}
-+#endif
-+
-+static void
-+pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
-+{
-+      int i;
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+      for (i = 0; i < buf->nsegs; i++) {
-+              if (buf->segs[i].ds_tlen) {
-+                      DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
-+                      pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
-+                                      buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
-+                      DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
-+              }
-+              buf->segs[i].ds_addr = 0;
-+              buf->segs[i].ds_len = 0;
-+              buf->segs[i].ds_tlen = 0;
-+      }
-+      buf->nsegs = 0;
-+      buf->mapsize = 0;
-+      buf->map = 0;
-+}
-+
-+
-+/*
-+ * SafeXcel Interrupt routine
-+ */
-+static irqreturn_t
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-+safe_intr(int irq, void *arg)
-+#else
-+safe_intr(int irq, void *arg, struct pt_regs *regs)
-+#endif
-+{
-+      struct safe_softc *sc = arg;
-+      int stat;
-+      unsigned long flags;
-+
-+      stat = READ_REG(sc, SAFE_HM_STAT);
-+
-+      DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
-+
-+      if (stat == 0)          /* shared irq, not for us */
-+              return IRQ_NONE;
-+
-+      WRITE_REG(sc, SAFE_HI_CLR, stat);       /* IACK */
-+
-+      if ((stat & SAFE_INT_PE_DDONE)) {
-+              /*
-+               * Descriptor(s) done; scan the ring and
-+               * process completed operations.
-+               */
-+              spin_lock_irqsave(&sc->sc_ringmtx, flags);
-+              while (sc->sc_back != sc->sc_front) {
-+                      struct safe_ringentry *re = sc->sc_back;
-+
-+#ifdef SAFE_DEBUG
-+                      if (debug) {
-+                              safe_dump_ringstate(sc, __func__);
-+                              safe_dump_request(sc, __func__, re);
-+                      }
-+#endif
-+                      /*
-+                       * safe_process marks ring entries that were allocated
-+                       * but not used with a csr of zero.  This insures the
-+                       * ring front pointer never needs to be set backwards
-+                       * in the event that an entry is allocated but not used
-+                       * because of a setup error.
-+                       */
-+                      DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
-+                      if (re->re_desc.d_csr != 0) {
-+                              if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
-+                                      DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
-+                                      break;
-+                              }
-+                              if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
-+                                      DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
-+                                      break;
-+                              }
-+                              sc->sc_nqchip--;
-+                              safe_callback(sc, re);
-+                      }
-+                      if (++(sc->sc_back) == sc->sc_ringtop)
-+                              sc->sc_back = sc->sc_ring;
-+              }
-+              spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
-+      }
-+
-+      /*
-+       * Check to see if we got any DMA Error
-+       */
-+      if (stat & SAFE_INT_PE_ERROR) {
-+              printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
-+                              (int)READ_REG(sc, SAFE_PE_DMASTAT));
-+              safestats.st_dmaerr++;
-+              safe_totalreset(sc);
-+#if 0
-+              safe_feed(sc);
-+#endif
-+      }
-+
-+      if (sc->sc_needwakeup) {                /* XXX check high watermark */
-+              int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
-+              DPRINTF(("%s: wakeup crypto %x\n", __func__,
-+                      sc->sc_needwakeup));
-+              sc->sc_needwakeup &= ~wakeup;
-+              crypto_unblock(sc->sc_cid, wakeup);
-+      }
-+      
-+      return IRQ_HANDLED;
-+}
-+
-+/*
-+ * safe_feed() - post a request to chip
-+ */
-+static void
-+safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
-+{
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+#ifdef SAFE_DEBUG
-+      if (debug) {
-+              safe_dump_ringstate(sc, __func__);
-+              safe_dump_request(sc, __func__, re);
-+      }
-+#endif
-+      sc->sc_nqchip++;
-+      if (sc->sc_nqchip > safestats.st_maxqchip)
-+              safestats.st_maxqchip = sc->sc_nqchip;
-+      /* poke h/w to check descriptor ring, any value can be written */
-+      WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
-+}
-+
-+#define       N(a)    (sizeof(a) / sizeof (a[0]))
-+static void
-+safe_setup_enckey(struct safe_session *ses, caddr_t key)
-+{
-+      int i;
-+
-+      bcopy(key, ses->ses_key, ses->ses_klen / 8);
-+
-+      /* PE is little-endian, insure proper byte order */
-+      for (i = 0; i < N(ses->ses_key); i++)
-+              ses->ses_key[i] = htole32(ses->ses_key[i]);
-+}
-+
-+static void
-+safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
-+{
-+#ifdef HMAC_HACK
-+      MD5_CTX md5ctx;
-+      SHA1_CTX sha1ctx;
-+      int i;
-+
-+
-+      for (i = 0; i < klen; i++)
-+              key[i] ^= HMAC_IPAD_VAL;
-+
-+      if (algo == CRYPTO_MD5_HMAC) {
-+              MD5Init(&md5ctx);
-+              MD5Update(&md5ctx, key, klen);
-+              MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
-+              bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
-+      } else {
-+              SHA1Init(&sha1ctx);
-+              SHA1Update(&sha1ctx, key, klen);
-+              SHA1Update(&sha1ctx, hmac_ipad_buffer,
-+                  SHA1_HMAC_BLOCK_LEN - klen);
-+              bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
-+      }
-+
-+      for (i = 0; i < klen; i++)
-+              key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
-+
-+      if (algo == CRYPTO_MD5_HMAC) {
-+              MD5Init(&md5ctx);
-+              MD5Update(&md5ctx, key, klen);
-+              MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
-+              bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
-+      } else {
-+              SHA1Init(&sha1ctx);
-+              SHA1Update(&sha1ctx, key, klen);
-+              SHA1Update(&sha1ctx, hmac_opad_buffer,
-+                  SHA1_HMAC_BLOCK_LEN - klen);
-+              bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
-+      }
-+
-+      for (i = 0; i < klen; i++)
-+              key[i] ^= HMAC_OPAD_VAL;
-+
-+#if 0
-+      /*
-+       * this code prevents SHA working on a BE host,
-+       * so it is obviously wrong.  I think the byte
-+       * swap setup we do with the chip fixes this for us
-+       */
-+
-+      /* PE is little-endian, insure proper byte order */
-+      for (i = 0; i < N(ses->ses_hminner); i++) {
-+              ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
-+              ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
-+      }
-+#endif
-+#else /* HMAC_HACK */
-+      printk("safe: md5/sha not implemented\n");
-+#endif /* HMAC_HACK */
-+}
-+#undef N
-+
-+/*
-+ * 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.
-+ */
-+static int
-+safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
-+{
-+      struct safe_softc *sc = device_get_softc(dev);
-+      struct cryptoini *c, *encini = NULL, *macini = NULL;
-+      struct safe_session *ses = NULL;
-+      int sesn;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (sidp == NULL || cri == NULL || 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_NULL_HMAC) {
-+                      if (macini)
-+                              return (EINVAL);
-+                      macini = c;
-+              } else if (c->cri_alg == CRYPTO_DES_CBC ||
-+                  c->cri_alg == CRYPTO_3DES_CBC ||
-+                  c->cri_alg == CRYPTO_AES_CBC ||
-+                  c->cri_alg == CRYPTO_NULL_CBC) {
-+                      if (encini)
-+                              return (EINVAL);
-+                      encini = c;
-+              } else
-+                      return (EINVAL);
-+      }
-+      if (encini == NULL && macini == NULL)
-+              return (EINVAL);
-+      if (encini) {                   /* validate key length */
-+              switch (encini->cri_alg) {
-+              case CRYPTO_DES_CBC:
-+                      if (encini->cri_klen != 64)
-+                              return (EINVAL);
-+                      break;
-+              case CRYPTO_3DES_CBC:
-+                      if (encini->cri_klen != 192)
-+                              return (EINVAL);
-+                      break;
-+              case CRYPTO_AES_CBC:
-+                      if (encini->cri_klen != 128 &&
-+                          encini->cri_klen != 192 &&
-+                          encini->cri_klen != 256)
-+                              return (EINVAL);
-+                      break;
-+              }
-+      }
-+
-+      if (sc->sc_sessions == NULL) {
-+              ses = sc->sc_sessions = (struct safe_session *)
-+                      kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
-+              if (ses == NULL)
-+                      return (ENOMEM);
-+              memset(ses, 0, sizeof(struct safe_session));
-+              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) {
-+                      sesn = sc->sc_nsessions;
-+                      ses = (struct safe_session *)
-+                              kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
-+                      if (ses == NULL)
-+                              return (ENOMEM);
-+                      memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
-+                      bcopy(sc->sc_sessions, ses, sesn *
-+                          sizeof(struct safe_session));
-+                      bzero(sc->sc_sessions, sesn *
-+                          sizeof(struct safe_session));
-+                      kfree(sc->sc_sessions);
-+                      sc->sc_sessions = ses;
-+                      ses = &sc->sc_sessions[sesn];
-+                      sc->sc_nsessions++;
-+              }
-+      }
-+
-+      bzero(ses, sizeof(struct safe_session));
-+      ses->ses_used = 1;
-+
-+      if (encini) {
-+              /* get an IV */
-+              /* XXX may read fewer than requested */
-+              read_random(ses->ses_iv, sizeof(ses->ses_iv));
-+
-+              ses->ses_klen = encini->cri_klen;
-+              if (encini->cri_key != NULL)
-+                      safe_setup_enckey(ses, encini->cri_key);
-+      }
-+
-+      if (macini) {
-+              ses->ses_mlen = macini->cri_mlen;
-+              if (ses->ses_mlen == 0) {
-+                      if (macini->cri_alg == CRYPTO_MD5_HMAC)
-+                              ses->ses_mlen = MD5_HASH_LEN;
-+                      else
-+                              ses->ses_mlen = SHA1_HASH_LEN;
-+              }
-+
-+              if (macini->cri_key != NULL) {
-+                      safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
-+                          macini->cri_klen / 8);
-+              }
-+      }
-+
-+      *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
-+      return (0);
-+}
-+
-+/*
-+ * Deallocate a session.
-+ */
-+static int
-+safe_freesession(device_t dev, u_int64_t tid)
-+{
-+      struct safe_softc *sc = device_get_softc(dev);
-+      int session, ret;
-+      u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (sc == NULL)
-+              return (EINVAL);
-+
-+      session = SAFE_SESSION(sid);
-+      if (session < sc->sc_nsessions) {
-+              bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
-+              ret = 0;
-+      } else
-+              ret = EINVAL;
-+      return (ret);
-+}
-+
-+
-+static int
-+safe_process(device_t dev, struct cryptop *crp, int hint)
-+{
-+      struct safe_softc *sc = device_get_softc(dev);
-+      int err = 0, i, nicealign, uniform;
-+      struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
-+      int bypass, oplen, ivsize;
-+      caddr_t iv;
-+      int16_t coffset;
-+      struct safe_session *ses;
-+      struct safe_ringentry *re;
-+      struct safe_sarec *sa;
-+      struct safe_pdesc *pd;
-+      u_int32_t cmd0, cmd1, staterec;
-+      unsigned long flags;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
-+              safestats.st_invalid++;
-+              return (EINVAL);
-+      }
-+      if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
-+              safestats.st_badsession++;
-+              return (EINVAL);
-+      }
-+
-+      spin_lock_irqsave(&sc->sc_ringmtx, flags);
-+      if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
-+              safestats.st_ringfull++;
-+              sc->sc_needwakeup |= CRYPTO_SYMQ;
-+              spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
-+              return (ERESTART);
-+      }
-+      re = sc->sc_front;
-+
-+      staterec = re->re_sa.sa_staterec;       /* save */
-+      /* NB: zero everything but the PE descriptor */
-+      bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
-+      re->re_sa.sa_staterec = staterec;       /* restore */
-+
-+      re->re_crp = crp;
-+      re->re_sesn = SAFE_SESSION(crp->crp_sid);
-+
-+      re->re_src.nsegs = 0;
-+      re->re_dst.nsegs = 0;
-+
-+      if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+              re->re_src_skb = (struct sk_buff *)crp->crp_buf;
-+              re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
-+      } else if (crp->crp_flags & CRYPTO_F_IOV) {
-+              re->re_src_io = (struct uio *)crp->crp_buf;
-+              re->re_dst_io = (struct uio *)crp->crp_buf;
-+      } else {
-+              safestats.st_badflags++;
-+              err = EINVAL;
-+              goto errout;    /* XXX we don't handle contiguous blocks! */
-+      }
-+
-+      sa = &re->re_sa;
-+      ses = &sc->sc_sessions[re->re_sesn];
-+
-+      crd1 = crp->crp_desc;
-+      if (crd1 == NULL) {
-+              safestats.st_nodesc++;
-+              err = EINVAL;
-+              goto errout;
-+      }
-+      crd2 = crd1->crd_next;
-+
-+      cmd0 = SAFE_SA_CMD0_BASIC;              /* basic group operation */
-+      cmd1 = 0;
-+      if (crd2 == NULL) {
-+              if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
-+                  crd1->crd_alg == CRYPTO_SHA1_HMAC ||
-+                  crd1->crd_alg == CRYPTO_NULL_HMAC) {
-+                      maccrd = crd1;
-+                      enccrd = NULL;
-+                      cmd0 |= SAFE_SA_CMD0_OP_HASH;
-+              } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
-+                  crd1->crd_alg == CRYPTO_3DES_CBC ||
-+                  crd1->crd_alg == CRYPTO_AES_CBC ||
-+                  crd1->crd_alg == CRYPTO_NULL_CBC) {
-+                      maccrd = NULL;
-+                      enccrd = crd1;
-+                      cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
-+              } else {
-+                      safestats.st_badalg++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+      } else {
-+              if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
-+                  crd1->crd_alg == CRYPTO_SHA1_HMAC ||
-+                  crd1->crd_alg == CRYPTO_NULL_HMAC) &&
-+                  (crd2->crd_alg == CRYPTO_DES_CBC ||
-+                      crd2->crd_alg == CRYPTO_3DES_CBC ||
-+                      crd2->crd_alg == CRYPTO_AES_CBC ||
-+                      crd2->crd_alg == CRYPTO_NULL_CBC) &&
-+                  ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
-+                      maccrd = crd1;
-+                      enccrd = crd2;
-+              } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
-+                  crd1->crd_alg == CRYPTO_3DES_CBC ||
-+                  crd1->crd_alg == CRYPTO_AES_CBC ||
-+                  crd1->crd_alg == CRYPTO_NULL_CBC) &&
-+                  (crd2->crd_alg == CRYPTO_MD5_HMAC ||
-+                      crd2->crd_alg == CRYPTO_SHA1_HMAC ||
-+                      crd2->crd_alg == CRYPTO_NULL_HMAC) &&
-+                  (crd1->crd_flags & CRD_F_ENCRYPT)) {
-+                      enccrd = crd1;
-+                      maccrd = crd2;
-+              } else {
-+                      safestats.st_badalg++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+              cmd0 |= SAFE_SA_CMD0_OP_BOTH;
-+      }
-+
-+      if (enccrd) {
-+              if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
-+                      safe_setup_enckey(ses, enccrd->crd_key);
-+
-+              if (enccrd->crd_alg == CRYPTO_DES_CBC) {
-+                      cmd0 |= SAFE_SA_CMD0_DES;
-+                      cmd1 |= SAFE_SA_CMD1_CBC;
-+                      ivsize = 2*sizeof(u_int32_t);
-+              } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
-+                      cmd0 |= SAFE_SA_CMD0_3DES;
-+                      cmd1 |= SAFE_SA_CMD1_CBC;
-+                      ivsize = 2*sizeof(u_int32_t);
-+              } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
-+                      cmd0 |= SAFE_SA_CMD0_AES;
-+                      cmd1 |= SAFE_SA_CMD1_CBC;
-+                      if (ses->ses_klen == 128)
-+                           cmd1 |=  SAFE_SA_CMD1_AES128;
-+                      else if (ses->ses_klen == 192)
-+                           cmd1 |=  SAFE_SA_CMD1_AES192;
-+                      else
-+                           cmd1 |=  SAFE_SA_CMD1_AES256;
-+                      ivsize = 4*sizeof(u_int32_t);
-+              } else {
-+                      cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
-+                      ivsize = 0;
-+              }
-+
-+              /*
-+               * Setup encrypt/decrypt state.  When using basic ops
-+               * we can't use an inline IV because hash/crypt offset
-+               * must be from the end of the IV to the start of the
-+               * crypt data and this leaves out the preceding header
-+               * from the hash calculation.  Instead we place the IV
-+               * in the state record and set the hash/crypt offset to
-+               * copy both the header+IV.
-+               */
-+              if (enccrd->crd_flags & CRD_F_ENCRYPT) {
-+                      cmd0 |= SAFE_SA_CMD0_OUTBOUND;
-+
-+                      if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
-+                              iv = enccrd->crd_iv;
-+                      else
-+                              iv = (caddr_t) ses->ses_iv;
-+                      if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
-+                              crypto_copyback(crp->crp_flags, crp->crp_buf,
-+                                  enccrd->crd_inject, ivsize, iv);
-+                      }
-+                      bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
-+                      /* make iv LE */
-+                      for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
-+                              re->re_sastate.sa_saved_iv[i] =
-+                                      cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
-+                      cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
-+                      re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
-+              } else {
-+                      cmd0 |= SAFE_SA_CMD0_INBOUND;
-+
-+                      if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
-+                              bcopy(enccrd->crd_iv,
-+                                      re->re_sastate.sa_saved_iv, ivsize);
-+                      } else {
-+                              crypto_copydata(crp->crp_flags, crp->crp_buf,
-+                                  enccrd->crd_inject, ivsize,
-+                                  (caddr_t)re->re_sastate.sa_saved_iv);
-+                      }
-+                      /* make iv LE */
-+                      for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
-+                              re->re_sastate.sa_saved_iv[i] =
-+                                      cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
-+                      cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
-+              }
-+              /*
-+               * For basic encryption use the zero pad algorithm.
-+               * This pads results to an 8-byte boundary and
-+               * suppresses padding verification for inbound (i.e.
-+               * decrypt) operations.
-+               *
-+               * NB: Not sure if the 8-byte pad boundary is a problem.
-+               */
-+              cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
-+
-+              /* XXX assert key bufs have the same size */
-+              bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
-+      }
-+
-+      if (maccrd) {
-+              if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
-+                      safe_setup_mackey(ses, maccrd->crd_alg,
-+                          maccrd->crd_key, maccrd->crd_klen / 8);
-+              }
-+
-+              if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
-+                      cmd0 |= SAFE_SA_CMD0_MD5;
-+                      cmd1 |= SAFE_SA_CMD1_HMAC;      /* NB: enable HMAC */
-+              } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
-+                      cmd0 |= SAFE_SA_CMD0_SHA1;
-+                      cmd1 |= SAFE_SA_CMD1_HMAC;      /* NB: enable HMAC */
-+              } else {
-+                      cmd0 |= SAFE_SA_CMD0_HASH_NULL;
-+              }
-+              /*
-+               * Digest data is loaded from the SA and the hash
-+               * result is saved to the state block where we
-+               * retrieve it for return to the caller.
-+               */
-+              /* XXX assert digest bufs have the same size */
-+              bcopy(ses->ses_hminner, sa->sa_indigest,
-+                      sizeof(sa->sa_indigest));
-+              bcopy(ses->ses_hmouter, sa->sa_outdigest,
-+                      sizeof(sa->sa_outdigest));
-+
-+              cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
-+              re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
-+      }
-+
-+      if (enccrd && maccrd) {
-+              /*
-+               * The offset from hash data to the start of
-+               * crypt data is the difference in the skips.
-+               */
-+              bypass = maccrd->crd_skip;
-+              coffset = enccrd->crd_skip - maccrd->crd_skip;
-+              if (coffset < 0) {
-+                      DPRINTF(("%s: hash does not precede crypt; "
-+                              "mac skip %u enc skip %u\n",
-+                              __func__, maccrd->crd_skip, enccrd->crd_skip));
-+                      safestats.st_skipmismatch++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+              oplen = enccrd->crd_skip + enccrd->crd_len;
-+              if (maccrd->crd_skip + maccrd->crd_len != oplen) {
-+                      DPRINTF(("%s: hash amount %u != crypt amount %u\n",
-+                              __func__, maccrd->crd_skip + maccrd->crd_len,
-+                              oplen));
-+                      safestats.st_lenmismatch++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+#ifdef SAFE_DEBUG
-+              if (debug) {
-+                      printf("mac: skip %d, len %d, inject %d\n",
-+                          maccrd->crd_skip, maccrd->crd_len,
-+                          maccrd->crd_inject);
-+                      printf("enc: skip %d, len %d, inject %d\n",
-+                          enccrd->crd_skip, enccrd->crd_len,
-+                          enccrd->crd_inject);
-+                      printf("bypass %d coffset %d oplen %d\n",
-+                              bypass, coffset, oplen);
-+              }
-+#endif
-+              if (coffset & 3) {      /* offset must be 32-bit aligned */
-+                      DPRINTF(("%s: coffset %u misaligned\n",
-+                              __func__, coffset));
-+                      safestats.st_coffmisaligned++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+              coffset >>= 2;
-+              if (coffset > 255) {    /* offset must be <256 dwords */
-+                      DPRINTF(("%s: coffset %u too big\n",
-+                              __func__, coffset));
-+                      safestats.st_cofftoobig++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+              /*
-+               * Tell the hardware to copy the header to the output.
-+               * The header is defined as the data from the end of
-+               * the bypass to the start of data to be encrypted. 
-+               * Typically this is the inline IV.  Note that you need
-+               * to do this even if src+dst are the same; it appears
-+               * that w/o this bit the crypted data is written
-+               * immediately after the bypass data.
-+               */
-+              cmd1 |= SAFE_SA_CMD1_HDRCOPY;
-+              /*
-+               * Disable IP header mutable bit handling.  This is
-+               * needed to get correct HMAC calculations.
-+               */
-+              cmd1 |= SAFE_SA_CMD1_MUTABLE;
-+      } else {
-+              if (enccrd) {
-+                      bypass = enccrd->crd_skip;
-+                      oplen = bypass + enccrd->crd_len;
-+              } else {
-+                      bypass = maccrd->crd_skip;
-+                      oplen = bypass + maccrd->crd_len;
-+              }
-+              coffset = 0;
-+      }
-+      /* XXX verify multiple of 4 when using s/g */
-+      if (bypass > 96) {              /* bypass offset must be <= 96 bytes */
-+              DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
-+              safestats.st_bypasstoobig++;
-+              err = EINVAL;
-+              goto errout;
-+      }
-+
-+      if (crp->crp_flags & CRYPTO_F_SKBUF) {
-+              if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
-+                      safestats.st_noload++;
-+                      err = ENOMEM;
-+                      goto errout;
-+              }
-+      } else if (crp->crp_flags & CRYPTO_F_IOV) {
-+              if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
-+                      safestats.st_noload++;
-+                      err = ENOMEM;
-+                      goto errout;
-+              }
-+      }
-+      nicealign = safe_dmamap_aligned(sc, &re->re_src);
-+      uniform = safe_dmamap_uniform(sc, &re->re_src);
-+
-+      DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
-+              nicealign, uniform, re->re_src.nsegs));
-+      if (re->re_src.nsegs > 1) {
-+              re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
-+                      ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
-+              for (i = 0; i < re->re_src_nsegs; i++) {
-+                      /* NB: no need to check if there's space */
-+                      pd = sc->sc_spfree;
-+                      if (++(sc->sc_spfree) == sc->sc_springtop)
-+                              sc->sc_spfree = sc->sc_spring;
-+
-+                      KASSERT((pd->pd_flags&3) == 0 ||
-+                              (pd->pd_flags&3) == SAFE_PD_DONE,
-+                              ("bogus source particle descriptor; flags %x",
-+                              pd->pd_flags));
-+                      pd->pd_addr = re->re_src_segs[i].ds_addr;
-+                      pd->pd_size = re->re_src_segs[i].ds_len;
-+                      pd->pd_flags = SAFE_PD_READY;
-+              }
-+              cmd0 |= SAFE_SA_CMD0_IGATHER;
-+      } else {
-+              /*
-+               * No need for gather, reference the operand directly.
-+               */
-+              re->re_desc.d_src = re->re_src_segs[0].ds_addr;
-+      }
-+
-+      if (enccrd == NULL && maccrd != NULL) {
-+              /*
-+               * Hash op; no destination needed.
-+               */
-+      } else {
-+              if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
-+                      if (!nicealign) {
-+                              safestats.st_iovmisaligned++;
-+                              err = EINVAL;
-+                              goto errout;
-+                      }
-+                      if (uniform != 1) {
-+                              device_printf(sc->sc_dev, "!uniform source\n");
-+                              if (!uniform) {
-+                                      /*
-+                                       * There's no way to handle the DMA
-+                                       * requirements with this uio.  We
-+                                       * could create a separate DMA area for
-+                                       * the result and then copy it back,
-+                                       * but for now we just bail and return
-+                                       * an error.  Note that uio requests
-+                                       * > SAFE_MAX_DSIZE are handled because
-+                                       * the DMA map and segment list for the
-+                                       * destination wil result in a
-+                                       * destination particle list that does
-+                                       * the necessary scatter DMA.
-+                                       */ 
-+                                      safestats.st_iovnotuniform++;
-+                                      err = EINVAL;
-+                                      goto errout;
-+                              }
-+                      } else
-+                              re->re_dst = re->re_src;
-+              } else {
-+                      safestats.st_badflags++;
-+                      err = EINVAL;
-+                      goto errout;
-+              }
-+
-+              if (re->re_dst.nsegs > 1) {
-+                      re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
-+                          ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
-+                      for (i = 0; i < re->re_dst_nsegs; i++) {
-+                              pd = sc->sc_dpfree;
-+                              KASSERT((pd->pd_flags&3) == 0 ||
-+                                      (pd->pd_flags&3) == SAFE_PD_DONE,
-+                                      ("bogus dest particle descriptor; flags %x",
-+                                              pd->pd_flags));
-+                              if (++(sc->sc_dpfree) == sc->sc_dpringtop)
-+                                      sc->sc_dpfree = sc->sc_dpring;
-+                              pd->pd_addr = re->re_dst_segs[i].ds_addr;
-+                              pd->pd_flags = SAFE_PD_READY;
-+                      }
-+                      cmd0 |= SAFE_SA_CMD0_OSCATTER;
-+              } else {
-+                      /*
-+                       * No need for scatter, reference the operand directly.
-+                       */
-+                      re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
-+              }
-+      }
-+
-+      /*
-+       * All done with setup; fillin the SA command words
-+       * and the packet engine descriptor.  The operation
-+       * is now ready for submission to the hardware.
-+       */
-+      sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
-+      sa->sa_cmd1 = cmd1
-+                  | (coffset << SAFE_SA_CMD1_OFFSET_S)
-+                  | SAFE_SA_CMD1_SAREV1       /* Rev 1 SA data structure */
-+                  | SAFE_SA_CMD1_SRPCI
-+                  ;
-+      /*
-+       * NB: the order of writes is important here.  In case the
-+       * chip is scanning the ring because of an outstanding request
-+       * it might nab this one too.  In that case we need to make
-+       * sure the setup is complete before we write the length
-+       * field of the descriptor as it signals the descriptor is
-+       * ready for processing.
-+       */
-+      re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
-+      if (maccrd)
-+              re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
-+      wmb();
-+      re->re_desc.d_len = oplen
-+                        | SAFE_PE_LEN_READY
-+                        | (bypass << SAFE_PE_LEN_BYPASS_S)
-+                        ;
-+
-+      safestats.st_ipackets++;
-+      safestats.st_ibytes += oplen;
-+
-+      if (++(sc->sc_front) == sc->sc_ringtop)
-+              sc->sc_front = sc->sc_ring;
-+
-+      /* XXX honor batching */
-+      safe_feed(sc, re);
-+      spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
-+      return (0);
-+
-+errout:
-+      if (re->re_src.map != re->re_dst.map)
-+              pci_unmap_operand(sc, &re->re_dst);
-+      if (re->re_src.map)
-+              pci_unmap_operand(sc, &re->re_src);
-+      spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
-+      if (err != ERESTART) {
-+              crp->crp_etype = err;
-+              crypto_done(crp);
-+      } else {
-+              sc->sc_needwakeup |= CRYPTO_SYMQ;
-+      }
-+      return (err);
-+}
-+
-+static void
-+safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
-+{
-+      struct cryptop *crp = (struct cryptop *)re->re_crp;
-+      struct cryptodesc *crd;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      safestats.st_opackets++;
-+      safestats.st_obytes += re->re_dst.mapsize;
-+
-+      if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
-+              device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
-+                      re->re_desc.d_csr,
-+                      re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
-+              safestats.st_peoperr++;
-+              crp->crp_etype = EIO;           /* something more meaningful? */
-+      }
-+
-+      if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
-+              pci_unmap_operand(sc, &re->re_dst);
-+      pci_unmap_operand(sc, &re->re_src);
-+
-+      /* 
-+       * If result was written to a differet mbuf chain, swap
-+       * it in as the return value and reclaim the original.
-+       */
-+      if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
-+              device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
-+              /* kfree_skb(skb) */
-+              /* crp->crp_buf = (caddr_t)re->re_dst_skb */
-+              return;
-+      }
-+
-+      if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
-+              /* copy out IV for future use */
-+              for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
-+                      int i;
-+                      int ivsize;
-+
-+                      if (crd->crd_alg == CRYPTO_DES_CBC ||
-+                          crd->crd_alg == CRYPTO_3DES_CBC) {
-+                              ivsize = 2*sizeof(u_int32_t);
-+                      } else if (crd->crd_alg == CRYPTO_AES_CBC) {
-+                              ivsize = 4*sizeof(u_int32_t);
-+                      } else
-+                              continue;
-+                      crypto_copydata(crp->crp_flags, crp->crp_buf,
-+                          crd->crd_skip + crd->crd_len - ivsize, ivsize,
-+                          (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
-+                      for (i = 0;
-+                                      i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
-+                                      i++)
-+                              sc->sc_sessions[re->re_sesn].ses_iv[i] =
-+                                      cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
-+                      break;
-+              }
-+      }
-+
-+      if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
-+              /* copy out ICV result */
-+              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_NULL_HMAC))
-+                              continue;
-+                      if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
-+                              /*
-+                               * SHA-1 ICV's are byte-swapped; fix 'em up
-+                               * before copy them to their destination.
-+                               */
-+                              re->re_sastate.sa_saved_indigest[0] =
-+                                      cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
-+                              re->re_sastate.sa_saved_indigest[1] = 
-+                                      cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
-+                              re->re_sastate.sa_saved_indigest[2] =
-+                                      cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
-+                      } else {
-+                              re->re_sastate.sa_saved_indigest[0] =
-+                                      cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
-+                              re->re_sastate.sa_saved_indigest[1] = 
-+                                      cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
-+                              re->re_sastate.sa_saved_indigest[2] =
-+                                      cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
-+                      }
-+                      crypto_copyback(crp->crp_flags, crp->crp_buf,
-+                          crd->crd_inject,
-+                          sc->sc_sessions[re->re_sesn].ses_mlen,
-+                          (caddr_t)re->re_sastate.sa_saved_indigest);
-+                      break;
-+              }
-+      }
-+      crypto_done(crp);
-+}
-+
-+
-+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
-+#define       SAFE_RNG_MAXWAIT        1000
-+
-+static void
-+safe_rng_init(struct safe_softc *sc)
-+{
-+      u_int32_t w, v;
-+      int i;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      WRITE_REG(sc, SAFE_RNG_CTRL, 0);
-+      /* use default value according to the manual */
-+      WRITE_REG(sc, SAFE_RNG_CNFG, 0x834);    /* magic from SafeNet */
-+      WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
-+
-+      /*
-+       * There is a bug in rev 1.0 of the 1140 that when the RNG
-+       * is brought out of reset the ready status flag does not
-+       * work until the RNG has finished its internal initialization.
-+       *
-+       * So in order to determine the device is through its
-+       * initialization we must read the data register, using the
-+       * status reg in the read in case it is initialized.  Then read
-+       * the data register until it changes from the first read.
-+       * Once it changes read the data register until it changes
-+       * again.  At this time the RNG is considered initialized. 
-+       * This could take between 750ms - 1000ms in time.
-+       */
-+      i = 0;
-+      w = READ_REG(sc, SAFE_RNG_OUT);
-+      do {
-+              v = READ_REG(sc, SAFE_RNG_OUT);
-+              if (v != w) {
-+                      w = v;
-+                      break;
-+              }
-+              DELAY(10);
-+      } while (++i < SAFE_RNG_MAXWAIT);
-+
-+      /* Wait Until data changes again */
-+      i = 0;
-+      do {
-+              v = READ_REG(sc, SAFE_RNG_OUT);
-+              if (v != w)
-+                      break;
-+              DELAY(10);
-+      } while (++i < SAFE_RNG_MAXWAIT);
-+}
-+
-+static __inline void
-+safe_rng_disable_short_cycle(struct safe_softc *sc)
-+{
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      WRITE_REG(sc, SAFE_RNG_CTRL,
-+              READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
-+}
-+
-+static __inline void
-+safe_rng_enable_short_cycle(struct safe_softc *sc)
-+{
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      WRITE_REG(sc, SAFE_RNG_CTRL, 
-+              READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
-+}
-+
-+static __inline u_int32_t
-+safe_rng_read(struct safe_softc *sc)
-+{
-+      int i;
-+
-+      i = 0;
-+      while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
-+              ;
-+      return READ_REG(sc, SAFE_RNG_OUT);
-+}
-+
-+static int
-+safe_read_random(void *arg, u_int32_t *buf, int maxwords)
-+{
-+      struct safe_softc *sc = (struct safe_softc *) arg;
-+      int i, rc;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+      
-+      safestats.st_rng++;
-+      /*
-+       * Fetch the next block of data.
-+       */
-+      if (maxwords > safe_rngbufsize)
-+              maxwords = safe_rngbufsize;
-+      if (maxwords > SAFE_RNG_MAXBUFSIZ)
-+              maxwords = SAFE_RNG_MAXBUFSIZ;
-+retry:
-+      /* read as much as we can */
-+      for (rc = 0; rc < maxwords; rc++) {
-+              if (READ_REG(sc, SAFE_RNG_STAT) != 0)
-+                      break;
-+              buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
-+      }
-+      if (rc == 0)
-+              return 0;
-+      /*
-+       * Check the comparator alarm count and reset the h/w if
-+       * it exceeds our threshold.  This guards against the
-+       * hardware oscillators resonating with external signals.
-+       */
-+      if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
-+              u_int32_t freq_inc, w;
-+
-+              DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
-+                      (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
-+              safestats.st_rngalarm++;
-+              safe_rng_enable_short_cycle(sc);
-+              freq_inc = 18;
-+              for (i = 0; i < 64; i++) {
-+                      w = READ_REG(sc, SAFE_RNG_CNFG);
-+                      freq_inc = ((w + freq_inc) & 0x3fL);
-+                      w = ((w & ~0x3fL) | freq_inc);
-+                      WRITE_REG(sc, SAFE_RNG_CNFG, w);
-+
-+                      WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
-+
-+                      (void) safe_rng_read(sc);
-+                      DELAY(25);
-+
-+                      if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
-+                              safe_rng_disable_short_cycle(sc);
-+                              goto retry;
-+                      }
-+                      freq_inc = 1;
-+              }
-+              safe_rng_disable_short_cycle(sc);
-+      } else
-+              WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
-+
-+      return(rc);
-+}
-+#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
-+
-+
-+/*
-+ * Resets the board.  Values in the regesters are left as is
-+ * from the reset (i.e. initial values are assigned elsewhere).
-+ */
-+static void
-+safe_reset_board(struct safe_softc *sc)
-+{
-+      u_int32_t v;
-+      /*
-+       * Reset the device.  The manual says no delay
-+       * is needed between marking and clearing reset.
-+       */
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      v = READ_REG(sc, SAFE_PE_DMACFG) &~
-+              (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
-+               SAFE_PE_DMACFG_SGRESET);
-+      WRITE_REG(sc, SAFE_PE_DMACFG, v
-+                                  | SAFE_PE_DMACFG_PERESET
-+                                  | SAFE_PE_DMACFG_PDRRESET
-+                                  | SAFE_PE_DMACFG_SGRESET);
-+      WRITE_REG(sc, SAFE_PE_DMACFG, v);
-+}
-+
-+/*
-+ * Initialize registers we need to touch only once.
-+ */
-+static void
-+safe_init_board(struct safe_softc *sc)
-+{
-+      u_int32_t v, dwords;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      v = READ_REG(sc, SAFE_PE_DMACFG);
-+      v &=~ (   SAFE_PE_DMACFG_PEMODE
-+                      | SAFE_PE_DMACFG_FSENA          /* failsafe enable */
-+                      | SAFE_PE_DMACFG_GPRPCI         /* gather ring on PCI */
-+                      | SAFE_PE_DMACFG_SPRPCI         /* scatter ring on PCI */
-+                      | SAFE_PE_DMACFG_ESDESC         /* endian-swap descriptors */
-+                      | SAFE_PE_DMACFG_ESPDESC        /* endian-swap part. desc's */
-+                      | SAFE_PE_DMACFG_ESSA           /* endian-swap SA's */
-+                      | SAFE_PE_DMACFG_ESPACKET       /* swap the packet data */
-+                );
-+      v |= SAFE_PE_DMACFG_FSENA               /* failsafe enable */
-+        |  SAFE_PE_DMACFG_GPRPCI              /* gather ring on PCI */
-+        |  SAFE_PE_DMACFG_SPRPCI              /* scatter ring on PCI */
-+        |  SAFE_PE_DMACFG_ESDESC              /* endian-swap descriptors */
-+        |  SAFE_PE_DMACFG_ESPDESC             /* endian-swap part. desc's */
-+        |  SAFE_PE_DMACFG_ESSA                /* endian-swap SA's */
-+#if 0
-+        |  SAFE_PE_DMACFG_ESPACKET    /* swap the packet data */
-+#endif
-+        ;
-+      WRITE_REG(sc, SAFE_PE_DMACFG, v);
-+
-+#ifdef __BIG_ENDIAN
-+      /* tell the safenet that we are 4321 and not 1234 */
-+      WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
-+#endif
-+
-+      if (sc->sc_chiprev == SAFE_REV(1,0)) {
-+              /*
-+               * Avoid large PCI DMA transfers.  Rev 1.0 has a bug where
-+               * "target mode transfers" done while the chip is DMA'ing
-+               * >1020 bytes cause the hardware to lockup.  To avoid this
-+               * we reduce the max PCI transfer size and use small source
-+               * particle descriptors (<= 256 bytes).
-+               */
-+              WRITE_REG(sc, SAFE_DMA_CFG, 256);
-+              device_printf(sc->sc_dev,
-+                      "Reduce max DMA size to %u words for rev %u.%u WAR\n",
-+                      (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
-+                      (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
-+                      (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
-+              sc->sc_max_dsize = 256;
-+      } else {
-+              sc->sc_max_dsize = SAFE_MAX_DSIZE;
-+      }
-+
-+      /* NB: operands+results are overlaid */
-+      WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
-+      WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
-+      /*
-+       * Configure ring entry size and number of items in the ring.
-+       */
-+      KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
-+              ("PE ring entry not 32-bit aligned!"));
-+      dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
-+      WRITE_REG(sc, SAFE_PE_RINGCFG,
-+              (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
-+      WRITE_REG(sc, SAFE_PE_RINGPOLL, 0);     /* disable polling */
-+
-+      WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
-+      WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
-+      WRITE_REG(sc, SAFE_PE_PARTSIZE,
-+              (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
-+      /*
-+       * NB: destination particles are fixed size.  We use
-+       *     an mbuf cluster and require all results go to
-+       *     clusters or smaller.
-+       */
-+      WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
-+
-+      /* it's now safe to enable PE mode, do it */
-+      WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
-+
-+      /*
-+       * Configure hardware to use level-triggered interrupts and
-+       * to interrupt after each descriptor is processed.
-+       */
-+      WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
-+      WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
-+      WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
-+      WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
-+}
-+
-+
-+/*
-+ * Clean up after a chip crash.
-+ * It is assumed that the caller in splimp()
-+ */
-+static void
-+safe_cleanchip(struct safe_softc *sc)
-+{
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (sc->sc_nqchip != 0) {
-+              struct safe_ringentry *re = sc->sc_back;
-+
-+              while (re != sc->sc_front) {
-+                      if (re->re_desc.d_csr != 0)
-+                              safe_free_entry(sc, re);
-+                      if (++re == sc->sc_ringtop)
-+                              re = sc->sc_ring;
-+              }
-+              sc->sc_back = re;
-+              sc->sc_nqchip = 0;
-+      }
-+}
-+
-+/*
-+ * free a safe_q
-+ * It is assumed that the caller is within splimp().
-+ */
-+static int
-+safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
-+{
-+      struct cryptop *crp;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      /*
-+       * Free header MCR
-+       */
-+      if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
-+#ifdef NOTYET
-+              m_freem(re->re_dst_m);
-+#else
-+              printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
-+#endif
-+
-+      crp = (struct cryptop *)re->re_crp;
-+      
-+      re->re_desc.d_csr = 0;
-+      
-+      crp->crp_etype = EFAULT;
-+      crypto_done(crp);
-+      return(0);
-+}
-+
-+/*
-+ * Routine to reset the chip and clean up.
-+ * It is assumed that the caller is in splimp()
-+ */
-+static void
-+safe_totalreset(struct safe_softc *sc)
-+{
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      safe_reset_board(sc);
-+      safe_init_board(sc);
-+      safe_cleanchip(sc);
-+}
-+
-+/*
-+ * Is the operand suitable aligned for direct DMA.  Each
-+ * segment must be aligned on a 32-bit boundary and all
-+ * but the last segment must be a multiple of 4 bytes.
-+ */
-+static int
-+safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
-+{
-+      int i;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      for (i = 0; i < op->nsegs; i++) {
-+              if (op->segs[i].ds_addr & 3)
-+                      return (0);
-+              if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
-+                      return (0);
-+      }
-+      return (1);
-+}
-+
-+/*
-+ * Is the operand suitable for direct DMA as the destination
-+ * of an operation.  The hardware requires that each ``particle''
-+ * but the last in an operation result have the same size.  We
-+ * fix that size at SAFE_MAX_DSIZE bytes.  This routine returns
-+ * 0 if some segment is not a multiple of of this size, 1 if all
-+ * segments are exactly this size, or 2 if segments are at worst
-+ * a multple of this size.
-+ */
-+static int
-+safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
-+{
-+      int result = 1;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (op->nsegs > 0) {
-+              int i;
-+
-+              for (i = 0; i < op->nsegs-1; i++) {
-+                      if (op->segs[i].ds_len % sc->sc_max_dsize)
-+                              return (0);
-+                      if (op->segs[i].ds_len != sc->sc_max_dsize)
-+                              result = 2;
-+              }
-+      }
-+      return (result);
-+}
-+
-+static int
-+safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
-+{
-+      struct safe_softc *sc = device_get_softc(dev);
-+      struct safe_pkq *q;
-+      unsigned long flags;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (sc == NULL) {
-+              krp->krp_status = EINVAL;
-+              goto err;
-+      }
-+
-+      if (krp->krp_op != CRK_MOD_EXP) {
-+              krp->krp_status = EOPNOTSUPP;
-+              goto err;
-+      }
-+
-+      q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
-+      if (q == NULL) {
-+              krp->krp_status = ENOMEM;
-+              goto err;
-+      }
-+      memset(q, 0, sizeof(*q));
-+      q->pkq_krp = krp;
-+      INIT_LIST_HEAD(&q->pkq_list);
-+
-+      spin_lock_irqsave(&sc->sc_pkmtx, flags);
-+      list_add_tail(&q->pkq_list, &sc->sc_pkq);
-+      safe_kfeed(sc);
-+      spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
-+      return (0);
-+
-+err:
-+      crypto_kdone(krp);
-+      return (0);
-+}
-+
-+#define       SAFE_CRK_PARAM_BASE     0
-+#define       SAFE_CRK_PARAM_EXP      1
-+#define       SAFE_CRK_PARAM_MOD      2
-+
-+static int
-+safe_kstart(struct safe_softc *sc)
-+{
-+      struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
-+      int exp_bits, mod_bits, base_bits;
-+      u_int32_t op, a_off, b_off, c_off, d_off;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
-+              krp->krp_status = EINVAL;
-+              return (1);
-+      }
-+
-+      base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
-+      if (base_bits > 2048)
-+              goto too_big;
-+      if (base_bits <= 0)             /* 5. base not zero */
-+              goto too_small;
-+
-+      exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
-+      if (exp_bits > 2048)
-+              goto too_big;
-+      if (exp_bits <= 0)              /* 1. exponent word length > 0 */
-+              goto too_small;         /* 4. exponent not zero */
-+
-+      mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
-+      if (mod_bits > 2048)
-+              goto too_big;
-+      if (mod_bits <= 32)             /* 2. modulus word length > 1 */
-+              goto too_small;         /* 8. MSW of modulus != zero */
-+      if (mod_bits < exp_bits)        /* 3 modulus len >= exponent len */
-+              goto too_small;
-+      if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
-+              goto bad_domain;        /* 6. modulus is odd */
-+      if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
-+              goto too_small;         /* make sure result will fit */
-+
-+      /* 7. modulus > base */
-+      if (mod_bits < base_bits)
-+              goto too_small;
-+      if (mod_bits == base_bits) {
-+              u_int8_t *basep, *modp;
-+              int i;
-+
-+              basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
-+                  ((base_bits + 7) / 8) - 1;
-+              modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
-+                  ((mod_bits + 7) / 8) - 1;
-+              
-+              for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
-+                      if (*modp < *basep)
-+                              goto too_small;
-+                      if (*modp > *basep)
-+                              break;
-+              }
-+      }
-+
-+      /* And on the 9th step, he rested. */
-+
-+      WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
-+      WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
-+      if (mod_bits > 1024) {
-+              op = SAFE_PK_FUNC_EXP4;
-+              a_off = 0x000;
-+              b_off = 0x100;
-+              c_off = 0x200;
-+              d_off = 0x300;
-+      } else {
-+              op = SAFE_PK_FUNC_EXP16;
-+              a_off = 0x000;
-+              b_off = 0x080;
-+              c_off = 0x100;
-+              d_off = 0x180;
-+      }
-+      sc->sc_pk_reslen = b_off - a_off;
-+      sc->sc_pk_resoff = d_off;
-+
-+      /* A is exponent, B is modulus, C is base, D is result */
-+      safe_kload_reg(sc, a_off, b_off - a_off,
-+          &krp->krp_param[SAFE_CRK_PARAM_EXP]);
-+      WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
-+      safe_kload_reg(sc, b_off, b_off - a_off,
-+          &krp->krp_param[SAFE_CRK_PARAM_MOD]);
-+      WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
-+      safe_kload_reg(sc, c_off, b_off - a_off,
-+          &krp->krp_param[SAFE_CRK_PARAM_BASE]);
-+      WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
-+      WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
-+
-+      WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
-+
-+      return (0);
-+
-+too_big:
-+      krp->krp_status = E2BIG;
-+      return (1);
-+too_small:
-+      krp->krp_status = ERANGE;
-+      return (1);
-+bad_domain:
-+      krp->krp_status = EDOM;
-+      return (1);
-+}
-+
-+static int
-+safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
-+{
-+      u_int plen = (cr->crp_nbits + 7) / 8;
-+      int i, sig = plen * 8;
-+      u_int8_t c, *p = cr->crp_p;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      for (i = plen - 1; i >= 0; i--) {
-+              c = p[i];
-+              if (c != 0) {
-+                      while ((c & 0x80) == 0) {
-+                              sig--;
-+                              c <<= 1;
-+                      }
-+                      break;
-+              }
-+              sig -= 8;
-+      }
-+      return (sig);
-+}
-+
-+static void
-+safe_kfeed(struct safe_softc *sc)
-+{
-+      struct safe_pkq *q, *tmp;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
-+              return;
-+      if (sc->sc_pkq_cur != NULL)
-+              return;
-+      list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
-+              sc->sc_pkq_cur = q;
-+              list_del(&q->pkq_list);
-+              if (safe_kstart(sc) != 0) {
-+                      crypto_kdone(q->pkq_krp);
-+                      kfree(q);
-+                      sc->sc_pkq_cur = NULL;
-+              } else {
-+                      /* op started, start polling */
-+                      mod_timer(&sc->sc_pkto, jiffies + 1);
-+                      break;
-+              }
-+      }
-+}
-+
-+static void
-+safe_kpoll(unsigned long arg)
-+{
-+      struct safe_softc *sc = NULL;
-+      struct safe_pkq *q;
-+      struct crparam *res;
-+      int i;
-+      u_int32_t buf[64];
-+      unsigned long flags;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (arg >= SAFE_MAX_CHIPS)
-+              return;
-+      sc = safe_chip_idx[arg];
-+      if (!sc) {
-+              DPRINTF(("%s() - bad callback\n", __FUNCTION__));
-+              return;
-+      }
-+
-+      spin_lock_irqsave(&sc->sc_pkmtx, flags);
-+      if (sc->sc_pkq_cur == NULL)
-+              goto out;
-+      if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
-+              /* still running, check back later */
-+              mod_timer(&sc->sc_pkto, jiffies + 1);
-+              goto out;
-+      }
-+
-+      q = sc->sc_pkq_cur;
-+      res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
-+      bzero(buf, sizeof(buf));
-+      bzero(res->crp_p, (res->crp_nbits + 7) / 8);
-+      for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
-+              buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
-+                  sc->sc_pk_resoff + (i << 2)));
-+      bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
-+      /*
-+       * reduce the bits that need copying if possible
-+       */
-+      res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
-+      res->crp_nbits = safe_ksigbits(sc, res);
-+
-+      for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
-+              WRITE_REG(sc, i, 0);
-+
-+      crypto_kdone(q->pkq_krp);
-+      kfree(q);
-+      sc->sc_pkq_cur = NULL;
-+
-+      safe_kfeed(sc);
-+out:
-+      spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
-+}
-+
-+static void
-+safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
-+    struct crparam *n)
-+{
-+      u_int32_t buf[64], i;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      bzero(buf, sizeof(buf));
-+      bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
-+
-+      for (i = 0; i < len >> 2; i++)
-+              WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
-+                  cpu_to_le32(buf[i]));
-+}
-+
-+#ifdef SAFE_DEBUG
-+static void
-+safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
-+{
-+      printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
-+              , tag
-+              , READ_REG(sc, SAFE_DMA_ENDIAN)
-+              , READ_REG(sc, SAFE_DMA_SRCADDR)
-+              , READ_REG(sc, SAFE_DMA_DSTADDR)
-+              , READ_REG(sc, SAFE_DMA_STAT)
-+      );
-+}
-+
-+static void
-+safe_dump_intrstate(struct safe_softc *sc, const char *tag)
-+{
-+      printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
-+              , tag
-+              , READ_REG(sc, SAFE_HI_CFG)
-+              , READ_REG(sc, SAFE_HI_MASK)
-+              , READ_REG(sc, SAFE_HI_DESC_CNT)
-+              , READ_REG(sc, SAFE_HU_STAT)
-+              , READ_REG(sc, SAFE_HM_STAT)
-+      );
-+}
-+
-+static void
-+safe_dump_ringstate(struct safe_softc *sc, const char *tag)
-+{
-+      u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
-+
-+      /* NB: assume caller has lock on ring */
-+      printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
-+              tag,
-+              estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
-+              (unsigned long)(sc->sc_back - sc->sc_ring),
-+              (unsigned long)(sc->sc_front - sc->sc_ring));
-+}
-+
-+static void
-+safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
-+{
-+      int ix, nsegs;
-+
-+      ix = re - sc->sc_ring;
-+      printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
-+              , tag
-+              , re, ix
-+              , re->re_desc.d_csr
-+              , re->re_desc.d_src
-+              , re->re_desc.d_dst
-+              , re->re_desc.d_sa
-+              , re->re_desc.d_len
-+      );
-+      if (re->re_src.nsegs > 1) {
-+              ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
-+                      sizeof(struct safe_pdesc);
-+              for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
-+                      printf(" spd[%u] %p: %p size %u flags %x"
-+                              , ix, &sc->sc_spring[ix]
-+                              , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
-+                              , sc->sc_spring[ix].pd_size
-+                              , sc->sc_spring[ix].pd_flags
-+                      );
-+                      if (sc->sc_spring[ix].pd_size == 0)
-+                              printf(" (zero!)");
-+                      printf("\n");
-+                      if (++ix == SAFE_TOTAL_SPART)
-+                              ix = 0;
-+              }
-+      }
-+      if (re->re_dst.nsegs > 1) {
-+              ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
-+                      sizeof(struct safe_pdesc);
-+              for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
-+                      printf(" dpd[%u] %p: %p flags %x\n"
-+                              , ix, &sc->sc_dpring[ix]
-+                              , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
-+                              , sc->sc_dpring[ix].pd_flags
-+                      );
-+                      if (++ix == SAFE_TOTAL_DPART)
-+                              ix = 0;
-+              }
-+      }
-+      printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
-+              re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
-+      printf("sa: key %x %x %x %x %x %x %x %x\n"
-+              , re->re_sa.sa_key[0]
-+              , re->re_sa.sa_key[1]
-+              , re->re_sa.sa_key[2]
-+              , re->re_sa.sa_key[3]
-+              , re->re_sa.sa_key[4]
-+              , re->re_sa.sa_key[5]
-+              , re->re_sa.sa_key[6]
-+              , re->re_sa.sa_key[7]
-+      );
-+      printf("sa: indigest %x %x %x %x %x\n"
-+              , re->re_sa.sa_indigest[0]
-+              , re->re_sa.sa_indigest[1]
-+              , re->re_sa.sa_indigest[2]
-+              , re->re_sa.sa_indigest[3]
-+              , re->re_sa.sa_indigest[4]
-+      );
-+      printf("sa: outdigest %x %x %x %x %x\n"
-+              , re->re_sa.sa_outdigest[0]
-+              , re->re_sa.sa_outdigest[1]
-+              , re->re_sa.sa_outdigest[2]
-+              , re->re_sa.sa_outdigest[3]
-+              , re->re_sa.sa_outdigest[4]
-+      );
-+      printf("sr: iv %x %x %x %x\n"
-+              , re->re_sastate.sa_saved_iv[0]
-+              , re->re_sastate.sa_saved_iv[1]
-+              , re->re_sastate.sa_saved_iv[2]
-+              , re->re_sastate.sa_saved_iv[3]
-+      );
-+      printf("sr: hashbc %u indigest %x %x %x %x %x\n"
-+              , re->re_sastate.sa_saved_hashbc
-+              , re->re_sastate.sa_saved_indigest[0]
-+              , re->re_sastate.sa_saved_indigest[1]
-+              , re->re_sastate.sa_saved_indigest[2]
-+              , re->re_sastate.sa_saved_indigest[3]
-+              , re->re_sastate.sa_saved_indigest[4]
-+      );
-+}
-+
-+static void
-+safe_dump_ring(struct safe_softc *sc, const char *tag)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&sc->sc_ringmtx, flags);
-+      printf("\nSafeNet Ring State:\n");
-+      safe_dump_intrstate(sc, tag);
-+      safe_dump_dmastatus(sc, tag);
-+      safe_dump_ringstate(sc, tag);
-+      if (sc->sc_nqchip) {
-+              struct safe_ringentry *re = sc->sc_back;
-+              do {
-+                      safe_dump_request(sc, tag, re);
-+                      if (++re == sc->sc_ringtop)
-+                              re = sc->sc_ring;
-+              } while (re != sc->sc_front);
-+      }
-+      spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
-+}
-+#endif /* SAFE_DEBUG */
-+
-+
-+static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
-+{
-+      struct safe_softc *sc = NULL;
-+      u32 mem_start, mem_len, cmd;
-+      int i, rc, devinfo;
-+      dma_addr_t raddr;
-+      static int num_chips = 0;
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      if (pci_enable_device(dev) < 0)
-+              return(-ENODEV);
-+
-+      if (!dev->irq) {
-+              printk("safe: found device with no IRQ assigned. check BIOS settings!");
-+              pci_disable_device(dev);
-+              return(-ENODEV);
-+      }
-+
-+      if (pci_set_mwi(dev)) {
-+              printk("safe: pci_set_mwi failed!");
-+              return(-ENODEV);
-+      }
-+
-+      sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
-+      if (!sc)
-+              return(-ENOMEM);
-+      memset(sc, 0, sizeof(*sc));
-+
-+      softc_device_init(sc, "safe", num_chips, safe_methods);
-+
-+      sc->sc_irq = -1;
-+      sc->sc_cid = -1;
-+      sc->sc_pcidev = dev;
-+      if (num_chips < SAFE_MAX_CHIPS) {
-+              safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
-+              num_chips++;
-+      }
-+
-+      INIT_LIST_HEAD(&sc->sc_pkq);
-+      spin_lock_init(&sc->sc_pkmtx);
-+
-+      pci_set_drvdata(sc->sc_pcidev, sc);
-+
-+      /* we read its hardware registers as memory */
-+      mem_start = pci_resource_start(sc->sc_pcidev, 0);
-+      mem_len   = pci_resource_len(sc->sc_pcidev, 0);
-+
-+      sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
-+      if (!sc->sc_base_addr) {
-+              device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
-+                              mem_start, mem_start + mem_len - 1);
-+              goto out;
-+      }
-+
-+      /* fix up the bus size */
-+      if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
-+              device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
-+              goto out;
-+      }
-+      if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
-+              device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
-+              goto out;
-+      }
-+
-+      pci_set_master(sc->sc_pcidev);
-+
-+      pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
-+
-+      if (!(cmd & PCI_COMMAND_MEMORY)) {
-+              device_printf(sc->sc_dev, "failed to enable memory mapping\n");
-+              goto out;
-+      }
-+
-+      if (!(cmd & PCI_COMMAND_MASTER)) {
-+              device_printf(sc->sc_dev, "failed to enable bus mastering\n");
-+              goto out;
-+      }
-+
-+      rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
-+      if (rc) {
-+              device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
-+              goto out;
-+      }
-+      sc->sc_irq = dev->irq;
-+
-+      sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
-+                      (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
-+
-+      /*
-+       * Allocate packet engine descriptors.
-+       */
-+      sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
-+                      SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
-+                      &sc->sc_ringalloc.dma_paddr);
-+      if (!sc->sc_ringalloc.dma_vaddr) {
-+              device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
-+              goto out;
-+      }
-+
-+      /*
-+       * Hookup the static portion of all our data structures.
-+       */
-+      sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
-+      sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
-+      sc->sc_front = sc->sc_ring;
-+      sc->sc_back = sc->sc_ring;
-+      raddr = sc->sc_ringalloc.dma_paddr;
-+      bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
-+      for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
-+              struct safe_ringentry *re = &sc->sc_ring[i];
-+
-+              re->re_desc.d_sa = raddr +
-+                      offsetof(struct safe_ringentry, re_sa);
-+              re->re_sa.sa_staterec = raddr +
-+                      offsetof(struct safe_ringentry, re_sastate);
-+
-+              raddr += sizeof (struct safe_ringentry);
-+      }
-+      spin_lock_init(&sc->sc_ringmtx);
-+
-+      /*
-+       * Allocate scatter and gather particle descriptors.
-+       */
-+      sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
-+                      SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
-+                      &sc->sc_spalloc.dma_paddr);
-+      if (!sc->sc_spalloc.dma_vaddr) {
-+              device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
-+              goto out;
-+      }
-+      sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
-+      sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
-+      sc->sc_spfree = sc->sc_spring;
-+      bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
-+
-+      sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
-+                      SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
-+                      &sc->sc_dpalloc.dma_paddr);
-+      if (!sc->sc_dpalloc.dma_vaddr) {
-+              device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
-+              goto out;
-+      }
-+      sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
-+      sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
-+      sc->sc_dpfree = sc->sc_dpring;
-+      bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
-+
-+      sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
-+      if (sc->sc_cid < 0) {
-+              device_printf(sc->sc_dev, "could not get crypto driver id\n");
-+              goto out;
-+      }
-+
-+      printf("%s:", device_get_nameunit(sc->sc_dev));
-+
-+      devinfo = READ_REG(sc, SAFE_DEVINFO);
-+      if (devinfo & SAFE_DEVINFO_RNG) {
-+              sc->sc_flags |= SAFE_FLAGS_RNG;
-+              printf(" rng");
-+      }
-+      if (devinfo & SAFE_DEVINFO_PKEY) {
-+              printf(" key");
-+              sc->sc_flags |= SAFE_FLAGS_KEY;
-+              crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
-+#if 0
-+              crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
-+#endif
-+              init_timer(&sc->sc_pkto);
-+              sc->sc_pkto.function = safe_kpoll;
-+              sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
-+      }
-+      if (devinfo & SAFE_DEVINFO_DES) {
-+              printf(" des/3des");
-+              crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
-+              crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
-+      }
-+      if (devinfo & SAFE_DEVINFO_AES) {
-+              printf(" aes");
-+              crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
-+      }
-+      if (devinfo & SAFE_DEVINFO_MD5) {
-+              printf(" md5");
-+              crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
-+      }
-+      if (devinfo & SAFE_DEVINFO_SHA1) {
-+              printf(" sha1");
-+              crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
-+      }
-+      printf(" null");
-+      crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
-+      crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
-+      /* XXX other supported algorithms */
-+      printf("\n");
-+
-+      safe_reset_board(sc);           /* reset h/w */
-+      safe_init_board(sc);            /* init h/w */
-+
-+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
-+      if (sc->sc_flags & SAFE_FLAGS_RNG) {
-+              safe_rng_init(sc);
-+              crypto_rregister(sc->sc_cid, safe_read_random, sc);
-+      }
-+#endif /* SAFE_NO_RNG */
-+
-+      return (0);
-+
-+out:
-+      if (sc->sc_cid >= 0)
-+              crypto_unregister_all(sc->sc_cid);
-+      if (sc->sc_irq != -1)
-+              free_irq(sc->sc_irq, sc);
-+      if (sc->sc_ringalloc.dma_vaddr)
-+              pci_free_consistent(sc->sc_pcidev,
-+                              SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
-+                              sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
-+      if (sc->sc_spalloc.dma_vaddr)
-+              pci_free_consistent(sc->sc_pcidev,
-+                              SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
-+                              sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
-+      if (sc->sc_dpalloc.dma_vaddr)
-+              pci_free_consistent(sc->sc_pcidev,
-+                              SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
-+                              sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
-+      kfree(sc);
-+      return(-ENODEV);
-+}
-+
-+static void safe_remove(struct pci_dev *dev)
-+{
-+      struct safe_softc *sc = pci_get_drvdata(dev);
-+
-+      DPRINTF(("%s()\n", __FUNCTION__));
-+
-+      /* XXX wait/abort active ops */
-+
-+      WRITE_REG(sc, SAFE_HI_MASK, 0);         /* disable interrupts */
-+
-+      del_timer_sync(&sc->sc_pkto);
-+
-+      crypto_unregister_all(sc->sc_cid);
-+
-+      safe_cleanchip(sc);
-+
-+      if (sc->sc_irq != -1)
-+              free_irq(sc->sc_irq, sc);
-+      if (sc->sc_ringalloc.dma_vaddr)
-+              pci_free_consistent(sc->sc_pcidev,
-+                              SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
-+                              sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
-+      if (sc->sc_spalloc.dma_vaddr)
-+              pci_free_consistent(sc->sc_pcidev,
-+                              SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
-+                              sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
-+      if (sc->sc_dpalloc.dma_vaddr)
-+              pci_free_consistent(sc->sc_pcidev,
-+                              SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
-+                              sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
-+      sc->sc_irq = -1;
-+      sc->sc_ringalloc.dma_vaddr = NULL;
-+      sc->sc_spalloc.dma_vaddr = NULL;
-+      sc->sc_dpalloc.dma_vaddr = NULL;
-+}
-+
-+static struct pci_device_id safe_pci_tbl[] = {
-+      { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
-+      { },
-+};
-+MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
-+
-+static struct pci_driver safe_driver = {
-+      .name         = "safe",
-+      .id_table     = safe_pci_tbl,
-+      .probe        = safe_probe,
-+      .remove       = safe_remove,
-+      /* add PM stuff here one day */
-+};
-+
-+static int __init safe_init (void)
-+{
-+      struct safe_softc *sc = NULL;
-+      int rc;
-+
-+      DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
-+
-+      rc = pci_register_driver(&safe_driver);
-+      pci_register_driver_compat(&safe_driver, rc);
-+
-+      return rc;
-+}
-+
-+static void __exit safe_exit (void)
-+{
-+      pci_unregister_driver(&safe_driver);
-+}
-+
-+module_init(safe_init);
-+module_exit(safe_exit);
-+
-+MODULE_LICENSE("BSD");
-+MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
-+MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
---- /dev/null
-+++ b/crypto/ocf/safe/sha1.c
-@@ -0,0 +1,279 @@
-+/*    $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $    */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
-+ * 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. Neither the name of the project nor the names of its contributors
-+ *    may be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
-+ */
-+
-+/*
-+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
-+ * based on: http://csrc.nist.gov/fips/fip180-1.txt
-+ * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
-+ */
-+
-+#if 0
-+#include <sys/cdefs.h>
-+__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
-+
-+#include <sys/types.h>
-+#include <sys/cdefs.h>
-+#include <sys/time.h>
-+#include <sys/systm.h>
-+
-+#include <crypto/sha1.h>
-+#endif
-+
-+/* sanity check */
-+#if BYTE_ORDER != BIG_ENDIAN
-+# if BYTE_ORDER != LITTLE_ENDIAN
-+#  define unsupported 1
-+# endif
-+#endif
-+
-+#ifndef unsupported
-+
-+/* constant table */
-+static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
-+#define       K(t)    _K[(t) / 20]
-+
-+#define       F0(b, c, d)     (((b) & (c)) | ((~(b)) & (d)))
-+#define       F1(b, c, d)     (((b) ^ (c)) ^ (d))
-+#define       F2(b, c, d)     (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
-+#define       F3(b, c, d)     (((b) ^ (c)) ^ (d))
-+
-+#define       S(n, x)         (((x) << (n)) | ((x) >> (32 - n)))
-+
-+#undef H
-+#define       H(n)    (ctxt->h.b32[(n)])
-+#define       COUNT   (ctxt->count)
-+#define       BCOUNT  (ctxt->c.b64[0] / 8)
-+#define       W(n)    (ctxt->m.b32[(n)])
-+
-+#define       PUTBYTE(x)      { \
-+      ctxt->m.b8[(COUNT % 64)] = (x);         \
-+      COUNT++;                                \
-+      COUNT %= 64;                            \
-+      ctxt->c.b64[0] += 8;                    \
-+      if (COUNT % 64 == 0)                    \
-+              sha1_step(ctxt);                \
-+     }
-+
-+#define       PUTPAD(x)       { \
-+      ctxt->m.b8[(COUNT % 64)] = (x);         \
-+      COUNT++;                                \
-+      COUNT %= 64;                            \
-+      if (COUNT % 64 == 0)                    \
-+              sha1_step(ctxt);                \
-+     }
-+
-+static void sha1_step(struct sha1_ctxt *);
-+
-+static void
-+sha1_step(ctxt)
-+      struct sha1_ctxt *ctxt;
-+{
-+      u_int32_t       a, b, c, d, e;
-+      size_t t, s;
-+      u_int32_t       tmp;
-+
-+#if BYTE_ORDER == LITTLE_ENDIAN
-+      struct sha1_ctxt tctxt;
-+      bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
-+      ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
-+      ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
-+      ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
-+      ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
-+      ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
-+      ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
-+      ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
-+      ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
-+      ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
-+      ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
-+      ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
-+      ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
-+      ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
-+      ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
-+      ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
-+      ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
-+      ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
-+      ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
-+      ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
-+      ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
-+      ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
-+      ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
-+      ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
-+      ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
-+      ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
-+      ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
-+      ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
-+      ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
-+      ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
-+      ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
-+      ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
-+      ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
-+#endif
-+
-+      a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
-+
-+      for (t = 0; t < 20; t++) {
-+              s = t & 0x0f;
-+              if (t >= 16) {
-+                      W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
-+              }
-+              tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
-+              e = d; d = c; c = S(30, b); b = a; a = tmp;
-+      }
-+      for (t = 20; t < 40; t++) {
-+              s = t & 0x0f;
-+              W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
-+              tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
-+              e = d; d = c; c = S(30, b); b = a; a = tmp;
-+      }
-+      for (t = 40; t < 60; t++) {
-+              s = t & 0x0f;
-+              W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
-+              tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
-+              e = d; d = c; c = S(30, b); b = a; a = tmp;
-+      }
-+      for (t = 60; t < 80; t++) {
-+              s = t & 0x0f;
-+              W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
-+              tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
-+              e = d; d = c; c = S(30, b); b = a; a = tmp;
-+      }
-+
-+      H(0) = H(0) + a;
-+      H(1) = H(1) + b;
-+      H(2) = H(2) + c;
-+      H(3) = H(3) + d;
-+      H(4) = H(4) + e;
-+
-+      bzero(&ctxt->m.b8[0], 64);
-+}
-+
-+/*------------------------------------------------------------*/
-+
-+void
-+sha1_init(ctxt)
-+      struct sha1_ctxt *ctxt;
-+{
-+      bzero(ctxt, sizeof(struct sha1_ctxt));
-+      H(0) = 0x67452301;
-+      H(1) = 0xefcdab89;
-+      H(2) = 0x98badcfe;
-+      H(3) = 0x10325476;
-+      H(4)