627f3538af19abf0820ae4e2cf8e1a9292a7158e
[openwrt-10.03/.git] / target / linux / generic-2.6 / patches-2.6.26 / 970-ocf_20080704.patch
1 --- a/crypto/Kconfig
2 +++ b/crypto/Kconfig
3 @@ -678,3 +678,6 @@
4  source "drivers/crypto/Kconfig"
5  
6  endif  # if CRYPTO
7 +
8 +source "crypto/ocf/Kconfig"
9 +
10 --- a/crypto/Makefile
11 +++ b/crypto/Makefile
12 @@ -72,6 +72,8 @@
13  obj-$(CONFIG_CRYPTO_PRNG) += prng.o
14  obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
15  
16 +obj-$(CONFIG_OCF_OCF) += ocf/
17 +
18  #
19  # generic algorithms and the async_tx api
20  #
21 --- a/drivers/char/random.c
22 +++ b/drivers/char/random.c
23 @@ -129,6 +129,9 @@
24   *                                unsigned int value);
25   *     void add_interrupt_randomness(int irq);
26   *
27 + *      void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
28 + *      int random_input_wait(void);
29 + *
30   * add_input_randomness() uses the input layer interrupt timing, as well as
31   * the event type information from the hardware.
32   *
33 @@ -140,6 +143,13 @@
34   * a better measure, since the timing of the disk interrupts are more
35   * unpredictable.
36   *
37 + * random_input_words() just provides a raw block of entropy to the input
38 + * pool, such as from a hardware entropy generator.
39 + *
40 + * random_input_wait() suspends the caller until such time as the
41 + * entropy pool falls below the write threshold, and returns a count of how
42 + * much entropy (in bits) is needed to sustain the pool.
43 + *
44   * All of these routines try to estimate how many bits of randomness a
45   * particular randomness source.  They do this by keeping track of the
46   * first and second order deltas of the event timings.
47 @@ -666,6 +676,61 @@
48  }
49  #endif
50  
51 +/*
52 + * random_input_words - add bulk entropy to pool
53 + *
54 + * @buf: buffer to add
55 + * @wordcount: number of __u32 words to add
56 + * @ent_count: total amount of entropy (in bits) to credit
57 + *
58 + * this provides bulk input of entropy to the input pool
59 + *
60 + */
61 +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
62 +{
63 +       mix_pool_bytes(&input_pool, buf, wordcount);
64 +
65 +       credit_entropy_bits(&input_pool, ent_count);
66 +
67 +       DEBUG_ENT("crediting %d bits => %d\n",
68 +                 ent_count, input_pool.entropy_count);
69 +       /*
70 +        * Wake up waiting processes if we have enough
71 +        * entropy.
72 +        */
73 +       if (input_pool.entropy_count >= random_read_wakeup_thresh)
74 +               wake_up_interruptible(&random_read_wait);
75 +}
76 +EXPORT_SYMBOL(random_input_words);
77 +
78 +/*
79 + * random_input_wait - wait until random needs entropy
80 + *
81 + * this function sleeps until the /dev/random subsystem actually
82 + * needs more entropy, and then return the amount of entropy
83 + * that it would be nice to have added to the system.
84 + */
85 +int random_input_wait(void)
86 +{
87 +       int count;
88 +
89 +       wait_event_interruptible(random_write_wait,
90 +                        input_pool.entropy_count < random_write_wakeup_thresh);
91 +
92 +       count = random_write_wakeup_thresh - input_pool.entropy_count;
93 +
94 +        /* likely we got woken up due to a signal */
95 +       if (count <= 0) count = random_read_wakeup_thresh;
96 +
97 +       DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
98 +                 count,
99 +                 input_pool.entropy_count, random_write_wakeup_thresh);
100 +
101 +       return count;
102 +}
103 +EXPORT_SYMBOL(random_input_wait);
104 +
105 +
106  #define EXTRACT_SIZE 10
107  
108  /*********************************************************************
109 --- a/fs/fcntl.c
110 +++ b/fs/fcntl.c
111 @@ -191,6 +191,7 @@
112                 ret = dupfd(file, 0, 0);
113         return ret;
114  }
115 +EXPORT_SYMBOL(sys_dup);
116  
117  #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME)
118  
119 --- a/include/linux/miscdevice.h
120 +++ b/include/linux/miscdevice.h
121 @@ -12,6 +12,7 @@
122  #define APOLLO_MOUSE_MINOR 7
123  #define PC110PAD_MINOR 9
124  /*#define ADB_MOUSE_MINOR 10   FIXME OBSOLETE */
125 +#define CRYPTODEV_MINOR                70      /* /dev/crypto */
126  #define WATCHDOG_MINOR         130     /* Watchdog timer     */
127  #define TEMP_MINOR             131     /* Temperature Sensor */
128  #define RTC_MINOR 135
129 --- a/include/linux/random.h
130 +++ b/include/linux/random.h
131 @@ -8,6 +8,7 @@
132  #define _LINUX_RANDOM_H
133  
134  #include <linux/ioctl.h>
135 +#include <linux/types.h> /* for __u32 in user space */
136  
137  /* ioctl()'s for the random number generator */
138  
139 @@ -32,6 +33,30 @@
140  /* Clear the entropy pool and associated counters.  (Superuser only.) */
141  #define RNDCLEARPOOL   _IO( 'R', 0x06 )
142  
143 +#ifdef CONFIG_FIPS_RNG
144 +
145 +/* Size of seed value - equal to AES blocksize */
146 +#define AES_BLOCK_SIZE_BYTES   16
147 +#define SEED_SIZE_BYTES                        AES_BLOCK_SIZE_BYTES
148 +/* Size of AES key */
149 +#define KEY_SIZE_BYTES         16
150 +
151 +/* ioctl() structure used by FIPS 140-2 Tests */
152 +struct rand_fips_test {
153 +       unsigned char key[KEY_SIZE_BYTES];                      /* Input */
154 +       unsigned char datetime[SEED_SIZE_BYTES];        /* Input */
155 +       unsigned char seed[SEED_SIZE_BYTES];            /* Input */
156 +       unsigned char result[SEED_SIZE_BYTES];          /* Output */
157 +};
158 +
159 +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
160 +#define RNDFIPSVST     _IOWR('R', 0x10, struct rand_fips_test)
161 +
162 +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
163 +#define RNDFIPSMCT     _IOWR('R', 0x11, struct rand_fips_test)
164 +
165 +#endif /* #ifdef CONFIG_FIPS_RNG */
166 +
167  struct rand_pool_info {
168         int     entropy_count;
169         int     buf_size;
170 @@ -48,6 +73,10 @@
171                                  unsigned int value);
172  extern void add_interrupt_randomness(int irq);
173  
174 +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
175 +extern int random_input_wait(void);
176 +#define HAS_RANDOM_INPUT_WAIT 1
177 +
178  extern void get_random_bytes(void *buf, int nbytes);
179  void generate_random_uuid(unsigned char uuid_out[16]);
180  
181 --- /dev/null
182 +++ b/crypto/ocf/hifn/Makefile
183 @@ -0,0 +1,13 @@
184 +# for SGlinux builds
185 +-include $(ROOTDIR)/modules/.config
186 +
187 +obj-$(CONFIG_OCF_HIFN)     += hifn7751.o
188 +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
189 +
190 +obj ?= .
191 +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
192 +
193 +ifdef TOPDIR
194 +-include $(TOPDIR)/Rules.make
195 +endif
196 +
197 --- /dev/null
198 +++ b/crypto/ocf/safe/Makefile
199 @@ -0,0 +1,12 @@
200 +# for SGlinux builds
201 +-include $(ROOTDIR)/modules/.config
202 +
203 +obj-$(CONFIG_OCF_SAFE) += safe.o
204 +
205 +obj ?= .
206 +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
207 +
208 +ifdef TOPDIR
209 +-include $(TOPDIR)/Rules.make
210 +endif
211 +
212 --- /dev/null
213 +++ b/crypto/ocf/Makefile
214 @@ -0,0 +1,120 @@
215 +# for SGlinux builds
216 +-include $(ROOTDIR)/modules/.config
217 +
218 +OCF_OBJS = crypto.o criov.o
219 +
220 +ifdef CONFIG_OCF_RANDOMHARVEST
221 +       OCF_OBJS += random.o
222 +endif
223 +
224 +ifdef CONFIG_OCF_FIPS
225 +       OCF_OBJS += rndtest.o
226 +endif
227 +
228 +# Add in autoconf.h to get #defines for CONFIG_xxx
229 +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
230 +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
231 +       EXTRA_CFLAGS += -include $(AUTOCONF_H)
232 +       export EXTRA_CFLAGS
233 +endif
234 +
235 +ifndef obj
236 +       obj ?= .
237 +       _obj = subdir
238 +       mod-subdirs := safe hifn ixp4xx talitos ocfnull
239 +       export-objs += crypto.o criov.o random.o
240 +       list-multi += ocf.o
241 +       _slash :=
242 +else
243 +       _obj = obj
244 +       _slash := /
245 +endif
246 +
247 +EXTRA_CFLAGS += -I$(obj)/.
248 +
249 +obj-$(CONFIG_OCF_OCF)         += ocf.o
250 +obj-$(CONFIG_OCF_CRYPTODEV)   += cryptodev.o
251 +obj-$(CONFIG_OCF_CRYPTOSOFT)  += cryptosoft.o
252 +obj-$(CONFIG_OCF_BENCH)       += ocf-bench.o
253 +
254 +$(_obj)-$(CONFIG_OCF_SAFE)    += safe$(_slash)
255 +$(_obj)-$(CONFIG_OCF_HIFN)    += hifn$(_slash)
256 +$(_obj)-$(CONFIG_OCF_IXP4XX)  += ixp4xx$(_slash)
257 +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
258 +$(_obj)-$(CONFIG_OCF_PASEMI)  += pasemi$(_slash)
259 +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
260 +
261 +ocf-objs := $(OCF_OBJS)
262 +
263 +$(list-multi) dummy1: $(ocf-objs)
264 +       $(LD) -r -o $@ $(ocf-objs)
265 +
266 +.PHONY:
267 +clean:
268 +       rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
269 +       rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
270 +
271 +ifdef TOPDIR
272 +-include $(TOPDIR)/Rules.make
273 +endif
274 +
275 +#
276 +# release gen targets
277 +#
278 +
279 +.PHONY: patch
280 +patch:
281 +       REL=`date +%Y%m%d`; \
282 +               patch=ocf-linux-$$REL.patch; \
283 +               patch24=ocf-linux-24-$$REL.patch; \
284 +               patch26=ocf-linux-26-$$REL.patch; \
285 +               ( \
286 +                       find . -name Makefile; \
287 +                       find . -name Config.in; \
288 +                       find . -name Kconfig; \
289 +                       find . -name README; \
290 +                       find . -name '*.[ch]' | grep -v '.mod.c'; \
291 +               ) | while read t; do \
292 +                       diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
293 +               done > $$patch; \
294 +               cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
295 +               cat patches/linux-2.6.25-ocf.patch $$patch > $$patch26
296 +
297 +.PHONY: tarball
298 +tarball:
299 +       REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
300 +               CURDIR=`pwd`; \
301 +               rm -rf /tmp/ocf-linux-$$REL*; \
302 +               mkdir -p $$RELDIR/tools; \
303 +               cp README* $$RELDIR; \
304 +               cp patches/openss*.patch $$RELDIR; \
305 +               cp patches/crypto-tools.patch $$RELDIR; \
306 +               cp tools/[!C]* $$RELDIR/tools; \
307 +               cd ..; \
308 +               tar cvf $$RELDIR/ocf-linux.tar \
309 +                                       --exclude=CVS \
310 +                                       --exclude=.* \
311 +                                       --exclude=*.o \
312 +                                       --exclude=*.ko \
313 +                                       --exclude=*.mod.* \
314 +                                       --exclude=README* \
315 +                                       --exclude=ocf-*.patch \
316 +                                       --exclude=ocf/patches/openss*.patch \
317 +                                       --exclude=ocf/patches/crypto-tools.patch \
318 +                                       --exclude=ocf/tools \
319 +                                       ocf; \
320 +               gzip -9 $$RELDIR/ocf-linux.tar; \
321 +               cd /tmp; \
322 +               tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
323 +               gzip -9 ocf-linux-$$REL.tar; \
324 +               cd $$CURDIR/../../user; \
325 +               rm -rf /tmp/crypto-tools-$$REL*; \
326 +               tar cvf /tmp/crypto-tools-$$REL.tar \
327 +                                       --exclude=CVS \
328 +                                       --exclude=.* \
329 +                                       --exclude=*.o \
330 +                                       --exclude=cryptotest \
331 +                                       --exclude=cryptokeytest \
332 +                                       crypto-tools; \
333 +               gzip -9 /tmp/crypto-tools-$$REL.tar
334 +
335 --- /dev/null
336 +++ b/crypto/ocf/talitos/Makefile
337 @@ -0,0 +1,12 @@
338 +# for SGlinux builds
339 +-include $(ROOTDIR)/modules/.config
340 +
341 +obj-$(CONFIG_OCF_TALITOS) += talitos.o
342 +
343 +obj ?= .
344 +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
345 +
346 +ifdef TOPDIR
347 +-include $(TOPDIR)/Rules.make
348 +endif
349 +
350 --- /dev/null
351 +++ b/crypto/ocf/ixp4xx/Makefile
352 @@ -0,0 +1,104 @@
353 +# for SGlinux builds
354 +-include $(ROOTDIR)/modules/.config
355 +
356 +#
357 +# You will need to point this at your Intel ixp425 includes,  this portion
358 +# of the Makefile only really works under SGLinux with the appropriate libs
359 +# installed.  They can be downloaded from http://www.snapgear.org/
360 +#
361 +ifeq ($(CONFIG_CPU_IXP46X),y)
362 +IXPLATFORM = ixp46X
363 +else
364 +ifeq ($(CONFIG_CPU_IXP43X),y)
365 +IXPLATFORM = ixp43X
366 +else
367 +IXPLATFORM = ixp42X
368 +endif
369 +endif
370 +
371 +ifdef CONFIG_IXP400_LIB_2_4
372 +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
373 +OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
374 +endif
375 +ifdef CONFIG_IXP400_LIB_2_1
376 +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
377 +OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
378 +endif
379 +ifdef CONFIG_IXP400_LIB_2_0
380 +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
381 +OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
382 +endif
383 +ifdef IX_XSCALE_SW
384 +ifdef CONFIG_IXP400_LIB_2_4
385 +IXP_CFLAGS = \
386 +       -I$(ROOTDIR)/. \
387 +       -I$(IX_XSCALE_SW)/src/include \
388 +       -I$(OSAL_DIR)/common/include/ \
389 +       -I$(OSAL_DIR)/common/include/modules/ \
390 +       -I$(OSAL_DIR)/common/include/modules/ddk/ \
391 +       -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
392 +       -I$(OSAL_DIR)/common/include/modules/ioMem/ \
393 +       -I$(OSAL_DIR)/common/os/linux/include/ \
394 +       -I$(OSAL_DIR)/common/os/linux/include/core/  \
395 +       -I$(OSAL_DIR)/common/os/linux/include/modules/ \
396 +       -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
397 +       -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
398 +       -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
399 +       -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
400 +       -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
401 +       -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
402 +       -DUSE_IXP4XX_CRYPTO
403 +else
404 +IXP_CFLAGS = \
405 +       -I$(ROOTDIR)/. \
406 +       -I$(IX_XSCALE_SW)/src/include \
407 +       -I$(OSAL_DIR)/ \
408 +       -I$(OSAL_DIR)/os/linux/include/ \
409 +       -I$(OSAL_DIR)/os/linux/include/modules/ \
410 +       -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
411 +       -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
412 +       -I$(OSAL_DIR)/os/linux/include/core/  \
413 +       -I$(OSAL_DIR)/os/linux/include/platforms/ \
414 +       -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
415 +       -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
416 +       -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
417 +       -I$(OSAL_DIR)/os/linux/include/core/ \
418 +       -I$(OSAL_DIR)/include/ \
419 +       -I$(OSAL_DIR)/include/modules/ \
420 +       -I$(OSAL_DIR)/include/modules/bufferMgt/ \
421 +       -I$(OSAL_DIR)/include/modules/ioMem/ \
422 +       -I$(OSAL_DIR)/include/platforms/ \
423 +       -I$(OSAL_DIR)/include/platforms/ixp400/ \
424 +       -DUSE_IXP4XX_CRYPTO
425 +endif
426 +endif
427 +ifdef CONFIG_IXP400_LIB_1_4
428 +IXP_CFLAGS   = \
429 +       -I$(ROOTDIR)/. \
430 +       -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
431 +       -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
432 +       -DUSE_IXP4XX_CRYPTO
433 +endif
434 +ifndef IXPDIR
435 +IXPDIR = ixp-version-is-not-supported
436 +endif
437 +
438 +ifeq ($(CONFIG_CPU_IXP46X),y)
439 +IXP_CFLAGS += -D__ixp46X
440 +else
441 +ifeq ($(CONFIG_CPU_IXP43X),y)
442 +IXP_CFLAGS += -D__ixp43X
443 +else
444 +IXP_CFLAGS += -D__ixp42X
445 +endif
446 +endif
447 +
448 +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
449 +
450 +obj ?= .
451 +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
452 +
453 +ifdef TOPDIR
454 +-include $(TOPDIR)/Rules.make
455 +endif
456 +
457 --- /dev/null
458 +++ b/crypto/ocf/ocfnull/Makefile
459 @@ -0,0 +1,12 @@
460 +# for SGlinux builds
461 +-include $(ROOTDIR)/modules/.config
462 +
463 +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
464 +
465 +obj ?= .
466 +EXTRA_CFLAGS += -I$(obj)/..
467 +
468 +ifdef TOPDIR
469 +-include $(TOPDIR)/Rules.make
470 +endif
471 +
472 --- /dev/null
473 +++ b/crypto/ocf/pasemi/Makefile
474 @@ -0,0 +1,12 @@
475 +# for SGlinux builds
476 +-include $(ROOTDIR)/modules/.config
477 +
478 +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
479 +
480 +obj ?= .
481 +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
482 +
483 +ifdef TOPDIR
484 +-include $(TOPDIR)/Rules.make
485 +endif
486 +
487 --- /dev/null
488 +++ b/crypto/ocf/Config.in
489 @@ -0,0 +1,32 @@
490 +#############################################################################
491 +
492 +mainmenu_option next_comment
493 +comment 'OCF Configuration'
494 +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
495 +dep_mbool '  enable fips RNG checks (fips check on RNG data before use)' \
496 +                               CONFIG_OCF_FIPS $CONFIG_OCF_OCF
497 +dep_mbool '  enable harvesting entropy for /dev/random' \
498 +                               CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
499 +dep_tristate '  cryptodev (user space support)' \
500 +                               CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
501 +dep_tristate '  cryptosoft (software crypto engine)' \
502 +                               CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
503 +dep_tristate '  safenet (HW crypto engine)' \
504 +                               CONFIG_OCF_SAFE $CONFIG_OCF_OCF
505 +dep_tristate '  IXP4xx (HW crypto engine)' \
506 +                               CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
507 +dep_mbool    '  Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
508 +                               CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
509 +dep_tristate '  hifn (HW crypto engine)' \
510 +                               CONFIG_OCF_HIFN $CONFIG_OCF_OCF
511 +dep_tristate '  talitos (HW crypto engine)' \
512 +                               CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
513 +dep_tristate '  pasemi (HW crypto engine)' \
514 +                               CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
515 +dep_tristate '  ocfnull (does no crypto)' \
516 +                               CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
517 +dep_tristate '  ocf-bench (HW crypto in-kernel benchmark)' \
518 +                               CONFIG_OCF_BENCH $CONFIG_OCF_OCF
519 +endmenu
520 +
521 +#############################################################################
522 --- /dev/null
523 +++ b/crypto/ocf/Kconfig
524 @@ -0,0 +1,95 @@
525 +menu "OCF Configuration"
526 +
527 +config OCF_OCF
528 +       tristate "OCF (Open Cryptograhic Framework)"
529 +       help
530 +         A linux port of the OpenBSD/FreeBSD crypto framework.
531 +
532 +config OCF_RANDOMHARVEST
533 +       bool "crypto random --- harvest entropy for /dev/random"
534 +       depends on OCF_OCF
535 +       help
536 +         Includes code to harvest random numbers from devices that support it.
537 +
538 +config OCF_FIPS
539 +       bool "enable fips RNG checks"
540 +       depends on OCF_OCF && OCF_RANDOMHARVEST
541 +       help
542 +         Run all RNG provided data through a fips check before
543 +         adding it /dev/random's entropy pool.
544 +
545 +config OCF_CRYPTODEV
546 +       tristate "cryptodev (user space support)"
547 +       depends on OCF_OCF
548 +       help
549 +         The user space API to access crypto hardware.
550 +
551 +config OCF_CRYPTOSOFT
552 +       tristate "cryptosoft (software crypto engine)"
553 +       depends on OCF_OCF
554 +       help
555 +         A software driver for the OCF framework that uses
556 +         the kernel CryptoAPI.
557 +
558 +config OCF_SAFE
559 +       tristate "safenet (HW crypto engine)"
560 +       depends on OCF_OCF
561 +       help
562 +         A driver for a number of the safenet Excel crypto accelerators.
563 +         Currently tested and working on the 1141 and 1741.
564 +
565 +config OCF_IXP4XX
566 +       tristate "IXP4xx (HW crypto engine)"
567 +       depends on OCF_OCF
568 +       help
569 +         XScale IXP4xx crypto accelerator driver.  Requires the
570 +         Intel Access library.
571 +
572 +config OCF_IXP4XX_SHA1_MD5
573 +       bool "IXP4xx SHA1 and MD5 Hashing"
574 +       depends on OCF_IXP4XX
575 +       help
576 +         Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
577 +         Note: this is MUCH slower than using cryptosoft (software crypto engine).
578 +
579 +config OCF_HIFN
580 +       tristate "hifn (HW crypto engine)"
581 +       depends on OCF_OCF
582 +       help
583 +         OCF driver for various HIFN based crypto accelerators.
584 +         (7951, 7955, 7956, 7751, 7811)
585 +
586 +config OCF_HIFNHIPP
587 +       tristate "Hifn HIPP (HW packet crypto engine)"
588 +       depends on OCF_OCF
589 +       help
590 +         OCF driver for various HIFN (HIPP) based crypto accelerators
591 +         (7855)
592 +
593 +config OCF_TALITOS
594 +       tristate "talitos (HW crypto engine)"
595 +       depends on OCF_OCF
596 +       help
597 +         OCF driver for Freescale's security engine (SEC/talitos).
598 +
599 +config OCF_PASEMI
600 +        tristate "pasemi (HW crypto engine)"
601 +        depends on OCF_OCF && PPC_PASEMI
602 +        help
603 +          OCF driver for for PA Semi PWRficient DMA Engine
604 +
605 +config OCF_OCFNULL
606 +       tristate "ocfnull (fake crypto engine)"
607 +       depends on OCF_OCF
608 +       help
609 +         OCF driver for measuring ipsec overheads (does no crypto)
610 +
611 +config OCF_BENCH
612 +       tristate "ocf-bench (HW crypto in-kernel benchmark)"
613 +       depends on OCF_OCF
614 +       help
615 +         A very simple encryption test for the in-kernel interface
616 +         of OCF.  Also includes code to benchmark the IXP Access library
617 +         for comparison.
618 +
619 +endmenu
620 --- /dev/null
621 +++ b/crypto/ocf/README
622 @@ -0,0 +1,166 @@
623 +README - ocf-linux-20071215
624 +---------------------------
625 +
626 +This README provides instructions for getting ocf-linux compiled and
627 +operating in a generic linux environment.  For other information you
628 +might like to visit the home page for this project:
629 +
630 +    http://ocf-linux.sourceforge.net/
631 +
632 +Adding OCF to linux
633 +-------------------
634 +
635 +    Not much in this file for now,  just some notes.  I usually build
636 +    the ocf support as modules but it can be built into the kernel as
637 +    well.  To use it:
638 +
639 +    * mknod /dev/crypto c 10 70
640 +
641 +    * to add OCF to your kernel source,  you have two options.  Apply
642 +      the kernel specific patch:
643 +
644 +          cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
645 +          cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
646 +
647 +      if you do one of the above,  then you can proceed to the next step,
648 +      or you can do the above process by hand with using the patches against
649 +      linux-2.4.35 and 2.6.23 to include the ocf code under crypto/ocf.
650 +      Here's how to add it:
651 +
652 +      for 2.4.35 (and later)
653 +
654 +          cd linux-2.4.35/crypto
655 +          tar xvzf ocf-linux.tar.gz
656 +          cd ..
657 +          patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
658 +
659 +      for 2.6.23 (and later)
660 +
661 +          cd linux-2.6.23/crypto
662 +          tar xvzf ocf-linux.tar.gz
663 +          cd ..
664 +          patch -p1 < crypto/ocf/patches/linux-2.6.23-ocf.patch
665 +
666 +      It should be easy to take this patch and apply it to other more
667 +      recent versions of the kernels.  The same patches should also work
668 +      relatively easily on kernels as old as 2.6.11 and 2.4.18.
669 +
670 +    * under 2.4 if you are on a non-x86 platform,  you may need to:
671 +
672 +        cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
673 +
674 +      so that you can build the kernel crypto support needed for the cryptosoft
675 +      driver.
676 +
677 +    * For simplicity you should enable all the crypto support in your kernel
678 +      except for the test driver.  Likewise for the OCF options.  Do not
679 +      enable OCF crypto drivers for HW that you do not have (for example
680 +      ixp4xx will not compile on non-Xscale systems).
681 +
682 +    * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
683 +      crypto/cryptodev.h in an include directory that is used for building
684 +      applications for your platform.  For example on a host system that
685 +      might be:
686 +
687 +              /usr/include/crypto/cryptodev.h
688 +
689 +    * patch your openssl-0.9.8g code with the openssl-0.9.8g.patch.
690 +      (NOTE: there is no longer a need to patch ssh). The patch is against:
691 +      openssl-0_9_8e
692 +
693 +      If you need a patch for an older version of openssl,  you should look
694 +      to older OCF releases.  This patch is unlikely to work on older
695 +      openssl versions.
696 +
697 +      openssl-0.9.8g.patch
698 +                - enables --with-cryptodev for non BSD systems
699 +                - adds -cpu option to openssl speed for calculating CPU load
700 +                  under linux
701 +                - fixes null pointer in openssl speed multi thread output.
702 +                - fixes test keys to work with linux crypto's more stringent
703 +                  key checking.
704 +                - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
705 +                  with the --with-cryptodev-digests option
706 +                - fixes bug in engine code caching.
707 +
708 +    * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
709 +      tools for testing OCF (ie., cryptotest).
710 +
711 +How to load the OCF drivers
712 +---------------------------
713 +
714 +    First insert the base modules:
715 +
716 +        insmod ocf
717 +        insmod cryptodev
718 +
719 +    You can then install the software OCF driver with:
720 +
721 +        insmod cryptosoft
722 +
723 +    and one or more of the OCF HW drivers with:
724 +
725 +        insmod safe
726 +        insmod hifn7751
727 +        insmod ixp4xx
728 +        ...
729 +
730 +    all the drivers take a debug option to enable verbose debug so that
731 +    you can see what is going on.  For debug you load them as:
732 +
733 +        insmod ocf crypto_debug=1
734 +        insmod cryptodev cryptodev_debug=1
735 +        insmod cryptosoft swcr_debug=1
736 +
737 +    You may load more than one OCF crypto driver but then there is no guarantee
738 +    as to which will be used.
739 +
740 +    You can also enable debug at run time on 2.6 systems with the following:
741 +
742 +        echo 1 > /sys/module/ocf/parameters/crypto_debug
743 +        echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
744 +        echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
745 +        echo 1 > /sys/module/hifn7751/parameters/hifn_debug
746 +        echo 1 > /sys/module/safe/parameters/safe_debug
747 +        echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
748 +        ...
749 +
750 +Testing the OCF support
751 +-----------------------
752 +
753 +    run "cryptotest",  it should do a short test for a couple of
754 +    des packets.  If it does everything is working.
755 +
756 +    If this works,  then ssh will use the driver when invoked as:
757 +
758 +        ssh -c 3des username@host
759 +
760 +    to see for sure that it is operating, enable debug as defined above.
761 +
762 +    To get a better idea of performance run:
763 +
764 +        cryptotest 100 4096
765 +
766 +    There are more options to cryptotest,  see the help.
767 +
768 +    It is also possible to use openssl to test the speed of the crypto
769 +    drivers.
770 +
771 +        openssl speed -evp des -engine cryptodev -elapsed
772 +        openssl speed -evp des3 -engine cryptodev -elapsed
773 +        openssl speed -evp aes128 -engine cryptodev -elapsed
774 +
775 +    and multiple threads (10) with:
776 +
777 +        openssl speed -evp des -engine cryptodev -elapsed -multi 10
778 +        openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
779 +        openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
780 +
781 +    for public key testing you can try:
782 +
783 +        cryptokeytest
784 +        openssl speed -engine cryptodev rsa -elapsed
785 +        openssl speed -engine cryptodev dsa -elapsed
786 +
787 +David McCullough
788 +david_mccullough@securecomputing.com
789 --- /dev/null
790 +++ b/crypto/ocf/hifn/hifn7751reg.h
791 @@ -0,0 +1,540 @@
792 +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
793 +/*     $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $  */
794 +
795 +/*-
796 + * Invertex AEON / Hifn 7751 driver
797 + * Copyright (c) 1999 Invertex Inc. All rights reserved.
798 + * Copyright (c) 1999 Theo de Raadt
799 + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
800 + *                     http://www.netsec.net
801 + *
802 + * Please send any comments, feedback, bug-fixes, or feature requests to
803 + * software@invertex.com.
804 + *
805 + * Redistribution and use in source and binary forms, with or without
806 + * modification, are permitted provided that the following conditions
807 + * are met:
808 + *
809 + * 1. Redistributions of source code must retain the above copyright
810 + *    notice, this list of conditions and the following disclaimer.
811 + * 2. Redistributions in binary form must reproduce the above copyright
812 + *    notice, this list of conditions and the following disclaimer in the
813 + *    documentation and/or other materials provided with the distribution.
814 + * 3. The name of the author may not be used to endorse or promote products
815 + *    derived from this software without specific prior written permission.
816 + *
817 + *
818 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
819 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
820 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
821 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
822 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
823 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
824 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
825 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
826 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
827 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
828 + *
829 + * Effort sponsored in part by the Defense Advanced Research Projects
830 + * Agency (DARPA) and Air Force Research Laboratory, Air Force
831 + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
832 + *
833 + */
834 +#ifndef __HIFN_H__
835 +#define        __HIFN_H__
836 +
837 +/*
838 + * Some PCI configuration space offset defines.  The names were made
839 + * identical to the names used by the Linux kernel.
840 + */
841 +#define        HIFN_BAR0               PCIR_BAR(0)     /* PUC register map */
842 +#define        HIFN_BAR1               PCIR_BAR(1)     /* DMA register map */
843 +#define        HIFN_TRDY_TIMEOUT       0x40
844 +#define        HIFN_RETRY_TIMEOUT      0x41
845 +
846 +/*
847 + * PCI vendor and device identifiers
848 + * (the names are preserved from their OpenBSD source).
849 + */
850 +#define        PCI_VENDOR_HIFN         0x13a3          /* Hifn */
851 +#define        PCI_PRODUCT_HIFN_7751   0x0005          /* 7751 */
852 +#define        PCI_PRODUCT_HIFN_6500   0x0006          /* 6500 */
853 +#define        PCI_PRODUCT_HIFN_7811   0x0007          /* 7811 */
854 +#define        PCI_PRODUCT_HIFN_7855   0x001f          /* 7855 */
855 +#define        PCI_PRODUCT_HIFN_7951   0x0012          /* 7951 */
856 +#define        PCI_PRODUCT_HIFN_7955   0x0020          /* 7954/7955 */
857 +#define        PCI_PRODUCT_HIFN_7956   0x001d          /* 7956 */
858 +
859 +#define        PCI_VENDOR_INVERTEX     0x14e1          /* Invertex */
860 +#define        PCI_PRODUCT_INVERTEX_AEON 0x0005        /* AEON */
861 +
862 +#define        PCI_VENDOR_NETSEC       0x1660          /* NetSec */
863 +#define        PCI_PRODUCT_NETSEC_7751 0x7751          /* 7751 */
864 +
865 +/*
866 + * The values below should multiple of 4 -- and be large enough to handle
867 + * any command the driver implements.
868 + *
869 + * MAX_COMMAND = base command + mac command + encrypt command +
870 + *                     mac-key + rc4-key
871 + * MAX_RESULT  = base result + mac result + mac + encrypt result
872 + *
873 + *
874 + */
875 +#define        HIFN_MAX_COMMAND        (8 + 8 + 8 + 64 + 260)
876 +#define        HIFN_MAX_RESULT         (8 + 4 + 20 + 4)
877 +
878 +/*
879 + * hifn_desc_t
880 + *
881 + * Holds an individual descriptor for any of the rings.
882 + */
883 +typedef struct hifn_desc {
884 +       volatile u_int32_t l;           /* length and status bits */
885 +       volatile u_int32_t p;
886 +} hifn_desc_t;
887 +
888 +/*
889 + * Masks for the "length" field of struct hifn_desc.
890 + */
891 +#define        HIFN_D_LENGTH           0x0000ffff      /* length bit mask */
892 +#define        HIFN_D_MASKDONEIRQ      0x02000000      /* mask the done interrupt */
893 +#define        HIFN_D_DESTOVER         0x04000000      /* destination overflow */
894 +#define        HIFN_D_OVER             0x08000000      /* overflow */
895 +#define        HIFN_D_LAST             0x20000000      /* last descriptor in chain */
896 +#define        HIFN_D_JUMP             0x40000000      /* jump descriptor */
897 +#define        HIFN_D_VALID            0x80000000      /* valid bit */
898 +
899 +
900 +/*
901 + * Processing Unit Registers (offset from BASEREG0)
902 + */
903 +#define        HIFN_0_PUDATA           0x00    /* Processing Unit Data */
904 +#define        HIFN_0_PUCTRL           0x04    /* Processing Unit Control */
905 +#define        HIFN_0_PUISR            0x08    /* Processing Unit Interrupt Status */
906 +#define        HIFN_0_PUCNFG           0x0c    /* Processing Unit Configuration */
907 +#define        HIFN_0_PUIER            0x10    /* Processing Unit Interrupt Enable */
908 +#define        HIFN_0_PUSTAT           0x14    /* Processing Unit Status/Chip ID */
909 +#define        HIFN_0_FIFOSTAT         0x18    /* FIFO Status */
910 +#define        HIFN_0_FIFOCNFG         0x1c    /* FIFO Configuration */
911 +#define        HIFN_0_PUCTRL2          0x28    /* Processing Unit Control (2nd map) */
912 +#define        HIFN_0_MUTE1            0x80
913 +#define        HIFN_0_MUTE2            0x90
914 +#define        HIFN_0_SPACESIZE        0x100   /* Register space size */
915 +
916 +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
917 +#define        HIFN_PUCTRL_CLRSRCFIFO  0x0010  /* clear source fifo */
918 +#define        HIFN_PUCTRL_STOP        0x0008  /* stop pu */
919 +#define        HIFN_PUCTRL_LOCKRAM     0x0004  /* lock ram */
920 +#define        HIFN_PUCTRL_DMAENA      0x0002  /* enable dma */
921 +#define        HIFN_PUCTRL_RESET       0x0001  /* Reset processing unit */
922 +
923 +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
924 +#define        HIFN_PUISR_CMDINVAL     0x8000  /* Invalid command interrupt */
925 +#define        HIFN_PUISR_DATAERR      0x4000  /* Data error interrupt */
926 +#define        HIFN_PUISR_SRCFIFO      0x2000  /* Source FIFO ready interrupt */
927 +#define        HIFN_PUISR_DSTFIFO      0x1000  /* Destination FIFO ready interrupt */
928 +#define        HIFN_PUISR_DSTOVER      0x0200  /* Destination overrun interrupt */
929 +#define        HIFN_PUISR_SRCCMD       0x0080  /* Source command interrupt */
930 +#define        HIFN_PUISR_SRCCTX       0x0040  /* Source context interrupt */
931 +#define        HIFN_PUISR_SRCDATA      0x0020  /* Source data interrupt */
932 +#define        HIFN_PUISR_DSTDATA      0x0010  /* Destination data interrupt */
933 +#define        HIFN_PUISR_DSTRESULT    0x0004  /* Destination result interrupt */
934 +
935 +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
936 +#define        HIFN_PUCNFG_DRAMMASK    0xe000  /* DRAM size mask */
937 +#define        HIFN_PUCNFG_DSZ_256K    0x0000  /* 256k dram */
938 +#define        HIFN_PUCNFG_DSZ_512K    0x2000  /* 512k dram */
939 +#define        HIFN_PUCNFG_DSZ_1M      0x4000  /* 1m dram */
940 +#define        HIFN_PUCNFG_DSZ_2M      0x6000  /* 2m dram */
941 +#define        HIFN_PUCNFG_DSZ_4M      0x8000  /* 4m dram */
942 +#define        HIFN_PUCNFG_DSZ_8M      0xa000  /* 8m dram */
943 +#define        HIFN_PUNCFG_DSZ_16M     0xc000  /* 16m dram */
944 +#define        HIFN_PUCNFG_DSZ_32M     0xe000  /* 32m dram */
945 +#define        HIFN_PUCNFG_DRAMREFRESH 0x1800  /* DRAM refresh rate mask */
946 +#define        HIFN_PUCNFG_DRFR_512    0x0000  /* 512 divisor of ECLK */
947 +#define        HIFN_PUCNFG_DRFR_256    0x0800  /* 256 divisor of ECLK */
948 +#define        HIFN_PUCNFG_DRFR_128    0x1000  /* 128 divisor of ECLK */
949 +#define        HIFN_PUCNFG_TCALLPHASES 0x0200  /* your guess is as good as mine... */
950 +#define        HIFN_PUCNFG_TCDRVTOTEM  0x0100  /* your guess is as good as mine... */
951 +#define        HIFN_PUCNFG_BIGENDIAN   0x0080  /* DMA big endian mode */
952 +#define        HIFN_PUCNFG_BUS32       0x0040  /* Bus width 32bits */
953 +#define        HIFN_PUCNFG_BUS16       0x0000  /* Bus width 16 bits */
954 +#define        HIFN_PUCNFG_CHIPID      0x0020  /* Allow chipid from PUSTAT */
955 +#define        HIFN_PUCNFG_DRAM        0x0010  /* Context RAM is DRAM */
956 +#define        HIFN_PUCNFG_SRAM        0x0000  /* Context RAM is SRAM */
957 +#define        HIFN_PUCNFG_COMPSING    0x0004  /* Enable single compression context */
958 +#define        HIFN_PUCNFG_ENCCNFG     0x0002  /* Encryption configuration */
959 +
960 +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
961 +#define        HIFN_PUIER_CMDINVAL     0x8000  /* Invalid command interrupt */
962 +#define        HIFN_PUIER_DATAERR      0x4000  /* Data error interrupt */
963 +#define        HIFN_PUIER_SRCFIFO      0x2000  /* Source FIFO ready interrupt */
964 +#define        HIFN_PUIER_DSTFIFO      0x1000  /* Destination FIFO ready interrupt */
965 +#define        HIFN_PUIER_DSTOVER      0x0200  /* Destination overrun interrupt */
966 +#define        HIFN_PUIER_SRCCMD       0x0080  /* Source command interrupt */
967 +#define        HIFN_PUIER_SRCCTX       0x0040  /* Source context interrupt */
968 +#define        HIFN_PUIER_SRCDATA      0x0020  /* Source data interrupt */
969 +#define        HIFN_PUIER_DSTDATA      0x0010  /* Destination data interrupt */
970 +#define        HIFN_PUIER_DSTRESULT    0x0004  /* Destination result interrupt */
971 +
972 +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
973 +#define        HIFN_PUSTAT_CMDINVAL    0x8000  /* Invalid command interrupt */
974 +#define        HIFN_PUSTAT_DATAERR     0x4000  /* Data error interrupt */
975 +#define        HIFN_PUSTAT_SRCFIFO     0x2000  /* Source FIFO ready interrupt */
976 +#define        HIFN_PUSTAT_DSTFIFO     0x1000  /* Destination FIFO ready interrupt */
977 +#define        HIFN_PUSTAT_DSTOVER     0x0200  /* Destination overrun interrupt */
978 +#define        HIFN_PUSTAT_SRCCMD      0x0080  /* Source command interrupt */
979 +#define        HIFN_PUSTAT_SRCCTX      0x0040  /* Source context interrupt */
980 +#define        HIFN_PUSTAT_SRCDATA     0x0020  /* Source data interrupt */
981 +#define        HIFN_PUSTAT_DSTDATA     0x0010  /* Destination data interrupt */
982 +#define        HIFN_PUSTAT_DSTRESULT   0x0004  /* Destination result interrupt */
983 +#define        HIFN_PUSTAT_CHIPREV     0x00ff  /* Chip revision mask */
984 +#define        HIFN_PUSTAT_CHIPENA     0xff00  /* Chip enabled mask */
985 +#define        HIFN_PUSTAT_ENA_2       0x1100  /* Level 2 enabled */
986 +#define        HIFN_PUSTAT_ENA_1       0x1000  /* Level 1 enabled */
987 +#define        HIFN_PUSTAT_ENA_0       0x3000  /* Level 0 enabled */
988 +#define        HIFN_PUSTAT_REV_2       0x0020  /* 7751 PT6/2 */
989 +#define        HIFN_PUSTAT_REV_3       0x0030  /* 7751 PT6/3 */
990 +
991 +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
992 +#define        HIFN_FIFOSTAT_SRC       0x7f00  /* Source FIFO available */
993 +#define        HIFN_FIFOSTAT_DST       0x007f  /* Destination FIFO available */
994 +
995 +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
996 +#define        HIFN_FIFOCNFG_THRESHOLD 0x0400  /* must be written as this value */
997 +
998 +/*
999 + * DMA Interface Registers (offset from BASEREG1)
1000 + */
1001 +#define        HIFN_1_DMA_CRAR         0x0c    /* DMA Command Ring Address */
1002 +#define        HIFN_1_DMA_SRAR         0x1c    /* DMA Source Ring Address */
1003 +#define        HIFN_1_DMA_RRAR         0x2c    /* DMA Result Ring Address */
1004 +#define        HIFN_1_DMA_DRAR         0x3c    /* DMA Destination Ring Address */
1005 +#define        HIFN_1_DMA_CSR          0x40    /* DMA Status and Control */
1006 +#define        HIFN_1_DMA_IER          0x44    /* DMA Interrupt Enable */
1007 +#define        HIFN_1_DMA_CNFG         0x48    /* DMA Configuration */
1008 +#define        HIFN_1_PLL              0x4c    /* 7955/7956: PLL config */
1009 +#define        HIFN_1_7811_RNGENA      0x60    /* 7811: rng enable */
1010 +#define        HIFN_1_7811_RNGCFG      0x64    /* 7811: rng config */
1011 +#define        HIFN_1_7811_RNGDAT      0x68    /* 7811: rng data */
1012 +#define        HIFN_1_7811_RNGSTS      0x6c    /* 7811: rng status */
1013 +#define        HIFN_1_DMA_CNFG2        0x6c    /* 7955/7956: dma config #2 */
1014 +#define        HIFN_1_7811_MIPSRST     0x94    /* 7811: MIPS reset */
1015 +#define        HIFN_1_REVID            0x98    /* Revision ID */
1016 +
1017 +#define        HIFN_1_PUB_RESET        0x204   /* Public/RNG Reset */
1018 +#define        HIFN_1_PUB_BASE         0x300   /* Public Base Address */
1019 +#define        HIFN_1_PUB_OPLEN        0x304   /* 7951-compat Public Operand Length */
1020 +#define        HIFN_1_PUB_OP           0x308   /* 7951-compat Public Operand */
1021 +#define        HIFN_1_PUB_STATUS       0x30c   /* 7951-compat Public Status */
1022 +#define        HIFN_1_PUB_IEN          0x310   /* Public Interrupt enable */
1023 +#define        HIFN_1_RNG_CONFIG       0x314   /* RNG config */
1024 +#define        HIFN_1_RNG_DATA         0x318   /* RNG data */
1025 +#define        HIFN_1_PUB_MODE         0x320   /* PK mode */
1026 +#define        HIFN_1_PUB_FIFO_OPLEN   0x380   /* first element of oplen fifo */
1027 +#define        HIFN_1_PUB_FIFO_OP      0x384   /* first element of op fifo */
1028 +#define        HIFN_1_PUB_MEM          0x400   /* start of Public key memory */
1029 +#define        HIFN_1_PUB_MEMEND       0xbff   /* end of Public key memory */
1030 +
1031 +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
1032 +#define        HIFN_DMACSR_D_CTRLMASK  0xc0000000      /* Destinition Ring Control */
1033 +#define        HIFN_DMACSR_D_CTRL_NOP  0x00000000      /* Dest. Control: no-op */
1034 +#define        HIFN_DMACSR_D_CTRL_DIS  0x40000000      /* Dest. Control: disable */
1035 +#define        HIFN_DMACSR_D_CTRL_ENA  0x80000000      /* Dest. Control: enable */
1036 +#define        HIFN_DMACSR_D_ABORT     0x20000000      /* Destinition Ring PCIAbort */
1037 +#define        HIFN_DMACSR_D_DONE      0x10000000      /* Destinition Ring Done */
1038 +#define        HIFN_DMACSR_D_LAST      0x08000000      /* Destinition Ring Last */
1039 +#define        HIFN_DMACSR_D_WAIT      0x04000000      /* Destinition Ring Waiting */
1040 +#define        HIFN_DMACSR_D_OVER      0x02000000      /* Destinition Ring Overflow */
1041 +#define        HIFN_DMACSR_R_CTRL      0x00c00000      /* Result Ring Control */
1042 +#define        HIFN_DMACSR_R_CTRL_NOP  0x00000000      /* Result Control: no-op */
1043 +#define        HIFN_DMACSR_R_CTRL_DIS  0x00400000      /* Result Control: disable */
1044 +#define        HIFN_DMACSR_R_CTRL_ENA  0x00800000      /* Result Control: enable */
1045 +#define        HIFN_DMACSR_R_ABORT     0x00200000      /* Result Ring PCI Abort */
1046 +#define        HIFN_DMACSR_R_DONE      0x00100000      /* Result Ring Done */
1047 +#define        HIFN_DMACSR_R_LAST      0x00080000      /* Result Ring Last */
1048 +#define        HIFN_DMACSR_R_WAIT      0x00040000      /* Result Ring Waiting */
1049 +#define        HIFN_DMACSR_R_OVER      0x00020000      /* Result Ring Overflow */
1050 +#define        HIFN_DMACSR_S_CTRL      0x0000c000      /* Source Ring Control */
1051 +#define        HIFN_DMACSR_S_CTRL_NOP  0x00000000      /* Source Control: no-op */
1052 +#define        HIFN_DMACSR_S_CTRL_DIS  0x00004000      /* Source Control: disable */
1053 +#define        HIFN_DMACSR_S_CTRL_ENA  0x00008000      /* Source Control: enable */
1054 +#define        HIFN_DMACSR_S_ABORT     0x00002000      /* Source Ring PCI Abort */
1055 +#define        HIFN_DMACSR_S_DONE      0x00001000      /* Source Ring Done */
1056 +#define        HIFN_DMACSR_S_LAST      0x00000800      /* Source Ring Last */
1057 +#define        HIFN_DMACSR_S_WAIT      0x00000400      /* Source Ring Waiting */
1058 +#define        HIFN_DMACSR_ILLW        0x00000200      /* Illegal write (7811 only) */
1059 +#define        HIFN_DMACSR_ILLR        0x00000100      /* Illegal read (7811 only) */
1060 +#define        HIFN_DMACSR_C_CTRL      0x000000c0      /* Command Ring Control */
1061 +#define        HIFN_DMACSR_C_CTRL_NOP  0x00000000      /* Command Control: no-op */
1062 +#define        HIFN_DMACSR_C_CTRL_DIS  0x00000040      /* Command Control: disable */
1063 +#define        HIFN_DMACSR_C_CTRL_ENA  0x00000080      /* Command Control: enable */
1064 +#define        HIFN_DMACSR_C_ABORT     0x00000020      /* Command Ring PCI Abort */
1065 +#define        HIFN_DMACSR_C_DONE      0x00000010      /* Command Ring Done */
1066 +#define        HIFN_DMACSR_C_LAST      0x00000008      /* Command Ring Last */
1067 +#define        HIFN_DMACSR_C_WAIT      0x00000004      /* Command Ring Waiting */
1068 +#define        HIFN_DMACSR_PUBDONE     0x00000002      /* Public op done (7951 only) */
1069 +#define        HIFN_DMACSR_ENGINE      0x00000001      /* Command Ring Engine IRQ */
1070 +
1071 +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
1072 +#define        HIFN_DMAIER_D_ABORT     0x20000000      /* Destination Ring PCIAbort */
1073 +#define        HIFN_DMAIER_D_DONE      0x10000000      /* Destination Ring Done */
1074 +#define        HIFN_DMAIER_D_LAST      0x08000000      /* Destination Ring Last */
1075 +#define        HIFN_DMAIER_D_WAIT      0x04000000      /* Destination Ring Waiting */
1076 +#define        HIFN_DMAIER_D_OVER      0x02000000      /* Destination Ring Overflow */
1077 +#define        HIFN_DMAIER_R_ABORT     0x00200000      /* Result Ring PCI Abort */
1078 +#define        HIFN_DMAIER_R_DONE      0x00100000      /* Result Ring Done */
1079 +#define        HIFN_DMAIER_R_LAST      0x00080000      /* Result Ring Last */
1080 +#define        HIFN_DMAIER_R_WAIT      0x00040000      /* Result Ring Waiting */
1081 +#define        HIFN_DMAIER_R_OVER      0x00020000      /* Result Ring Overflow */
1082 +#define        HIFN_DMAIER_S_ABORT     0x00002000      /* Source Ring PCI Abort */
1083 +#define        HIFN_DMAIER_S_DONE      0x00001000      /* Source Ring Done */
1084 +#define        HIFN_DMAIER_S_LAST      0x00000800      /* Source Ring Last */
1085 +#define        HIFN_DMAIER_S_WAIT      0x00000400      /* Source Ring Waiting */
1086 +#define        HIFN_DMAIER_ILLW        0x00000200      /* Illegal write (7811 only) */
1087 +#define        HIFN_DMAIER_ILLR        0x00000100      /* Illegal read (7811 only) */
1088 +#define        HIFN_DMAIER_C_ABORT     0x00000020      /* Command Ring PCI Abort */
1089 +#define        HIFN_DMAIER_C_DONE      0x00000010      /* Command Ring Done */
1090 +#define        HIFN_DMAIER_C_LAST      0x00000008      /* Command Ring Last */
1091 +#define        HIFN_DMAIER_C_WAIT      0x00000004      /* Command Ring Waiting */
1092 +#define        HIFN_DMAIER_PUBDONE     0x00000002      /* public op done (7951 only) */
1093 +#define        HIFN_DMAIER_ENGINE      0x00000001      /* Engine IRQ */
1094 +
1095 +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
1096 +#define        HIFN_DMACNFG_BIGENDIAN  0x10000000      /* big endian mode */
1097 +#define        HIFN_DMACNFG_POLLFREQ   0x00ff0000      /* Poll frequency mask */
1098 +#define        HIFN_DMACNFG_UNLOCK     0x00000800
1099 +#define        HIFN_DMACNFG_POLLINVAL  0x00000700      /* Invalid Poll Scalar */
1100 +#define        HIFN_DMACNFG_LAST       0x00000010      /* Host control LAST bit */
1101 +#define        HIFN_DMACNFG_MODE       0x00000004      /* DMA mode */
1102 +#define        HIFN_DMACNFG_DMARESET   0x00000002      /* DMA Reset # */
1103 +#define        HIFN_DMACNFG_MSTRESET   0x00000001      /* Master Reset # */
1104 +
1105 +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
1106 +#define        HIFN_DMACNFG2_PKSWAP32  (1 << 19)       /* swap the OPLEN/OP reg */
1107 +#define        HIFN_DMACNFG2_PKSWAP8   (1 << 18)       /* swap the bits of OPLEN/OP */
1108 +#define        HIFN_DMACNFG2_BAR0_SWAP32 (1<<17)       /* swap the bytes of BAR0 */
1109 +#define        HIFN_DMACNFG2_BAR1_SWAP8 (1<<16)        /* swap the bits  of BAR0 */
1110 +#define        HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
1111 +#define        HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
1112 +#define        HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
1113 +#define        HIFN_DMACNFG2_TGT_READ_BURST_SHIFT  0
1114 +
1115 +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
1116 +#define        HIFN_7811_RNGENA_ENA    0x00000001      /* enable RNG */
1117 +
1118 +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
1119 +#define        HIFN_7811_RNGCFG_PRE1   0x00000f00      /* first prescalar */
1120 +#define        HIFN_7811_RNGCFG_OPRE   0x00000080      /* output prescalar */
1121 +#define        HIFN_7811_RNGCFG_DEFL   0x00000f80      /* 2 words/ 1/100 sec */
1122 +
1123 +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
1124 +#define        HIFN_7811_RNGSTS_RDY    0x00004000      /* two numbers in FIFO */
1125 +#define        HIFN_7811_RNGSTS_UFL    0x00001000      /* rng underflow */
1126 +
1127 +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
1128 +#define        HIFN_MIPSRST_BAR2SIZE   0xffff0000      /* sdram size */
1129 +#define        HIFN_MIPSRST_GPRAMINIT  0x00008000      /* gpram can be accessed */
1130 +#define        HIFN_MIPSRST_CRAMINIT   0x00004000      /* ctxram can be accessed */
1131 +#define        HIFN_MIPSRST_LED2       0x00000400      /* external LED2 */
1132 +#define        HIFN_MIPSRST_LED1       0x00000200      /* external LED1 */
1133 +#define        HIFN_MIPSRST_LED0       0x00000100      /* external LED0 */
1134 +#define        HIFN_MIPSRST_MIPSDIS    0x00000004      /* disable MIPS */
1135 +#define        HIFN_MIPSRST_MIPSRST    0x00000002      /* warm reset MIPS */
1136 +#define        HIFN_MIPSRST_MIPSCOLD   0x00000001      /* cold reset MIPS */
1137 +
1138 +/* Public key reset register (HIFN_1_PUB_RESET) */
1139 +#define        HIFN_PUBRST_RESET       0x00000001      /* reset public/rng unit */
1140 +
1141 +/* Public operation register (HIFN_1_PUB_OP) */
1142 +#define        HIFN_PUBOP_AOFFSET      0x0000003e      /* A offset */
1143 +#define        HIFN_PUBOP_BOFFSET      0x00000fc0      /* B offset */
1144 +#define        HIFN_PUBOP_MOFFSET      0x0003f000      /* M offset */
1145 +#define        HIFN_PUBOP_OP_MASK      0x003c0000      /* Opcode: */
1146 +#define        HIFN_PUBOP_OP_NOP       0x00000000      /*  NOP */
1147 +#define        HIFN_PUBOP_OP_ADD       0x00040000      /*  ADD */
1148 +#define        HIFN_PUBOP_OP_ADDC      0x00080000      /*  ADD w/carry */
1149 +#define        HIFN_PUBOP_OP_SUB       0x000c0000      /*  SUB */
1150 +#define        HIFN_PUBOP_OP_SUBC      0x00100000      /*  SUB w/carry */
1151 +#define        HIFN_PUBOP_OP_MODADD    0x00140000      /*  Modular ADD */
1152 +#define        HIFN_PUBOP_OP_MODSUB    0x00180000      /*  Modular SUB */
1153 +#define        HIFN_PUBOP_OP_INCA      0x001c0000      /*  INC A */
1154 +#define        HIFN_PUBOP_OP_DECA      0x00200000      /*  DEC A */
1155 +#define        HIFN_PUBOP_OP_MULT      0x00240000      /*  MULT */
1156 +#define        HIFN_PUBOP_OP_MODMULT   0x00280000      /*  Modular MULT */
1157 +#define        HIFN_PUBOP_OP_MODRED    0x002c0000      /*  Modular Red */
1158 +#define        HIFN_PUBOP_OP_MODEXP    0x00300000      /*  Modular Exp */
1159 +
1160 +/* Public operand length register (HIFN_1_PUB_OPLEN) */
1161 +#define        HIFN_PUBOPLEN_MODLEN    0x0000007f
1162 +#define        HIFN_PUBOPLEN_EXPLEN    0x0003ff80
1163 +#define        HIFN_PUBOPLEN_REDLEN    0x003c0000
1164 +
1165 +/* Public status register (HIFN_1_PUB_STATUS) */
1166 +#define        HIFN_PUBSTS_DONE        0x00000001      /* operation done */
1167 +#define        HIFN_PUBSTS_CARRY       0x00000002      /* carry */
1168 +#define        HIFN_PUBSTS_FIFO_EMPTY  0x00000100      /* fifo empty */
1169 +#define        HIFN_PUBSTS_FIFO_FULL   0x00000200      /* fifo full */
1170 +#define        HIFN_PUBSTS_FIFO_OVFL   0x00000400      /* fifo overflow */
1171 +#define        HIFN_PUBSTS_FIFO_WRITE  0x000f0000      /* fifo write */
1172 +#define        HIFN_PUBSTS_FIFO_READ   0x0f000000      /* fifo read */
1173 +
1174 +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
1175 +#define        HIFN_PUBIEN_DONE        0x00000001      /* operation done interrupt */
1176 +
1177 +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
1178 +#define        HIFN_RNGCFG_ENA         0x00000001      /* enable rng */
1179 +
1180 +/*
1181 + * Register offsets in register set 1
1182 + */
1183 +
1184 +#define        HIFN_UNLOCK_SECRET1     0xf4
1185 +#define        HIFN_UNLOCK_SECRET2     0xfc
1186 +
1187 +/*
1188 + * PLL config register
1189 + *
1190 + * This register is present only on 7954/7955/7956 parts. It must be
1191 + * programmed according to the bus interface method used by the h/w.
1192 + * Note that the parts require a stable clock.  Since the PCI clock
1193 + * may vary the reference clock must usually be used.  To avoid
1194 + * overclocking the core logic, setup must be done carefully, refer
1195 + * to the driver for details.  The exact multiplier required varies
1196 + * by part and system configuration; refer to the Hifn documentation.
1197 + */
1198 +#define        HIFN_PLL_REF_SEL        0x00000001      /* REF/HBI clk selection */
1199 +#define        HIFN_PLL_BP             0x00000002      /* bypass (used during setup) */
1200 +/* bit 2 reserved */
1201 +#define        HIFN_PLL_PK_CLK_SEL     0x00000008      /* public key clk select */
1202 +#define        HIFN_PLL_PE_CLK_SEL     0x00000010      /* packet engine clk select */
1203 +/* bits 5-9 reserved */
1204 +#define        HIFN_PLL_MBSET          0x00000400      /* must be set to 1 */
1205 +#define        HIFN_PLL_ND             0x00003800      /* Fpll_ref multiplier select */
1206 +#define        HIFN_PLL_ND_SHIFT       11
1207 +#define        HIFN_PLL_ND_2           0x00000000      /* 2x */
1208 +#define        HIFN_PLL_ND_4           0x00000800      /* 4x */
1209 +#define        HIFN_PLL_ND_6           0x00001000      /* 6x */
1210 +#define        HIFN_PLL_ND_8           0x00001800      /* 8x */
1211 +#define        HIFN_PLL_ND_10          0x00002000      /* 10x */
1212 +#define        HIFN_PLL_ND_12          0x00002800      /* 12x */
1213 +/* bits 14-15 reserved */
1214 +#define        HIFN_PLL_IS             0x00010000      /* charge pump current select */
1215 +/* bits 17-31 reserved */
1216 +
1217 +/*
1218 + * Board configuration specifies only these bits.
1219 + */
1220 +#define        HIFN_PLL_CONFIG         (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
1221 +
1222 +/*
1223 + * Public Key Engine Mode Register
1224 + */
1225 +#define        HIFN_PKMODE_HOSTINVERT  (1 << 0)        /* HOST INVERT */
1226 +#define        HIFN_PKMODE_ENHANCED    (1 << 1)        /* Enable enhanced mode */
1227 +
1228 +
1229 +/*********************************************************************
1230 + * Structs for board commands
1231 + *
1232 + *********************************************************************/
1233 +
1234 +/*
1235 + * Structure to help build up the command data structure.
1236 + */
1237 +typedef struct hifn_base_command {
1238 +       volatile u_int16_t masks;
1239 +       volatile u_int16_t session_num;
1240 +       volatile u_int16_t total_source_count;
1241 +       volatile u_int16_t total_dest_count;
1242 +} hifn_base_command_t;
1243 +
1244 +#define        HIFN_BASE_CMD_MAC               0x0400
1245 +#define        HIFN_BASE_CMD_CRYPT             0x0800
1246 +#define        HIFN_BASE_CMD_DECODE            0x2000
1247 +#define        HIFN_BASE_CMD_SRCLEN_M          0xc000
1248 +#define        HIFN_BASE_CMD_SRCLEN_S          14
1249 +#define        HIFN_BASE_CMD_DSTLEN_M          0x3000
1250 +#define        HIFN_BASE_CMD_DSTLEN_S          12
1251 +#define        HIFN_BASE_CMD_LENMASK_HI        0x30000
1252 +#define        HIFN_BASE_CMD_LENMASK_LO        0x0ffff
1253 +
1254 +/*
1255 + * Structure to help build up the command data structure.
1256 + */
1257 +typedef struct hifn_crypt_command {
1258 +       volatile u_int16_t masks;
1259 +       volatile u_int16_t header_skip;
1260 +       volatile u_int16_t source_count;
1261 +       volatile u_int16_t reserved;
1262 +} hifn_crypt_command_t;
1263 +
1264 +#define        HIFN_CRYPT_CMD_ALG_MASK         0x0003          /* algorithm: */
1265 +#define        HIFN_CRYPT_CMD_ALG_DES          0x0000          /*   DES */
1266 +#define        HIFN_CRYPT_CMD_ALG_3DES         0x0001          /*   3DES */
1267 +#define        HIFN_CRYPT_CMD_ALG_RC4          0x0002          /*   RC4 */
1268 +#define        HIFN_CRYPT_CMD_ALG_AES          0x0003          /*   AES */
1269 +#define        HIFN_CRYPT_CMD_MODE_MASK        0x0018          /* Encrypt mode: */
1270 +#define        HIFN_CRYPT_CMD_MODE_ECB         0x0000          /*   ECB */
1271 +#define        HIFN_CRYPT_CMD_MODE_CBC         0x0008          /*   CBC */
1272 +#define        HIFN_CRYPT_CMD_MODE_CFB         0x0010          /*   CFB */
1273 +#define        HIFN_CRYPT_CMD_MODE_OFB         0x0018          /*   OFB */
1274 +#define        HIFN_CRYPT_CMD_CLR_CTX          0x0040          /* clear context */
1275 +#define        HIFN_CRYPT_CMD_NEW_KEY          0x0800          /* expect new key */
1276 +#define        HIFN_CRYPT_CMD_NEW_IV           0x1000          /* expect new iv */
1277 +
1278 +#define        HIFN_CRYPT_CMD_SRCLEN_M         0xc000
1279 +#define        HIFN_CRYPT_CMD_SRCLEN_S         14
1280 +
1281 +#define        HIFN_CRYPT_CMD_KSZ_MASK         0x0600          /* AES key size: */
1282 +#define        HIFN_CRYPT_CMD_KSZ_128          0x0000          /*   128 bit */
1283 +#define        HIFN_CRYPT_CMD_KSZ_192          0x0200          /*   192 bit */
1284 +#define        HIFN_CRYPT_CMD_KSZ_256          0x0400          /*   256 bit */
1285 +
1286 +/*
1287 + * Structure to help build up the command data structure.
1288 + */
1289 +typedef struct hifn_mac_command {
1290 +       volatile u_int16_t masks;
1291 +       volatile u_int16_t header_skip;
1292 +       volatile u_int16_t source_count;
1293 +       volatile u_int16_t reserved;
1294 +} hifn_mac_command_t;
1295 +
1296 +#define        HIFN_MAC_CMD_ALG_MASK           0x0001
1297 +#define        HIFN_MAC_CMD_ALG_SHA1           0x0000
1298 +#define        HIFN_MAC_CMD_ALG_MD5            0x0001
1299 +#define        HIFN_MAC_CMD_MODE_MASK          0x000c
1300 +#define        HIFN_MAC_CMD_MODE_HMAC          0x0000
1301 +#define        HIFN_MAC_CMD_MODE_SSL_MAC       0x0004
1302 +#define        HIFN_MAC_CMD_MODE_HASH          0x0008
1303 +#define        HIFN_MAC_CMD_MODE_FULL          0x0004
1304 +#define        HIFN_MAC_CMD_TRUNC              0x0010
1305 +#define        HIFN_MAC_CMD_RESULT             0x0020
1306 +#define        HIFN_MAC_CMD_APPEND             0x0040
1307 +#define        HIFN_MAC_CMD_SRCLEN_M           0xc000
1308 +#define        HIFN_MAC_CMD_SRCLEN_S           14
1309 +
1310 +/*
1311 + * MAC POS IPsec initiates authentication after encryption on encodes
1312 + * and before decryption on decodes.
1313 + */
1314 +#define        HIFN_MAC_CMD_POS_IPSEC          0x0200
1315 +#define        HIFN_MAC_CMD_NEW_KEY            0x0800
1316 +
1317 +/*
1318 + * The poll frequency and poll scalar defines are unshifted values used
1319 + * to set fields in the DMA Configuration Register.
1320 + */
1321 +#ifndef HIFN_POLL_FREQUENCY
1322 +#define        HIFN_POLL_FREQUENCY     0x1
1323 +#endif
1324 +
1325 +#ifndef HIFN_POLL_SCALAR
1326 +#define        HIFN_POLL_SCALAR        0x0
1327 +#endif
1328 +
1329 +#define        HIFN_MAX_SEGLEN         0xffff          /* maximum dma segment len */
1330 +#define        HIFN_MAX_DMALEN         0x3ffff         /* maximum dma length */
1331 +#endif /* __HIFN_H__ */
1332 --- /dev/null
1333 +++ b/crypto/ocf/hifn/hifn7751var.h
1334 @@ -0,0 +1,369 @@
1335 +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
1336 +/*     $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $  */
1337 +
1338 +/*-
1339 + * Invertex AEON / Hifn 7751 driver
1340 + * Copyright (c) 1999 Invertex Inc. All rights reserved.
1341 + * Copyright (c) 1999 Theo de Raadt
1342 + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
1343 + *                     http://www.netsec.net
1344 + *
1345 + * Please send any comments, feedback, bug-fixes, or feature requests to
1346 + * software@invertex.com.
1347 + *
1348 + * Redistribution and use in source and binary forms, with or without
1349 + * modification, are permitted provided that the following conditions
1350 + * are met:
1351 + *
1352 + * 1. Redistributions of source code must retain the above copyright
1353 + *    notice, this list of conditions and the following disclaimer.
1354 + * 2. Redistributions in binary form must reproduce the above copyright
1355 + *    notice, this list of conditions and the following disclaimer in the
1356 + *    documentation and/or other materials provided with the distribution.
1357 + * 3. The name of the author may not be used to endorse or promote products
1358 + *    derived from this software without specific prior written permission.
1359 + *
1360 + *
1361 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1362 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1363 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1364 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1365 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1366 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1367 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1368 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1369 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1370 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1371 + *
1372 + * Effort sponsored in part by the Defense Advanced Research Projects
1373 + * Agency (DARPA) and Air Force Research Laboratory, Air Force
1374 + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
1375 + *
1376 + */
1377 +
1378 +#ifndef __HIFN7751VAR_H__
1379 +#define __HIFN7751VAR_H__
1380 +
1381 +#ifdef __KERNEL__
1382 +
1383 +/*
1384 + * Some configurable values for the driver.  By default command+result
1385 + * descriptor rings are the same size.  The src+dst descriptor rings
1386 + * are sized at 3.5x the number of potential commands.  Slower parts
1387 + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
1388 + * src+cmd/result descriptors.  It's not clear that increasing the size
1389 + * of the descriptor rings helps performance significantly as other
1390 + * factors tend to come into play (e.g. copying misaligned packets).
1391 + */
1392 +#define        HIFN_D_CMD_RSIZE        24      /* command descriptors */
1393 +#define        HIFN_D_SRC_RSIZE        ((HIFN_D_CMD_RSIZE * 7) / 2)    /* source descriptors */
1394 +#define        HIFN_D_RES_RSIZE        HIFN_D_CMD_RSIZE        /* result descriptors */
1395 +#define        HIFN_D_DST_RSIZE        HIFN_D_SRC_RSIZE        /* destination descriptors */
1396 +
1397 +/*
1398 + *  Length values for cryptography
1399 + */
1400 +#define HIFN_DES_KEY_LENGTH            8
1401 +#define HIFN_3DES_KEY_LENGTH           24
1402 +#define HIFN_MAX_CRYPT_KEY_LENGTH      HIFN_3DES_KEY_LENGTH
1403 +#define HIFN_IV_LENGTH                 8
1404 +#define        HIFN_AES_IV_LENGTH              16
1405 +#define HIFN_MAX_IV_LENGTH             HIFN_AES_IV_LENGTH
1406 +
1407 +/*
1408 + *  Length values for authentication
1409 + */
1410 +#define HIFN_MAC_KEY_LENGTH            64
1411 +#define HIFN_MD5_LENGTH                        16
1412 +#define HIFN_SHA1_LENGTH               20
1413 +#define HIFN_MAC_TRUNC_LENGTH          12
1414 +
1415 +#define MAX_SCATTER 64
1416 +
1417 +/*
1418 + * Data structure to hold all 4 rings and any other ring related data.
1419 + */
1420 +struct hifn_dma {
1421 +       /*
1422 +        *  Descriptor rings.  We add +1 to the size to accomidate the
1423 +        *  jump descriptor.
1424 +        */
1425 +       struct hifn_desc        cmdr[HIFN_D_CMD_RSIZE+1];
1426 +       struct hifn_desc        srcr[HIFN_D_SRC_RSIZE+1];
1427 +       struct hifn_desc        dstr[HIFN_D_DST_RSIZE+1];
1428 +       struct hifn_desc        resr[HIFN_D_RES_RSIZE+1];
1429 +
1430 +       struct hifn_command     *hifn_commands[HIFN_D_RES_RSIZE];
1431 +
1432 +       u_char                  command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
1433 +       u_char                  result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
1434 +       u_int32_t               slop[HIFN_D_CMD_RSIZE];
1435 +
1436 +       u_int64_t               test_src, test_dst;
1437 +
1438 +       /*
1439 +        *  Our current positions for insertion and removal from the desriptor
1440 +        *  rings.
1441 +        */
1442 +       int                     cmdi, srci, dsti, resi;
1443 +       volatile int            cmdu, srcu, dstu, resu;
1444 +       int                     cmdk, srck, dstk, resk;
1445 +};
1446 +
1447 +struct hifn_session {
1448 +       int hs_used;
1449 +       int hs_mlen;
1450 +       u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
1451 +};
1452 +
1453 +#define        HIFN_RING_SYNC(sc, r, i, f)                                     \
1454 +       /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
1455 +
1456 +#define        HIFN_CMDR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), cmdr, (i), (f))
1457 +#define        HIFN_RESR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), resr, (i), (f))
1458 +#define        HIFN_SRCR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), srcr, (i), (f))
1459 +#define        HIFN_DSTR_SYNC(sc, i, f)        HIFN_RING_SYNC((sc), dstr, (i), (f))
1460 +
1461 +#define        HIFN_CMD_SYNC(sc, i, f)                                         \
1462 +       /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
1463 +
1464 +#define        HIFN_RES_SYNC(sc, i, f)                                         \
1465 +       /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
1466 +
1467 +typedef int bus_size_t;
1468 +
1469 +/*
1470 + * Holds data specific to a single HIFN board.
1471 + */
1472 +struct hifn_softc {
1473 +       softc_device_decl                sc_dev;
1474 +
1475 +       struct pci_dev          *sc_pcidev;     /* PCI device pointer */
1476 +       spinlock_t              sc_mtx;         /* per-instance lock */
1477 +
1478 +       int                     sc_num;         /* for multiple devs */
1479 +
1480 +       ocf_iomem_t             sc_bar0;
1481 +       bus_size_t              sc_bar0_lastreg;/* bar0 last reg written */
1482 +       ocf_iomem_t             sc_bar1;
1483 +       bus_size_t              sc_bar1_lastreg;/* bar1 last reg written */
1484 +
1485 +       int                     sc_irq;
1486 +
1487 +       u_int32_t               sc_dmaier;
1488 +       u_int32_t               sc_drammodel;   /* 1=dram, 0=sram */
1489 +       u_int32_t               sc_pllconfig;   /* 7954/7955/7956 PLL config */
1490 +
1491 +       struct hifn_dma         *sc_dma;
1492 +       dma_addr_t              sc_dma_physaddr;/* physical address of sc_dma */
1493 +
1494 +       int                     sc_dmansegs;
1495 +       int32_t                 sc_cid;
1496 +       int                     sc_maxses;
1497 +       int                     sc_nsessions;
1498 +       struct hifn_session     *sc_sessions;
1499 +       int                     sc_ramsize;
1500 +       int                     sc_flags;
1501 +#define        HIFN_HAS_RNG            0x1     /* includes random number generator */
1502 +#define        HIFN_HAS_PUBLIC         0x2     /* includes public key support */
1503 +#define        HIFN_HAS_AES            0x4     /* includes AES support */
1504 +#define        HIFN_IS_7811            0x8     /* Hifn 7811 part */
1505 +#define        HIFN_IS_7956            0x10    /* Hifn 7956/7955 don't have SDRAM */
1506 +
1507 +       struct timer_list       sc_tickto;      /* for managing DMA */
1508 +
1509 +       int                     sc_rngfirst;
1510 +       int                     sc_rnghz;       /* RNG polling frequency */
1511 +
1512 +       int                     sc_c_busy;      /* command ring busy */
1513 +       int                     sc_s_busy;      /* source data ring busy */
1514 +       int                     sc_d_busy;      /* destination data ring busy */
1515 +       int                     sc_r_busy;      /* result ring busy */
1516 +       int                     sc_active;      /* for initial countdown */
1517 +       int                     sc_needwakeup;  /* ops q'd wating on resources */
1518 +       int                     sc_curbatch;    /* # ops submitted w/o int */
1519 +       int                     sc_suspended;
1520 +#ifdef HIFN_VULCANDEV
1521 +       struct cdev            *sc_pkdev;
1522 +#endif
1523 +};
1524 +
1525 +#define        HIFN_LOCK(_sc)          spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
1526 +#define        HIFN_UNLOCK(_sc)        spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
1527 +
1528 +/*
1529 + *  hifn_command_t
1530 + *
1531 + *  This is the control structure used to pass commands to hifn_encrypt().
1532 + *
1533 + *  flags
1534 + *  -----
1535 + *  Flags is the bitwise "or" values for command configuration.  A single
1536 + *  encrypt direction needs to be set:
1537 + *
1538 + *     HIFN_ENCODE or HIFN_DECODE
1539 + *
1540 + *  To use cryptography, a single crypto algorithm must be included:
1541 + *
1542 + *     HIFN_CRYPT_3DES or HIFN_CRYPT_DES
1543 + *
1544 + *  To use authentication is used, a single MAC algorithm must be included:
1545 + *
1546 + *     HIFN_MAC_MD5 or HIFN_MAC_SHA1
1547 + *
1548 + *  By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
1549 + *  If the value below is set, hash values are truncated or assumed
1550 + *  truncated to 12 bytes:
1551 + *
1552 + *     HIFN_MAC_TRUNC
1553 + *
1554 + *  Keys for encryption and authentication can be sent as part of a command,
1555 + *  or the last key value used with a particular session can be retrieved
1556 + *  and used again if either of these flags are not specified.
1557 + *
1558 + *     HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
1559 + *
1560 + *  session_num
1561 + *  -----------
1562 + *  A number between 0 and 2048 (for DRAM models) or a number between
1563 + *  0 and 768 (for SRAM models).  Those who don't want to use session
1564 + *  numbers should leave value at zero and send a new crypt key and/or
1565 + *  new MAC key on every command.  If you use session numbers and
1566 + *  don't send a key with a command, the last key sent for that same
1567 + *  session number will be used.
1568 + *
1569 + *  Warning:  Using session numbers and multiboard at the same time
1570 + *            is currently broken.
1571 + *
1572 + *  mbuf
1573 + *  ----
1574 + *  Either fill in the mbuf pointer and npa=0 or
1575 + *      fill packp[] and packl[] and set npa to > 0
1576 + *
1577 + *  mac_header_skip
1578 + *  ---------------
1579 + *  The number of bytes of the source_buf that are skipped over before
1580 + *  authentication begins.  This must be a number between 0 and 2^16-1
1581 + *  and can be used by IPsec implementers to skip over IP headers.
1582 + *  *** Value ignored if authentication not used ***
1583 + *
1584 + *  crypt_header_skip
1585 + *  -----------------
1586 + *  The number of bytes of the source_buf that are skipped over before
1587 + *  the cryptographic operation begins.  This must be a number between 0
1588 + *  and 2^16-1.  For IPsec, this number will always be 8 bytes larger
1589 + *  than the auth_header_skip (to skip over the ESP header).
1590 + *  *** Value ignored if cryptography not used ***
1591 + *
1592 + */
1593 +struct hifn_operand {
1594 +       union {
1595 +               struct sk_buff *skb;
1596 +               struct uio *io;
1597 +               unsigned char *buf;
1598 +       } u;
1599 +       void            *map;
1600 +       bus_size_t      mapsize;
1601 +       int             nsegs;
1602 +       struct {
1603 +           dma_addr_t  ds_addr;
1604 +           int         ds_len;
1605 +       } segs[MAX_SCATTER];
1606 +};
1607 +
1608 +struct hifn_command {
1609 +       u_int16_t session_num;
1610 +       u_int16_t base_masks, cry_masks, mac_masks;
1611 +       u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
1612 +       int cklen;
1613 +       int sloplen, slopidx;
1614 +
1615 +       struct hifn_operand src;
1616 +       struct hifn_operand dst;
1617 +
1618 +       struct hifn_softc *softc;
1619 +       struct cryptop *crp;
1620 +       struct cryptodesc *enccrd, *maccrd;
1621 +};
1622 +
1623 +#define        src_skb         src.u.skb
1624 +#define        src_io          src.u.io
1625 +#define        src_map         src.map
1626 +#define        src_mapsize     src.mapsize
1627 +#define        src_segs        src.segs
1628 +#define        src_nsegs       src.nsegs
1629 +#define        src_buf         src.u.buf
1630 +
1631 +#define        dst_skb         dst.u.skb
1632 +#define        dst_io          dst.u.io
1633 +#define        dst_map         dst.map
1634 +#define        dst_mapsize     dst.mapsize
1635 +#define        dst_segs        dst.segs
1636 +#define        dst_nsegs       dst.nsegs
1637 +#define        dst_buf         dst.u.buf
1638 +
1639 +/*
1640 + *  Return values for hifn_crypto()
1641 + */
1642 +#define HIFN_CRYPTO_SUCCESS    0
1643 +#define HIFN_CRYPTO_BAD_INPUT  (-1)
1644 +#define HIFN_CRYPTO_RINGS_FULL (-2)
1645 +
1646 +/**************************************************************************
1647 + *
1648 + *  Function:  hifn_crypto
1649 + *
1650 + *  Purpose:   Called by external drivers to begin an encryption on the
1651 + *             HIFN board.
1652 + *
1653 + *  Blocking/Non-blocking Issues
1654 + *  ============================
1655 + *  The driver cannot block in hifn_crypto (no calls to tsleep) currently.
1656 + *  hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
1657 + *  room in any of the rings for the request to proceed.
1658 + *
1659 + *  Return Values
1660 + *  =============
1661 + *  0 for success, negative values on error
1662 + *
1663 + *  Defines for negative error codes are:
1664 + *
1665 + *    HIFN_CRYPTO_BAD_INPUT  :  The passed in command had invalid settings.
1666 + *    HIFN_CRYPTO_RINGS_FULL :  All DMA rings were full and non-blocking
1667 + *                              behaviour was requested.
1668 + *
1669 + *************************************************************************/
1670 +
1671 +/*
1672 + * Convert back and forth from 'sid' to 'card' and 'session'
1673 + */
1674 +#define HIFN_CARD(sid)         (((sid) & 0xf0000000) >> 28)
1675 +#define HIFN_SESSION(sid)      ((sid) & 0x000007ff)
1676 +#define HIFN_SID(crd,ses)      (((crd) << 28) | ((ses) & 0x7ff))
1677 +
1678 +#endif /* _KERNEL */
1679 +
1680 +struct hifn_stats {
1681 +       u_int64_t hst_ibytes;
1682 +       u_int64_t hst_obytes;
1683 +       u_int32_t hst_ipackets;
1684 +       u_int32_t hst_opackets;
1685 +       u_int32_t hst_invalid;
1686 +       u_int32_t hst_nomem;            /* malloc or one of hst_nomem_* */
1687 +       u_int32_t hst_abort;
1688 +       u_int32_t hst_noirq;            /* IRQ for no reason */
1689 +       u_int32_t hst_totbatch;         /* ops submitted w/o interrupt */
1690 +       u_int32_t hst_maxbatch;         /* max ops submitted together */
1691 +       u_int32_t hst_unaligned;        /* unaligned src caused copy */
1692 +       /*
1693 +        * The following divides hst_nomem into more specific buckets.
1694 +        */
1695 +       u_int32_t hst_nomem_map;        /* bus_dmamap_create failed */
1696 +       u_int32_t hst_nomem_load;       /* bus_dmamap_load_* failed */
1697 +       u_int32_t hst_nomem_mbuf;       /* MGET* failed */
1698 +       u_int32_t hst_nomem_mcl;        /* MCLGET* failed */
1699 +       u_int32_t hst_nomem_cr;         /* out of command/result descriptor */
1700 +       u_int32_t hst_nomem_sd;         /* out of src/dst descriptors */
1701 +};
1702 +
1703 +#endif /* __HIFN7751VAR_H__ */
1704 --- /dev/null
1705 +++ b/crypto/ocf/hifn/hifn7751.c
1706 @@ -0,0 +1,2970 @@
1707 +/*     $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $  */
1708 +
1709 +/*-
1710 + * Invertex AEON / Hifn 7751 driver
1711 + * Copyright (c) 1999 Invertex Inc. All rights reserved.
1712 + * Copyright (c) 1999 Theo de Raadt
1713 + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
1714 + *                     http://www.netsec.net
1715 + * Copyright (c) 2003 Hifn Inc.
1716 + *
1717 + * This driver is based on a previous driver by Invertex, for which they
1718 + * requested:  Please send any comments, feedback, bug-fixes, or feature
1719 + * requests to software@invertex.com.
1720 + *
1721 + * Redistribution and use in source and binary forms, with or without
1722 + * modification, are permitted provided that the following conditions
1723 + * are met:
1724 + *
1725 + * 1. Redistributions of source code must retain the above copyright
1726 + *   notice, this list of conditions and the following disclaimer.
1727 + * 2. Redistributions in binary form must reproduce the above copyright
1728 + *   notice, this list of conditions and the following disclaimer in the
1729 + *   documentation and/or other materials provided with the distribution.
1730 + * 3. The name of the author may not be used to endorse or promote products
1731 + *   derived from this software without specific prior written permission.
1732 + *
1733 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1734 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1735 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1736 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1737 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1738 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1739 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1740 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1741 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1742 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1743 + *
1744 + * Effort sponsored in part by the Defense Advanced Research Projects
1745 + * Agency (DARPA) and Air Force Research Laboratory, Air Force
1746 + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
1747 + *
1748 + *
1749 +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
1750 + */
1751 +
1752 +/*
1753 + * Driver for various Hifn encryption processors.
1754 + */
1755 +#ifndef AUTOCONF_INCLUDED
1756 +#include <linux/config.h>
1757 +#endif
1758 +#include <linux/module.h>
1759 +#include <linux/init.h>
1760 +#include <linux/list.h>
1761 +#include <linux/slab.h>
1762 +#include <linux/wait.h>
1763 +#include <linux/sched.h>
1764 +#include <linux/pci.h>
1765 +#include <linux/delay.h>
1766 +#include <linux/interrupt.h>
1767 +#include <linux/spinlock.h>
1768 +#include <linux/random.h>
1769 +#include <linux/version.h>
1770 +#include <linux/skbuff.h>
1771 +#include <asm/io.h>
1772 +
1773 +#include <cryptodev.h>
1774 +#include <uio.h>
1775 +#include <hifn/hifn7751reg.h>
1776 +#include <hifn/hifn7751var.h>
1777 +
1778 +#if 1
1779 +#define        DPRINTF(a...)   if (hifn_debug) { \
1780 +                                                       printk("%s: ", sc ? \
1781 +                                                               device_get_nameunit(sc->sc_dev) : "hifn"); \
1782 +                                                       printk(a); \
1783 +                                               } else
1784 +#else
1785 +#define        DPRINTF(a...)
1786 +#endif
1787 +
1788 +static inline int
1789 +pci_get_revid(struct pci_dev *dev)
1790 +{
1791 +       u8 rid = 0;
1792 +       pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
1793 +       return rid;
1794 +}
1795 +
1796 +static struct hifn_stats hifnstats;
1797 +
1798 +#define        debug hifn_debug
1799 +int hifn_debug = 0;
1800 +module_param(hifn_debug, int, 0644);
1801 +MODULE_PARM_DESC(hifn_debug, "Enable debug");
1802 +
1803 +int hifn_maxbatch = 1;
1804 +module_param(hifn_maxbatch, int, 0644);
1805 +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
1806 +
1807 +#ifdef MODULE_PARM
1808 +char *hifn_pllconfig = NULL;
1809 +MODULE_PARM(hifn_pllconfig, "s");
1810 +#else
1811 +char hifn_pllconfig[32]; /* This setting is RO after loading */
1812 +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
1813 +#endif
1814 +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
1815 +
1816 +#ifdef HIFN_VULCANDEV
1817 +#include <sys/conf.h>
1818 +#include <sys/uio.h>
1819 +
1820 +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
1821 +#endif
1822 +
1823 +/*
1824 + * Prototypes and count for the pci_device structure
1825 + */
1826 +static int  hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
1827 +static void hifn_remove(struct pci_dev *dev);
1828 +
1829 +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
1830 +static int hifn_freesession(device_t, u_int64_t);
1831 +static int hifn_process(device_t, struct cryptop *, int);
1832 +
1833 +static device_method_t hifn_methods = {
1834 +       /* crypto device methods */
1835 +       DEVMETHOD(cryptodev_newsession, hifn_newsession),
1836 +       DEVMETHOD(cryptodev_freesession,hifn_freesession),
1837 +       DEVMETHOD(cryptodev_process,    hifn_process),
1838 +};
1839 +
1840 +static void hifn_reset_board(struct hifn_softc *, int);
1841 +static void hifn_reset_puc(struct hifn_softc *);
1842 +static void hifn_puc_wait(struct hifn_softc *);
1843 +static int hifn_enable_crypto(struct hifn_softc *);
1844 +static void hifn_set_retry(struct hifn_softc *sc);
1845 +static void hifn_init_dma(struct hifn_softc *);
1846 +static void hifn_init_pci_registers(struct hifn_softc *);
1847 +static int hifn_sramsize(struct hifn_softc *);
1848 +static int hifn_dramsize(struct hifn_softc *);
1849 +static int hifn_ramtype(struct hifn_softc *);
1850 +static void hifn_sessions(struct hifn_softc *);
1851 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
1852 +static irqreturn_t hifn_intr(int irq, void *arg);
1853 +#else
1854 +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
1855 +#endif
1856 +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
1857 +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
1858 +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
1859 +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
1860 +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
1861 +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
1862 +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
1863 +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
1864 +static int hifn_init_pubrng(struct hifn_softc *);
1865 +static void hifn_tick(unsigned long arg);
1866 +static void hifn_abort(struct hifn_softc *);
1867 +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
1868 +
1869 +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
1870 +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
1871 +
1872 +#ifdef CONFIG_OCF_RANDOMHARVEST
1873 +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
1874 +#endif
1875 +
1876 +#define HIFN_MAX_CHIPS 8
1877 +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
1878 +
1879 +static __inline u_int32_t
1880 +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
1881 +{
1882 +       u_int32_t v = readl(sc->sc_bar0 + reg);
1883 +       sc->sc_bar0_lastreg = (bus_size_t) -1;
1884 +       return (v);
1885 +}
1886 +#define        WRITE_REG_0(sc, reg, val)       hifn_write_reg_0(sc, reg, val)
1887 +
1888 +static __inline u_int32_t
1889 +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
1890 +{
1891 +       u_int32_t v = readl(sc->sc_bar1 + reg);
1892 +       sc->sc_bar1_lastreg = (bus_size_t) -1;
1893 +       return (v);
1894 +}
1895 +#define        WRITE_REG_1(sc, reg, val)       hifn_write_reg_1(sc, reg, val)
1896 +
1897 +/*
1898 + * map in a given buffer (great on some arches :-)
1899 + */
1900 +
1901 +static int
1902 +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
1903 +{
1904 +       struct iovec *iov = uio->uio_iov;
1905 +
1906 +       DPRINTF("%s()\n", __FUNCTION__);
1907 +
1908 +       buf->mapsize = 0;
1909 +       for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
1910 +               buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
1911 +                               iov->iov_base, iov->iov_len,
1912 +                               PCI_DMA_BIDIRECTIONAL);
1913 +               buf->segs[buf->nsegs].ds_len = iov->iov_len;
1914 +               buf->mapsize += iov->iov_len;
1915 +               iov++;
1916 +               buf->nsegs++;
1917 +       }
1918 +       /* identify this buffer by the first segment */
1919 +       buf->map = (void *) buf->segs[0].ds_addr;
1920 +       return(0);
1921 +}
1922 +
1923 +/*
1924 + * map in a given sk_buff
1925 + */
1926 +
1927 +static int
1928 +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
1929 +{
1930 +       int i;
1931 +
1932 +       DPRINTF("%s()\n", __FUNCTION__);
1933 +
1934 +       buf->mapsize = 0;
1935 +
1936 +       buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
1937 +                       skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
1938 +       buf->segs[0].ds_len = skb_headlen(skb);
1939 +       buf->mapsize += buf->segs[0].ds_len;
1940 +
1941 +       buf->nsegs = 1;
1942 +
1943 +       for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
1944 +               buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
1945 +               buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
1946 +                               page_address(skb_shinfo(skb)->frags[i].page) +
1947 +                                       skb_shinfo(skb)->frags[i].page_offset,
1948 +                               buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
1949 +               buf->mapsize += buf->segs[buf->nsegs].ds_len;
1950 +               buf->nsegs++;
1951 +       }
1952 +
1953 +       /* identify this buffer by the first segment */
1954 +       buf->map = (void *) buf->segs[0].ds_addr;
1955 +       return(0);
1956 +}
1957 +
1958 +/*
1959 + * map in a given contiguous buffer
1960 + */
1961 +
1962 +static int
1963 +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
1964 +{
1965 +       DPRINTF("%s()\n", __FUNCTION__);
1966 +
1967 +       buf->mapsize = 0;
1968 +       buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
1969 +                       b, len, PCI_DMA_BIDIRECTIONAL);
1970 +       buf->segs[0].ds_len = len;
1971 +       buf->mapsize += buf->segs[0].ds_len;
1972 +       buf->nsegs = 1;
1973 +
1974 +       /* identify this buffer by the first segment */
1975 +       buf->map = (void *) buf->segs[0].ds_addr;
1976 +       return(0);
1977 +}
1978 +
1979 +#if 0 /* not needed at this time */
1980 +static void
1981 +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
1982 +{
1983 +       int i;
1984 +
1985 +       DPRINTF("%s()\n", __FUNCTION__);
1986 +       for (i = 0; i < buf->nsegs; i++)
1987 +               pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
1988 +                               buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
1989 +}
1990 +#endif
1991 +
1992 +static void
1993 +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
1994 +{
1995 +       int i;
1996 +       DPRINTF("%s()\n", __FUNCTION__);
1997 +       for (i = 0; i < buf->nsegs; i++) {
1998 +               pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
1999 +                               buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
2000 +               buf->segs[i].ds_addr = 0;
2001 +               buf->segs[i].ds_len = 0;
2002 +       }
2003 +       buf->nsegs = 0;
2004 +       buf->mapsize = 0;
2005 +       buf->map = 0;
2006 +}
2007 +
2008 +static const char*
2009 +hifn_partname(struct hifn_softc *sc)
2010 +{
2011 +       /* XXX sprintf numbers when not decoded */
2012 +       switch (pci_get_vendor(sc->sc_pcidev)) {
2013 +       case PCI_VENDOR_HIFN:
2014 +               switch (pci_get_device(sc->sc_pcidev)) {
2015 +               case PCI_PRODUCT_HIFN_6500:     return "Hifn 6500";
2016 +               case PCI_PRODUCT_HIFN_7751:     return "Hifn 7751";
2017 +               case PCI_PRODUCT_HIFN_7811:     return "Hifn 7811";
2018 +               case PCI_PRODUCT_HIFN_7951:     return "Hifn 7951";
2019 +               case PCI_PRODUCT_HIFN_7955:     return "Hifn 7955";
2020 +               case PCI_PRODUCT_HIFN_7956:     return "Hifn 7956";
2021 +               }
2022 +               return "Hifn unknown-part";
2023 +       case PCI_VENDOR_INVERTEX:
2024 +               switch (pci_get_device(sc->sc_pcidev)) {
2025 +               case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
2026 +               }
2027 +               return "Invertex unknown-part";
2028 +       case PCI_VENDOR_NETSEC:
2029 +               switch (pci_get_device(sc->sc_pcidev)) {
2030 +               case PCI_PRODUCT_NETSEC_7751:   return "NetSec 7751";
2031 +               }
2032 +               return "NetSec unknown-part";
2033 +       }
2034 +       return "Unknown-vendor unknown-part";
2035 +}
2036 +
2037 +static u_int
2038 +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
2039 +{
2040 +       struct hifn_softc *sc = pci_get_drvdata(dev);
2041 +       if (v > max) {
2042 +               device_printf(sc->sc_dev, "Warning, %s %u out of range, "
2043 +                       "using max %u\n", what, v, max);
2044 +               v = max;
2045 +       } else if (v < min) {
2046 +               device_printf(sc->sc_dev, "Warning, %s %u out of range, "
2047 +                       "using min %u\n", what, v, min);
2048 +               v = min;
2049 +       }
2050 +       return v;
2051 +}
2052 +
2053 +/*
2054 + * Select PLL configuration for 795x parts.  This is complicated in
2055 + * that we cannot determine the optimal parameters without user input.
2056 + * The reference clock is derived from an external clock through a
2057 + * multiplier.  The external clock is either the host bus (i.e. PCI)
2058 + * or an external clock generator.  When using the PCI bus we assume
2059 + * the clock is either 33 or 66 MHz; for an external source we cannot
2060 + * tell the speed.
2061 + *
2062 + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
2063 + * for an external source, followed by the frequency.  We calculate
2064 + * the appropriate multiplier and PLL register contents accordingly.
2065 + * When no configuration is given we default to "pci66" since that
2066 + * always will allow the card to work.  If a card is using the PCI
2067 + * bus clock and in a 33MHz slot then it will be operating at half
2068 + * speed until the correct information is provided.
2069 + *
2070 + * We use a default setting of "ext66" because according to Mike Ham
2071 + * of HiFn, almost every board in existence has an external crystal
2072 + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
2073 + * because PCI33 can have clocks from 0 to 33Mhz, and some have
2074 + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
2075 + */
2076 +static void
2077 +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
2078 +{
2079 +       const char *pllspec = hifn_pllconfig;
2080 +       u_int freq, mul, fl, fh;
2081 +       u_int32_t pllconfig;
2082 +       char *nxt;
2083 +
2084 +       if (pllspec == NULL)
2085 +               pllspec = "ext66";
2086 +       fl = 33, fh = 66;
2087 +       pllconfig = 0;
2088 +       if (strncmp(pllspec, "ext", 3) == 0) {
2089 +               pllspec += 3;
2090 +               pllconfig |= HIFN_PLL_REF_SEL;
2091 +               switch (pci_get_device(dev)) {
2092 +               case PCI_PRODUCT_HIFN_7955:
2093 +               case PCI_PRODUCT_HIFN_7956:
2094 +                       fl = 20, fh = 100;
2095 +                       break;
2096 +#ifdef notyet
2097 +               case PCI_PRODUCT_HIFN_7954:
2098 +                       fl = 20, fh = 66;
2099 +                       break;
2100 +#endif
2101 +               }
2102 +       } else if (strncmp(pllspec, "pci", 3) == 0)
2103 +               pllspec += 3;
2104 +       freq = strtoul(pllspec, &nxt, 10);
2105 +       if (nxt == pllspec)
2106 +               freq = 66;
2107 +       else
2108 +               freq = checkmaxmin(dev, "frequency", freq, fl, fh);
2109 +       /*
2110 +        * Calculate multiplier.  We target a Fck of 266 MHz,
2111 +        * allowing only even values, possibly rounded down.
2112 +        * Multipliers > 8 must set the charge pump current.
2113 +        */
2114 +       mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
2115 +       pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
2116 +       if (mul > 8)
2117 +               pllconfig |= HIFN_PLL_IS;
2118 +       *pll = pllconfig;
2119 +}
2120 +
2121 +/*
2122 + * Attach an interface that successfully probed.
2123 + */
2124 +static int
2125 +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
2126 +{
2127 +       struct hifn_softc *sc = NULL;
2128 +       char rbase;
2129 +       u_int16_t ena, rev;
2130 +       int rseg, rc;
2131 +       unsigned long mem_start, mem_len;
2132 +       static int num_chips = 0;
2133 +
2134 +       DPRINTF("%s()\n", __FUNCTION__);
2135 +
2136 +       if (pci_enable_device(dev) < 0)
2137 +               return(-ENODEV);
2138 +
2139 +       if (pci_set_mwi(dev))
2140 +               return(-ENODEV);
2141 +
2142 +       if (!dev->irq) {
2143 +               printk("hifn: found device with no IRQ assigned. check BIOS settings!");
2144 +               pci_disable_device(dev);
2145 +               return(-ENODEV);
2146 +       }
2147 +
2148 +       sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
2149 +       if (!sc)
2150 +               return(-ENOMEM);
2151 +       memset(sc, 0, sizeof(*sc));
2152 +
2153 +       softc_device_init(sc, "hifn", num_chips, hifn_methods);
2154 +
2155 +       sc->sc_pcidev = dev;
2156 +       sc->sc_irq = -1;
2157 +       sc->sc_cid = -1;
2158 +       sc->sc_num = num_chips++;
2159 +       if (sc->sc_num < HIFN_MAX_CHIPS)
2160 +               hifn_chip_idx[sc->sc_num] = sc;
2161 +
2162 +       pci_set_drvdata(sc->sc_pcidev, sc);
2163 +
2164 +       spin_lock_init(&sc->sc_mtx);
2165 +
2166 +       /* XXX handle power management */
2167 +
2168 +       /*
2169 +        * The 7951 and 795x have a random number generator and
2170 +        * public key support; note this.
2171 +        */
2172 +       if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
2173 +           (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
2174 +            pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
2175 +            pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
2176 +               sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
2177 +       /*
2178 +        * The 7811 has a random number generator and
2179 +        * we also note it's identity 'cuz of some quirks.
2180 +        */
2181 +       if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
2182 +           pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
2183 +               sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
2184 +
2185 +       /*
2186 +        * The 795x parts support AES.
2187 +        */
2188 +       if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
2189 +           (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
2190 +            pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
2191 +               sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
2192 +               /*
2193 +                * Select PLL configuration.  This depends on the
2194 +                * bus and board design and must be manually configured
2195 +                * if the default setting is unacceptable.
2196 +                */
2197 +               hifn_getpllconfig(dev, &sc->sc_pllconfig);
2198 +       }
2199 +
2200 +       /*
2201 +        * Setup PCI resources. Note that we record the bus
2202 +        * tag and handle for each register mapping, this is
2203 +        * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
2204 +        * and WRITE_REG_1 macros throughout the driver.
2205 +        */
2206 +       mem_start = pci_resource_start(sc->sc_pcidev, 0);
2207 +       mem_len   = pci_resource_len(sc->sc_pcidev, 0);
2208 +       sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
2209 +       if (!sc->sc_bar0) {
2210 +               device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
2211 +               goto fail;
2212 +       }
2213 +       sc->sc_bar0_lastreg = (bus_size_t) -1;
2214 +
2215 +       mem_start = pci_resource_start(sc->sc_pcidev, 1);
2216 +       mem_len   = pci_resource_len(sc->sc_pcidev, 1);
2217 +       sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
2218 +       if (!sc->sc_bar1) {
2219 +               device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
2220 +               goto fail;
2221 +       }
2222 +       sc->sc_bar1_lastreg = (bus_size_t) -1;
2223 +
2224 +       /* fix up the bus size */
2225 +       if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
2226 +               device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
2227 +               goto fail;
2228 +       }
2229 +       if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
2230 +               device_printf(sc->sc_dev,
2231 +                               "No usable consistent DMA configuration, aborting.\n");
2232 +               goto fail;
2233 +       }
2234 +
2235 +       hifn_set_retry(sc);
2236 +
2237 +       /*
2238 +        * Setup the area where the Hifn DMA's descriptors
2239 +        * and associated data structures.
2240 +        */
2241 +       sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
2242 +                       sizeof(*sc->sc_dma),
2243 +                       &sc->sc_dma_physaddr);
2244 +       if (!sc->sc_dma) {
2245 +               device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
2246 +               goto fail;
2247 +       }
2248 +       bzero(sc->sc_dma, sizeof(*sc->sc_dma));
2249 +
2250 +       /*
2251 +        * Reset the board and do the ``secret handshake''
2252 +        * to enable the crypto support.  Then complete the
2253 +        * initialization procedure by setting up the interrupt
2254 +        * and hooking in to the system crypto support so we'll
2255 +        * get used for system services like the crypto device,
2256 +        * IPsec, RNG device, etc.
2257 +        */
2258 +       hifn_reset_board(sc, 0);
2259 +
2260 +       if (hifn_enable_crypto(sc) != 0) {
2261 +               device_printf(sc->sc_dev, "crypto enabling failed\n");
2262 +               goto fail;
2263 +       }
2264 +       hifn_reset_puc(sc);
2265 +
2266 +       hifn_init_dma(sc);
2267 +       hifn_init_pci_registers(sc);
2268 +
2269 +       pci_set_master(sc->sc_pcidev);
2270 +
2271 +       /* XXX can't dynamically determine ram type for 795x; force dram */
2272 +       if (sc->sc_flags & HIFN_IS_7956)
2273 +               sc->sc_drammodel = 1;
2274 +       else if (hifn_ramtype(sc))
2275 +               goto fail;
2276 +
2277 +       if (sc->sc_drammodel == 0)
2278 +               hifn_sramsize(sc);
2279 +       else
2280 +               hifn_dramsize(sc);
2281 +
2282 +       /*
2283 +        * Workaround for NetSec 7751 rev A: half ram size because two
2284 +        * of the address lines were left floating
2285 +        */
2286 +       if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
2287 +           pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
2288 +           pci_get_revid(dev) == 0x61) /*XXX???*/
2289 +               sc->sc_ramsize >>= 1;
2290 +
2291 +       /*
2292 +        * Arrange the interrupt line.
2293 +        */
2294 +       rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
2295 +       if (rc) {
2296 +               device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
2297 +               goto fail;
2298 +       }
2299 +       sc->sc_irq = dev->irq;
2300 +
2301 +       hifn_sessions(sc);
2302 +
2303 +       /*
2304 +        * NB: Keep only the low 16 bits; this masks the chip id
2305 +        *     from the 7951.
2306 +        */
2307 +       rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
2308 +
2309 +       rseg = sc->sc_ramsize / 1024;
2310 +       rbase = 'K';
2311 +       if (sc->sc_ramsize >= (1024 * 1024)) {
2312 +               rbase = 'M';
2313 +               rseg /= 1024;
2314 +       }
2315 +       device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
2316 +               hifn_partname(sc), rev,
2317 +               rseg, rbase, sc->sc_drammodel ? 'd' : 's');
2318 +       if (sc->sc_flags & HIFN_IS_7956)
2319 +               printf(", pll=0x%x<%s clk, %ux mult>",
2320 +                       sc->sc_pllconfig,
2321 +                       sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
2322 +                       2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
2323 +       printf("\n");
2324 +
2325 +       sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
2326 +       if (sc->sc_cid < 0) {
2327 +               device_printf(sc->sc_dev, "could not get crypto driver id\n");
2328 +               goto fail;
2329 +       }
2330 +
2331 +       WRITE_REG_0(sc, HIFN_0_PUCNFG,
2332 +           READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
2333 +       ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
2334 +
2335 +       switch (ena) {
2336 +       case HIFN_PUSTAT_ENA_2:
2337 +               crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
2338 +               crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
2339 +               if (sc->sc_flags & HIFN_HAS_AES)
2340 +                       crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
2341 +               /*FALLTHROUGH*/
2342 +       case HIFN_PUSTAT_ENA_1:
2343 +               crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
2344 +               crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
2345 +               crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
2346 +               crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
2347 +               crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
2348 +               break;
2349 +       }
2350 +
2351 +       if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
2352 +               hifn_init_pubrng(sc);
2353 +
2354 +       init_timer(&sc->sc_tickto);
2355 +       sc->sc_tickto.function = hifn_tick;
2356 +       sc->sc_tickto.data = (unsigned long) sc->sc_num;
2357 +       mod_timer(&sc->sc_tickto, jiffies + HZ);
2358 +
2359 +       return (0);
2360 +
2361 +fail:
2362 +    if (sc->sc_cid >= 0)
2363 +        crypto_unregister_all(sc->sc_cid);
2364 +    if (sc->sc_irq != -1)
2365 +        free_irq(sc->sc_irq, sc);
2366 +    if (sc->sc_dma) {
2367 +               /* Turn off DMA polling */
2368 +               WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
2369 +                       HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
2370 +
2371 +        pci_free_consistent(sc->sc_pcidev,
2372 +                               sizeof(*sc->sc_dma),
2373 +                sc->sc_dma, sc->sc_dma_physaddr);
2374 +       }
2375 +    kfree(sc);
2376 +       return (-ENXIO);
2377 +}
2378 +
2379 +/*
2380 + * Detach an interface that successfully probed.
2381 + */
2382 +static void
2383 +hifn_remove(struct pci_dev *dev)
2384 +{
2385 +       struct hifn_softc *sc = pci_get_drvdata(dev);
2386 +       unsigned long l_flags;
2387 +
2388 +       DPRINTF("%s()\n", __FUNCTION__);
2389 +
2390 +       KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
2391 +
2392 +       /* disable interrupts */
2393 +       HIFN_LOCK(sc);
2394 +       WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
2395 +       HIFN_UNLOCK(sc);
2396 +
2397 +       /*XXX other resources */
2398 +       del_timer_sync(&sc->sc_tickto);
2399 +
2400 +       /* Turn off DMA polling */
2401 +       WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
2402 +           HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
2403 +
2404 +       crypto_unregister_all(sc->sc_cid);
2405 +
2406 +       free_irq(sc->sc_irq, sc);
2407 +
2408 +       pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
2409 +                sc->sc_dma, sc->sc_dma_physaddr);
2410 +}
2411 +
2412 +
2413 +static int
2414 +hifn_init_pubrng(struct hifn_softc *sc)
2415 +{
2416 +       int i;
2417 +
2418 +       DPRINTF("%s()\n", __FUNCTION__);
2419 +
2420 +       if ((sc->sc_flags & HIFN_IS_7811) == 0) {
2421 +               /* Reset 7951 public key/rng engine */
2422 +               WRITE_REG_1(sc, HIFN_1_PUB_RESET,
2423 +                   READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
2424 +
2425 +               for (i = 0; i < 100; i++) {
2426 +                       DELAY(1000);
2427 +                       if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
2428 +                           HIFN_PUBRST_RESET) == 0)
2429 +                               break;
2430 +               }
2431 +
2432 +               if (i == 100) {
2433 +                       device_printf(sc->sc_dev, "public key init failed\n");
2434 +                       return (1);
2435 +               }
2436 +       }
2437 +
2438 +       /* Enable the rng, if available */
2439 +#ifdef CONFIG_OCF_RANDOMHARVEST
2440 +       if (sc->sc_flags & HIFN_HAS_RNG) {
2441 +               if (sc->sc_flags & HIFN_IS_7811) {
2442 +                       u_int32_t r;
2443 +                       r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
2444 +                       if (r & HIFN_7811_RNGENA_ENA) {
2445 +                               r &= ~HIFN_7811_RNGENA_ENA;
2446 +                               WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
2447 +                       }
2448 +                       WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
2449 +                           HIFN_7811_RNGCFG_DEFL);
2450 +                       r |= HIFN_7811_RNGENA_ENA;
2451 +                       WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
2452 +               } else
2453 +                       WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
2454 +                           READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
2455 +                           HIFN_RNGCFG_ENA);
2456 +
2457 +               sc->sc_rngfirst = 1;
2458 +               crypto_rregister(sc->sc_cid, hifn_read_random, sc);
2459 +       }
2460 +#endif
2461 +
2462 +       /* Enable public key engine, if available */
2463 +       if (sc->sc_flags & HIFN_HAS_PUBLIC) {
2464 +               WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
2465 +               sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
2466 +               WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
2467 +#ifdef HIFN_VULCANDEV
2468 +               sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
2469 +                                       UID_ROOT, GID_WHEEL, 0666,
2470 +                                       "vulcanpk");
2471 +               sc->sc_pkdev->si_drv1 = sc;
2472 +#endif
2473 +       }
2474 +
2475 +       return (0);
2476 +}
2477 +
2478 +#ifdef CONFIG_OCF_RANDOMHARVEST
2479 +static int
2480 +hifn_read_random(void *arg, u_int32_t *buf, int len)
2481 +{
2482 +       struct hifn_softc *sc = (struct hifn_softc *) arg;
2483 +       u_int32_t sts;
2484 +       int i, rc = 0;
2485 +
2486 +       if (len <= 0)
2487 +               return rc;
2488 +
2489 +       if (sc->sc_flags & HIFN_IS_7811) {
2490 +               /* ONLY VALID ON 7811!!!! */
2491 +               for (i = 0; i < 5; i++) {
2492 +                       sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
2493 +                       if (sts & HIFN_7811_RNGSTS_UFL) {
2494 +                               device_printf(sc->sc_dev,
2495 +                                             "RNG underflow: disabling\n");
2496 +                               /* DAVIDM perhaps return -1 */
2497 +                               break;
2498 +                       }
2499 +                       if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
2500 +                               break;
2501 +
2502 +                       /*
2503 +                        * There are at least two words in the RNG FIFO
2504 +                        * at this point.
2505 +                        */
2506 +                       if (rc < len)
2507 +                               buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
2508 +                       if (rc < len)
2509 +                               buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
2510 +               }
2511 +       } else
2512 +               buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
2513 +
2514 +       /* NB: discard first data read */
2515 +       if (sc->sc_rngfirst) {
2516 +               sc->sc_rngfirst = 0;
2517 +               rc = 0;
2518 +       }
2519 +
2520 +       return(rc);
2521 +}
2522 +#endif /* CONFIG_OCF_RANDOMHARVEST */
2523 +
2524 +static void
2525 +hifn_puc_wait(struct hifn_softc *sc)
2526 +{
2527 +       int i;
2528 +       int reg = HIFN_0_PUCTRL;
2529 +
2530 +       if (sc->sc_flags & HIFN_IS_7956) {
2531 +               reg = HIFN_0_PUCTRL2;
2532 +       }
2533 +
2534 +       for (i = 5000; i > 0; i--) {
2535 +               DELAY(1);
2536 +               if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
2537 +                       break;
2538 +       }
2539 +       if (!i)
2540 +               device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
2541 +                               READ_REG_0(sc, HIFN_0_PUCTRL));
2542 +}
2543 +
2544 +/*
2545 + * Reset the processing unit.
2546 + */
2547 +static void
2548 +hifn_reset_puc(struct hifn_softc *sc)
2549 +{
2550 +       /* Reset processing unit */
2551 +       int reg = HIFN_0_PUCTRL;
2552 +
2553 +       if (sc->sc_flags & HIFN_IS_7956) {
2554 +               reg = HIFN_0_PUCTRL2;
2555 +       }
2556 +       WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
2557 +
2558 +       hifn_puc_wait(sc);
2559 +}
2560 +
2561 +/*
2562 + * Set the Retry and TRDY registers; note that we set them to
2563 + * zero because the 7811 locks up when forced to retry (section
2564 + * 3.6 of "Specification Update SU-0014-04".  Not clear if we
2565 + * should do this for all Hifn parts, but it doesn't seem to hurt.
2566 + */
2567 +static void
2568 +hifn_set_retry(struct hifn_softc *sc)
2569 +{
2570 +       DPRINTF("%s()\n", __FUNCTION__);
2571 +       /* NB: RETRY only responds to 8-bit reads/writes */
2572 +       pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
2573 +       pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
2574 +}
2575 +
2576 +/*
2577 + * Resets the board.  Values in the regesters are left as is
2578 + * from the reset (i.e. initial values are assigned elsewhere).
2579 + */
2580 +static void
2581 +hifn_reset_board(struct hifn_softc *sc, int full)
2582 +{
2583 +       u_int32_t reg;
2584 +
2585 +       DPRINTF("%s()\n", __FUNCTION__);
2586 +       /*
2587 +        * Set polling in the DMA configuration register to zero.  0x7 avoids
2588 +        * resetting the board and zeros out the other fields.
2589 +        */
2590 +       WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
2591 +           HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
2592 +
2593 +       /*
2594 +        * Now that polling has been disabled, we have to wait 1 ms
2595 +        * before resetting the board.
2596 +        */
2597 +       DELAY(1000);
2598 +
2599 +       /* Reset the DMA unit */
2600 +       if (full) {
2601 +               WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
2602 +               DELAY(1000);
2603 +       } else {
2604 +               WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
2605 +                   HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
2606 +               hifn_reset_puc(sc);
2607 +       }
2608 +
2609 +       KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
2610 +       bzero(sc->sc_dma, sizeof(*sc->sc_dma));
2611 +
2612 +       /* Bring dma unit out of reset */
2613 +       WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
2614 +           HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
2615 +
2616 +       hifn_puc_wait(sc);
2617 +       hifn_set_retry(sc);
2618 +
2619 +       if (sc->sc_flags & HIFN_IS_7811) {
2620 +               for (reg = 0; reg < 1000; reg++) {
2621 +                       if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
2622 +                           HIFN_MIPSRST_CRAMINIT)
2623 +                               break;
2624 +                       DELAY(1000);
2625 +               }
2626 +               if (reg == 1000)
2627 +                       device_printf(sc->sc_dev, ": cram init timeout\n");
2628 +       } else {
2629 +         /* set up DMA configuration register #2 */
2630 +         /* turn off all PK and BAR0 swaps */
2631 +         WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
2632 +                     (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
2633 +                     (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
2634 +                     (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
2635 +                     (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
2636 +       }
2637 +}
2638 +
2639 +static u_int32_t
2640 +hifn_next_signature(u_int32_t a, u_int cnt)
2641 +{
2642 +       int i;
2643 +       u_int32_t v;
2644 +
2645 +       for (i = 0; i < cnt; i++) {
2646 +
2647 +               /* get the parity */
2648 +               v = a & 0x80080125;
2649 +               v ^= v >> 16;
2650 +               v ^= v >> 8;
2651 +               v ^= v >> 4;
2652 +               v ^= v >> 2;
2653 +               v ^= v >> 1;
2654 +
2655 +               a = (v & 1) ^ (a << 1);
2656 +       }
2657 +
2658 +       return a;
2659 +}
2660 +
2661 +
2662 +/*
2663 + * Checks to see if crypto is already enabled.  If crypto isn't enable,
2664 + * "hifn_enable_crypto" is called to enable it.  The check is important,
2665 + * as enabling crypto twice will lock the board.
2666 + */
2667 +static int
2668 +hifn_enable_crypto(struct hifn_softc *sc)
2669 +{
2670 +       u_int32_t dmacfg, ramcfg, encl, addr, i;
2671 +       char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2672 +                                         0x00, 0x00, 0x00, 0x00 };
2673 +
2674 +       DPRINTF("%s()\n", __FUNCTION__);
2675 +
2676 +       ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
2677 +       dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
2678 +
2679 +       /*
2680 +        * The RAM config register's encrypt level bit needs to be set before
2681 +        * every read performed on the encryption level register.
2682 +        */
2683 +       WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
2684 +
2685 +       encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
2686 +
2687 +       /*
2688 +        * Make sure we don't re-unlock.  Two unlocks kills chip until the
2689 +        * next reboot.
2690 +        */
2691 +       if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
2692 +#ifdef HIFN_DEBUG
2693 +               if (hifn_debug)
2694 +                       device_printf(sc->sc_dev,
2695 +                           "Strong crypto already enabled!\n");
2696 +#endif
2697 +               goto report;
2698 +       }
2699 +
2700 +       if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
2701 +#ifdef HIFN_DEBUG
2702 +               if (hifn_debug)
2703 +                       device_printf(sc->sc_dev,
2704 +                             "Unknown encryption level 0x%x\n", encl);
2705 +#endif
2706 +               return 1;
2707 +       }
2708 +
2709 +       WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
2710 +           HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
2711 +       DELAY(1000);
2712 +       addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
2713 +       DELAY(1000);
2714 +       WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
2715 +       DELAY(1000);
2716 +
2717 +       for (i = 0; i <= 12; i++) {
2718 +               addr = hifn_next_signature(addr, offtbl[i] + 0x101);
2719 +               WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
2720 +
2721 +               DELAY(1000);
2722 +       }
2723 +
2724 +       WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
2725 +       encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
2726 +
2727 +#ifdef HIFN_DEBUG
2728 +       if (hifn_debug) {
2729 +               if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
2730 +                       device_printf(sc->sc_dev, "Engine is permanently "
2731 +                               "locked until next system reset!\n");
2732 +               else
2733 +                       device_printf(sc->sc_dev, "Engine enabled "
2734 +                               "successfully!\n");
2735 +       }
2736 +#endif
2737 +
2738 +report:
2739 +       WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
2740 +       WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
2741 +
2742 +       switch (encl) {
2743 +       case HIFN_PUSTAT_ENA_1:
2744 +       case HIFN_PUSTAT_ENA_2:
2745 +               break;
2746 +       case HIFN_PUSTAT_ENA_0:
2747 +       default:
2748 +               device_printf(sc->sc_dev, "disabled\n");
2749 +               break;
2750 +       }
2751 +
2752 +       return 0;
2753 +}
2754 +
2755 +/*
2756 + * Give initial values to the registers listed in the "Register Space"
2757 + * section of the HIFN Software Development reference manual.
2758 + */
2759 +static void
2760 +hifn_init_pci_registers(struct hifn_softc *sc)
2761 +{
2762 +       DPRINTF("%s()\n", __FUNCTION__);
2763 +
2764 +       /* write fixed values needed by the Initialization registers */
2765 +       WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
2766 +       WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
2767 +       WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
2768 +
2769 +       /* write all 4 ring address registers */
2770 +       WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
2771 +           offsetof(struct hifn_dma, cmdr[0]));
2772 +       WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
2773 +           offsetof(struct hifn_dma, srcr[0]));
2774 +       WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
2775 +           offsetof(struct hifn_dma, dstr[0]));
2776 +       WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
2777 +           offsetof(struct hifn_dma, resr[0]));
2778 +
2779 +       DELAY(2000);
2780 +
2781 +       /* write status register */
2782 +       WRITE_REG_1(sc, HIFN_1_DMA_CSR,
2783 +           HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
2784 +           HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
2785 +           HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
2786 +           HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
2787 +           HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
2788 +           HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
2789 +           HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
2790 +           HIFN_DMACSR_S_WAIT |
2791 +           HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
2792 +           HIFN_DMACSR_C_WAIT |
2793 +           HIFN_DMACSR_ENGINE |
2794 +           ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
2795 +               HIFN_DMACSR_PUBDONE : 0) |
2796 +           ((sc->sc_flags & HIFN_IS_7811) ?
2797 +               HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
2798 +
2799 +       sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
2800 +       sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
2801 +           HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
2802 +           HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
2803 +           ((sc->sc_flags & HIFN_IS_7811) ?
2804 +               HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
2805 +       sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
2806 +       WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
2807 +
2808 +
2809 +       if (sc->sc_flags & HIFN_IS_7956) {
2810 +               u_int32_t pll;
2811 +
2812 +               WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
2813 +                   HIFN_PUCNFG_TCALLPHASES |
2814 +                   HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
2815 +
2816 +               /* turn off the clocks and insure bypass is set */
2817 +               pll = READ_REG_1(sc, HIFN_1_PLL);
2818 +               pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
2819 +                 | HIFN_PLL_BP | HIFN_PLL_MBSET;
2820 +               WRITE_REG_1(sc, HIFN_1_PLL, pll);
2821 +               DELAY(10*1000);         /* 10ms */
2822 +
2823 +               /* change configuration */
2824 +               pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
2825 +               WRITE_REG_1(sc, HIFN_1_PLL, pll);
2826 +               DELAY(10*1000);         /* 10ms */
2827 +
2828 +               /* disable bypass */
2829 +               pll &= ~HIFN_PLL_BP;
2830 +               WRITE_REG_1(sc, HIFN_1_PLL, pll);
2831 +               /* enable clocks with new configuration */
2832 +               pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
2833 +               WRITE_REG_1(sc, HIFN_1_PLL, pll);
2834 +       } else {
2835 +               WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
2836 +                   HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
2837 +                   HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
2838 +                   (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
2839 +       }
2840 +
2841 +       WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
2842 +       WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
2843 +           HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
2844 +           ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
2845 +           ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
2846 +}
2847 +
2848 +/*
2849 + * The maximum number of sessions supported by the card
2850 + * is dependent on the amount of context ram, which
2851 + * encryption algorithms are enabled, and how compression
2852 + * is configured.  This should be configured before this
2853 + * routine is called.
2854 + */
2855 +static void
2856 +hifn_sessions(struct hifn_softc *sc)
2857 +{
2858 +       u_int32_t pucnfg;
2859 +       int ctxsize;
2860 +
2861 +       DPRINTF("%s()\n", __FUNCTION__);
2862 +
2863 +       pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
2864 +
2865 +       if (pucnfg & HIFN_PUCNFG_COMPSING) {
2866 +               if (pucnfg & HIFN_PUCNFG_ENCCNFG)
2867 +                       ctxsize = 128;
2868 +               else
2869 +                       ctxsize = 512;
2870 +               /*
2871 +                * 7955/7956 has internal context memory of 32K
2872 +                */
2873 +               if (sc->sc_flags & HIFN_IS_7956)
2874 +                       sc->sc_maxses = 32768 / ctxsize;
2875 +               else
2876 +                       sc->sc_maxses = 1 +
2877 +                           ((sc->sc_ramsize - 32768) / ctxsize);
2878 +       } else
2879 +               sc->sc_maxses = sc->sc_ramsize / 16384;
2880 +
2881 +       if (sc->sc_maxses > 2048)
2882 +               sc->sc_maxses = 2048;
2883 +}
2884 +
2885 +/*
2886 + * Determine ram type (sram or dram).  Board should be just out of a reset
2887 + * state when this is called.
2888 + */
2889 +static int
2890 +hifn_ramtype(struct hifn_softc *sc)
2891 +{
2892 +       u_int8_t data[8], dataexpect[8];
2893 +       int i;
2894 +
2895 +       for (i = 0; i < sizeof(data); i++)
2896 +               data[i] = dataexpect[i] = 0x55;
2897 +       if (hifn_writeramaddr(sc, 0, data))
2898 +               return (-1);
2899 +       if (hifn_readramaddr(sc, 0, data))
2900 +               return (-1);
2901 +       if (bcmp(data, dataexpect, sizeof(data)) != 0) {
2902 +               sc->sc_drammodel = 1;
2903 +               return (0);
2904 +       }
2905 +
2906 +       for (i = 0; i < sizeof(data); i++)
2907 +               data[i] = dataexpect[i] = 0xaa;
2908 +       if (hifn_writeramaddr(sc, 0, data))
2909 +               return (-1);
2910 +       if (hifn_readramaddr(sc, 0, data))
2911 +               return (-1);
2912 +       if (bcmp(data, dataexpect, sizeof(data)) != 0) {
2913 +               sc->sc_drammodel = 1;
2914 +               return (0);
2915 +       }
2916 +
2917 +       return (0);
2918 +}
2919 +
2920 +#define        HIFN_SRAM_MAX           (32 << 20)
2921 +#define        HIFN_SRAM_STEP_SIZE     16384
2922 +#define        HIFN_SRAM_GRANULARITY   (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
2923 +
2924 +static int
2925 +hifn_sramsize(struct hifn_softc *sc)
2926 +{
2927 +       u_int32_t a;
2928 +       u_int8_t data[8];
2929 +       u_int8_t dataexpect[sizeof(data)];
2930 +       int32_t i;
2931 +
2932 +       for (i = 0; i < sizeof(data); i++)
2933 +               data[i] = dataexpect[i] = i ^ 0x5a;
2934 +
2935 +       for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
2936 +               a = i * HIFN_SRAM_STEP_SIZE;
2937 +               bcopy(&i, data, sizeof(i));
2938 +               hifn_writeramaddr(sc, a, data);
2939 +       }
2940 +
2941 +       for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
2942 +               a = i * HIFN_SRAM_STEP_SIZE;
2943 +               bcopy(&i, dataexpect, sizeof(i));
2944 +               if (hifn_readramaddr(sc, a, data) < 0)
2945 +                       return (0);
2946 +               if (bcmp(data, dataexpect, sizeof(data)) != 0)
2947 +                       return (0);
2948 +               sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
2949 +       }
2950 +
2951 +       return (0);
2952 +}
2953 +
2954 +/*
2955 + * XXX For dram boards, one should really try all of the
2956 + * HIFN_PUCNFG_DSZ_*'s.  This just assumes that PUCNFG
2957 + * is already set up correctly.
2958 + */
2959 +static int
2960 +hifn_dramsize(struct hifn_softc *sc)
2961 +{
2962 +       u_int32_t cnfg;
2963 +
2964 +       if (sc->sc_flags & HIFN_IS_7956) {
2965 +               /*
2966 +                * 7955/7956 have a fixed internal ram of only 32K.
2967 +                */
2968 +               sc->sc_ramsize = 32768;
2969 +       } else {
2970 +               cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
2971 +                   HIFN_PUCNFG_DRAMMASK;
2972 +               sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
2973 +       }
2974 +       return (0);
2975 +}
2976 +
2977 +static void
2978 +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
2979 +{
2980 +       struct hifn_dma *dma = sc->sc_dma;
2981 +
2982 +       DPRINTF("%s()\n", __FUNCTION__);
2983 +
2984 +       if (dma->cmdi == HIFN_D_CMD_RSIZE) {
2985 +               dma->cmdi = 0;
2986 +               dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
2987 +               wmb();
2988 +               dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
2989 +               HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
2990 +                   BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2991 +       }
2992 +       *cmdp = dma->cmdi++;
2993 +       dma->cmdk = dma->cmdi;
2994 +
2995 +       if (dma->srci == HIFN_D_SRC_RSIZE) {
2996 +               dma->srci = 0;
2997 +               dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
2998 +               wmb();
2999 +               dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
3000 +               HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
3001 +                   BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3002 +       }
3003 +       *srcp = dma->srci++;
3004 +       dma->srck = dma->srci;
3005 +
3006 +       if (dma->dsti == HIFN_D_DST_RSIZE) {
3007 +               dma->dsti = 0;
3008 +               dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
3009 +               wmb();
3010 +               dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
3011 +               HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
3012 +                   BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3013 +       }
3014 +       *dstp = dma->dsti++;
3015 +       dma->dstk = dma->dsti;
3016 +
3017 +       if (dma->resi == HIFN_D_RES_RSIZE) {
3018 +               dma->resi = 0;
3019 +               dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
3020 +               wmb();
3021 +               dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
3022 +               HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
3023 +                   BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3024 +       }
3025 +       *resp = dma->resi++;
3026 +       dma->resk = dma->resi;
3027 +}
3028 +
3029 +static int
3030 +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
3031 +{
3032 +       struct hifn_dma *dma = sc->sc_dma;
3033 +       hifn_base_command_t wc;
3034 +       const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
3035 +       int r, cmdi, resi, srci, dsti;
3036 +
3037 +       DPRINTF("%s()\n", __FUNCTION__);
3038 +
3039 +       wc.masks = htole16(3 << 13);
3040 +       wc.session_num = htole16(addr >> 14);
3041 +       wc.total_source_count = htole16(8);
3042 +       wc.total_dest_count = htole16(addr & 0x3fff);
3043 +
3044 +       hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
3045 +
3046 +       WRITE_REG_1(sc, HIFN_1_DMA_CSR,
3047 +           HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
3048 +           HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
3049 +
3050 +       /* build write command */
3051 +       bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
3052 +       *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
3053 +       bcopy(data, &dma->test_src, sizeof(dma->test_src));
3054 +
3055 +       dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
3056 +           + offsetof(struct hifn_dma, test_src));
3057 +       dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
3058 +           + offsetof(struct hifn_dma, test_dst));
3059 +
3060 +       dma->cmdr[cmdi].l = htole32(16 | masks);
3061 +       dma->srcr[srci].l = htole32(8 | masks);
3062 +       dma->dstr[dsti].l = htole32(4 | masks);
3063 +       dma->resr[resi].l = htole32(4 | masks);
3064 +
3065 +       for (r = 10000; r >= 0; r--) {
3066 +               DELAY(10);
3067 +               if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
3068 +                       break;
3069 +       }
3070 +       if (r == 0) {
3071 +               device_printf(sc->sc_dev, "writeramaddr -- "
3072 +                   "result[%d](addr %d) still valid\n", resi, addr);
3073 +               r = -1;
3074 +               return (-1);
3075 +       } else
3076 +               r = 0;
3077 +
3078 +       WRITE_REG_1(sc, HIFN_1_DMA_CSR,
3079 +           HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
3080 +           HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
3081 +
3082 +       return (r);
3083 +}
3084 +
3085 +static int
3086 +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
3087 +{
3088 +       struct hifn_dma *dma = sc->sc_dma;
3089 +       hifn_base_command_t rc;
3090 +       const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
3091 +       int r, cmdi, srci, dsti, resi;
3092 +
3093 +       DPRINTF("%s()\n", __FUNCTION__);
3094 +
3095 +       rc.masks = htole16(2 << 13);
3096 +       rc.session_num = htole16(addr >> 14);
3097 +       rc.total_source_count = htole16(addr & 0x3fff);
3098 +       rc.total_dest_count = htole16(8);
3099 +
3100 +       hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
3101 +
3102 +       WRITE_REG_1(sc, HIFN_1_DMA_CSR,
3103 +           HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
3104 +           HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
3105 +
3106 +       bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
3107 +       *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
3108 +
3109 +       dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
3110 +           offsetof(struct hifn_dma, test_src));
3111 +       dma->test_src = 0;
3112 +       dma->dstr[dsti].p =  htole32(sc->sc_dma_physaddr +
3113 +           offsetof(struct hifn_dma, test_dst));
3114 +       dma->test_dst = 0;
3115 +       dma->cmdr[cmdi].l = htole32(8 | masks);
3116 +       dma->srcr[srci].l = htole32(8 | masks);
3117 +       dma->dstr[dsti].l = htole32(8 | masks);
3118 +       dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
3119 +
3120 +       for (r = 10000; r >= 0; r--) {
3121 +               DELAY(10);
3122 +               if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
3123 +                       break;
3124 +       }
3125 +       if (r == 0) {
3126 +               device_printf(sc->sc_dev, "readramaddr -- "
3127 +                   "result[%d](addr %d) still valid\n", resi, addr);
3128 +               r = -1;
3129 +       } else {
3130 +               r = 0;
3131 +               bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
3132 +       }
3133 +
3134 +       WRITE_REG_1(sc, HIFN_1_DMA_CSR,
3135 +           HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
3136 +           HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
3137 +
3138 +       return (r);
3139 +}
3140 +
3141 +/*
3142 + * Initialize the descriptor rings.
3143 + */
3144 +static void
3145 +hifn_init_dma(struct hifn_softc *sc)
3146 +{
3147 +       struct hifn_dma *dma = sc->sc_dma;
3148 +       int i;
3149 +
3150 +       DPRINTF("%s()\n", __FUNCTION__);
3151 +
3152 +       hifn_set_retry(sc);
3153 +
3154 +       /* initialize static pointer values */
3155 +       for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
3156 +               dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
3157 +                   offsetof(struct hifn_dma, command_bufs[i][0]));
3158 +       for (i = 0; i < HIFN_D_RES_RSIZE; i++)
3159 +               dma->resr[i].p = htole32(sc->sc_dma_physaddr +
3160 +                   offsetof(struct hifn_dma, result_bufs[i][0]));
3161 +
3162 +       dma->cmdr[HIFN_D_CMD_RSIZE].p =
3163 +           htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
3164 +       dma->srcr[HIFN_D_SRC_RSIZE].p =
3165 +           htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
3166 +       dma->dstr[HIFN_D_DST_RSIZE].p =
3167 +           htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
3168 +       dma->resr[HIFN_D_RES_RSIZE].p =
3169 +           htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
3170 +
3171 +       dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
3172 +       dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
3173 +       dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
3174 +}
3175 +
3176 +/*
3177 + * Writes out the raw command buffer space.  Returns the
3178 + * command buffer size.
3179 + */
3180 +static u_int
3181 +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
3182 +{
3183 +       struct hifn_softc *sc = NULL;
3184 +       u_int8_t *buf_pos;
3185 +       hifn_base_command_t *base_cmd;
3186 +       hifn_mac_command_t *mac_cmd;
3187 +       hifn_crypt_command_t *cry_cmd;
3188 +       int using_mac, using_crypt, len, ivlen;
3189 +       u_int32_t dlen, slen;
3190 +
3191 +       DPRINTF("%s()\n", __FUNCTION__);
3192 +
3193 +       buf_pos = buf;
3194 +       using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
3195 +       using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
3196 +
3197 +       base_cmd = (hifn_base_command_t *)buf_pos;
3198 +       base_cmd->masks = htole16(cmd->base_masks);
3199 +       slen = cmd->src_mapsize;
3200 +       if (cmd->sloplen)
3201 +               dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
3202 +       else
3203 +               dlen = cmd->dst_mapsize;
3204 +       base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
3205 +       base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
3206 +       dlen >>= 16;
3207 +       slen >>= 16;
3208 +       base_cmd->session_num = htole16(
3209 +           ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
3210 +           ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
3211 +       buf_pos += sizeof(hifn_base_command_t);
3212 +
3213 +       if (using_mac) {
3214 +               mac_cmd = (hifn_mac_command_t *)buf_pos;
3215 +               dlen = cmd->maccrd->crd_len;
3216 +               mac_cmd->source_count = htole16(dlen & 0xffff);
3217 +               dlen >>= 16;
3218 +               mac_cmd->masks = htole16(cmd->mac_masks |
3219 +                   ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
3220 +               mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
3221 +               mac_cmd->reserved = 0;
3222 +               buf_pos += sizeof(hifn_mac_command_t);
3223 +       }
3224 +
3225 +       if (using_crypt) {
3226 +               cry_cmd = (hifn_crypt_command_t *)buf_pos;
3227 +               dlen = cmd->enccrd->crd_len;
3228 +               cry_cmd->source_count = htole16(dlen & 0xffff);
3229 +               dlen >>= 16;
3230 +               cry_cmd->masks = htole16(cmd->cry_masks |
3231 +                   ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
3232 +               cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
3233 +               cry_cmd->reserved = 0;
3234 +               buf_pos += sizeof(hifn_crypt_command_t);
3235 +       }
3236 +
3237 +       if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
3238 +               bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
3239 +               buf_pos += HIFN_MAC_KEY_LENGTH;
3240 +       }
3241 +
3242 +       if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
3243 +               switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
3244 +               case HIFN_CRYPT_CMD_ALG_3DES:
3245 +                       bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
3246 +                       buf_pos += HIFN_3DES_KEY_LENGTH;
3247 +                       break;
3248 +               case HIFN_CRYPT_CMD_ALG_DES:
3249 +                       bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
3250 +                       buf_pos += HIFN_DES_KEY_LENGTH;
3251 +                       break;
3252 +               case HIFN_CRYPT_CMD_ALG_RC4:
3253 +                       len = 256;
3254 +                       do {
3255 +                               int clen;
3256 +
3257 +                               clen = MIN(cmd->cklen, len);
3258 +                               bcopy(cmd->ck, buf_pos, clen);
3259 +                               len -= clen;
3260 +                               buf_pos += clen;
3261 +                       } while (len > 0);
3262 +                       bzero(buf_pos, 4);
3263 +                       buf_pos += 4;
3264 +                       break;
3265 +               case HIFN_CRYPT_CMD_ALG_AES:
3266 +                       /*
3267 +                        * AES keys are variable 128, 192 and
3268 +                        * 256 bits (16, 24 and 32 bytes).
3269 +                        */
3270 +                       bcopy(cmd->ck, buf_pos, cmd->cklen);
3271 +                       buf_pos += cmd->cklen;
3272 +                       break;
3273 +               }
3274 +       }
3275 +
3276 +       if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
3277 +               switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
3278 +               case HIFN_CRYPT_CMD_ALG_AES:
3279 +                       ivlen = HIFN_AES_IV_LENGTH;
3280 +                       break;
3281 +               default:
3282 +                       ivlen = HIFN_IV_LENGTH;
3283 +                       break;
3284 +               }
3285 +               bcopy(cmd->iv, buf_pos, ivlen);
3286 +               buf_pos += ivlen;
3287 +       }
3288 +
3289 +       if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
3290 +               bzero(buf_pos, 8);
3291 +               buf_pos += 8;
3292 +       }
3293 +
3294 +       return (buf_pos - buf);
3295 +}
3296 +
3297 +static int
3298 +hifn_dmamap_aligned(struct hifn_operand *op)
3299 +{
3300 +       struct hifn_softc *sc = NULL;
3301 +       int i;
3302 +
3303 +       DPRINTF("%s()\n", __FUNCTION__);
3304 +
3305 +       for (i = 0; i < op->nsegs; i++) {
3306 +               if (op->segs[i].ds_addr & 3)
3307 +                       return (0);
3308 +               if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
3309 +                       return (0);
3310 +       }
3311 +       return (1);
3312 +}
3313 +
3314 +static __inline int
3315 +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
3316 +{
3317 +       struct hifn_dma *dma = sc->sc_dma;
3318 +
3319 +       if (++idx == HIFN_D_DST_RSIZE) {
3320 +               dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
3321 +                   HIFN_D_MASKDONEIRQ);
3322 +               HIFN_DSTR_SYNC(sc, idx,
3323 +                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3324 +               idx = 0;
3325 +       }
3326 +       return (idx);
3327 +}
3328 +
3329 +static int
3330 +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
3331 +{
3332 +       struct hifn_dma *dma = sc->sc_dma;
3333 +       struct hifn_operand *dst = &cmd->dst;
3334 +       u_int32_t p, l;
3335 +       int idx, used = 0, i;
3336 +
3337 +       DPRINTF("%s()\n", __FUNCTION__);
3338 +
3339 +       idx = dma->dsti;
3340 +       for (i = 0; i < dst->nsegs - 1; i++) {
3341 +               dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
3342 +               dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
3343 +               wmb();
3344 +               dma->dstr[idx].l |= htole32(HIFN_D_VALID);
3345 +               HIFN_DSTR_SYNC(sc, idx,
3346 +                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3347 +               used++;
3348 +
3349 +               idx = hifn_dmamap_dstwrap(sc, idx);
3350 +       }
3351 +
3352 +       if (cmd->sloplen == 0) {
3353 +               p = dst->segs[i].ds_addr;
3354 +               l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
3355 +                   dst->segs[i].ds_len;
3356 +       } else {
3357 +               p = sc->sc_dma_physaddr +
3358 +                   offsetof(struct hifn_dma, slop[cmd->slopidx]);
3359 +               l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
3360 +                   sizeof(u_int32_t);
3361 +
3362 +               if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
3363 +                       dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
3364 +                       dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
3365 +                           (dst->segs[i].ds_len - cmd->sloplen));
3366 +                       wmb();
3367 +                       dma->dstr[idx].l |= htole32(HIFN_D_VALID);
3368 +                       HIFN_DSTR_SYNC(sc, idx,
3369 +                           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3370 +                       used++;
3371 +
3372 +                       idx = hifn_dmamap_dstwrap(sc, idx);
3373 +               }
3374 +       }
3375 +       dma->dstr[idx].p = htole32(p);
3376 +       dma->dstr[idx].l = htole32(l);
3377 +       wmb();
3378 +       dma->dstr[idx].l |= htole32(HIFN_D_VALID);
3379 +       HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3380 +       used++;
3381 +
3382 +       idx = hifn_dmamap_dstwrap(sc, idx);
3383 +
3384 +       dma->dsti = idx;
3385 +       dma->dstu += used;
3386 +       return (idx);
3387 +}
3388 +
3389 +static __inline int
3390 +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
3391 +{
3392 +       struct hifn_dma *dma = sc->sc_dma;
3393 +
3394 +       if (++idx == HIFN_D_SRC_RSIZE) {
3395 +               dma->srcr[idx].l = htole32(HIFN_D_VALID |
3396 +                   HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
3397 +               HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
3398 +                   BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3399 +               idx = 0;
3400 +       }
3401 +       return (idx);
3402 +}
3403 +
3404 +static int
3405 +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
3406 +{
3407 +       struct hifn_dma *dma = sc->sc_dma;
3408 +       struct hifn_operand *src = &cmd->src;
3409 +       int idx, i;
3410 +       u_int32_t last = 0;
3411 +
3412 +       DPRINTF("%s()\n", __FUNCTION__);
3413 +
3414 +       idx = dma->srci;
3415 +       for (i = 0; i < src->nsegs; i++) {
3416 +               if (i == src->nsegs - 1)
3417 +                       last = HIFN_D_LAST;
3418 +
3419 +               dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
3420 +               dma->srcr[idx].l = htole32(src->segs[i].ds_len |
3421 +                   HIFN_D_MASKDONEIRQ | last);
3422 +               wmb();
3423 +               dma->srcr[idx].l |= htole32(HIFN_D_VALID);
3424 +               HIFN_SRCR_SYNC(sc, idx,
3425 +                   BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3426 +
3427 +               idx = hifn_dmamap_srcwrap(sc, idx);
3428 +       }
3429 +       dma->srci = idx;
3430 +       dma->srcu += src->nsegs;
3431 +       return (idx);
3432 +}
3433 +
3434 +
3435 +static int
3436 +hifn_crypto(
3437 +       struct hifn_softc *sc,
3438 +       struct hifn_command *cmd,
3439 +       struct cryptop *crp,
3440 +       int hint)
3441 +{
3442 +       struct  hifn_dma *dma = sc->sc_dma;
3443 +       u_int32_t cmdlen, csr;
3444 +       int cmdi, resi, err = 0;
3445 +       unsigned long l_flags;