1 /* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
4 * Invertex AEON / Hifn 7751 driver
5 * Copyright (c) 1999 Invertex Inc. All rights reserved.
6 * Copyright (c) 1999 Theo de Raadt
7 * Copyright (c) 2000-2001 Network Security Technologies, Inc.
8 * http://www.netsec.net
9 * Copyright (c) 2003 Hifn Inc.
11 * This driver is based on a previous driver by Invertex, for which they
12 * requested: Please send any comments, feedback, bug-fixes, or feature
13 * requests to software@invertex.com.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. The name of the author may not be used to endorse or promote products
25 * derived from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Effort sponsored in part by the Defense Advanced Research Projects
39 * Agency (DARPA) and Air Force Research Laboratory, Air Force
40 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
43 __FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
47 * Driver for various Hifn encryption processors.
49 #ifndef AUTOCONF_INCLUDED
50 #include <linux/config.h>
52 #include <linux/module.h>
53 #include <linux/init.h>
54 #include <linux/list.h>
55 #include <linux/slab.h>
56 #include <linux/wait.h>
57 #include <linux/sched.h>
58 #include <linux/pci.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h>
61 #include <linux/spinlock.h>
62 #include <linux/random.h>
63 #include <linux/version.h>
64 #include <linux/skbuff.h>
67 #include <cryptodev.h>
69 #include <hifn/hifn7751reg.h>
70 #include <hifn/hifn7751var.h>
73 #define DPRINTF(a...) if (hifn_debug) { \
75 device_get_nameunit(sc->sc_dev) : "hifn"); \
83 pci_get_revid(struct pci_dev
*dev
)
86 pci_read_config_byte(dev
, PCI_REVISION_ID
, &rid
);
90 static struct hifn_stats hifnstats
;
92 #define debug hifn_debug
94 module_param(hifn_debug
, int, 0644);
95 MODULE_PARM_DESC(hifn_debug
, "Enable debug");
97 int hifn_maxbatch
= 1;
98 module_param(hifn_maxbatch
, int, 0644);
99 MODULE_PARM_DESC(hifn_maxbatch
, "max ops to batch w/o interrupt");
101 int hifn_cache_linesize
= 0x10;
102 module_param(hifn_cache_linesize
, int, 0444);
103 MODULE_PARM_DESC(hifn_cache_linesize
, "PCI config cache line size");
106 char *hifn_pllconfig
= NULL
;
107 MODULE_PARM(hifn_pllconfig
, "s");
109 char hifn_pllconfig
[32]; /* This setting is RO after loading */
110 module_param_string(hifn_pllconfig
, hifn_pllconfig
, 32, 0444);
112 MODULE_PARM_DESC(hifn_pllconfig
, "PLL config, ie., pci66, ext33, ...");
114 #ifdef HIFN_VULCANDEV
115 #include <sys/conf.h>
118 static struct cdevsw vulcanpk_cdevsw
; /* forward declaration */
122 * Prototypes and count for the pci_device structure
124 static int hifn_probe(struct pci_dev
*dev
, const struct pci_device_id
*ent
);
125 static void hifn_remove(struct pci_dev
*dev
);
127 static int hifn_newsession(device_t
, u_int32_t
*, struct cryptoini
*);
128 static int hifn_freesession(device_t
, u_int64_t
);
129 static int hifn_process(device_t
, struct cryptop
*, int);
131 static device_method_t hifn_methods
= {
132 /* crypto device methods */
133 DEVMETHOD(cryptodev_newsession
, hifn_newsession
),
134 DEVMETHOD(cryptodev_freesession
,hifn_freesession
),
135 DEVMETHOD(cryptodev_process
, hifn_process
),
138 static void hifn_reset_board(struct hifn_softc
*, int);
139 static void hifn_reset_puc(struct hifn_softc
*);
140 static void hifn_puc_wait(struct hifn_softc
*);
141 static int hifn_enable_crypto(struct hifn_softc
*);
142 static void hifn_set_retry(struct hifn_softc
*sc
);
143 static void hifn_init_dma(struct hifn_softc
*);
144 static void hifn_init_pci_registers(struct hifn_softc
*);
145 static int hifn_sramsize(struct hifn_softc
*);
146 static int hifn_dramsize(struct hifn_softc
*);
147 static int hifn_ramtype(struct hifn_softc
*);
148 static void hifn_sessions(struct hifn_softc
*);
149 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
150 static irqreturn_t
hifn_intr(int irq
, void *arg
);
152 static irqreturn_t
hifn_intr(int irq
, void *arg
, struct pt_regs
*regs
);
154 static u_int
hifn_write_command(struct hifn_command
*, u_int8_t
*);
155 static u_int32_t
hifn_next_signature(u_int32_t a
, u_int cnt
);
156 static void hifn_callback(struct hifn_softc
*, struct hifn_command
*, u_int8_t
*);
157 static int hifn_crypto(struct hifn_softc
*, struct hifn_command
*, struct cryptop
*, int);
158 static int hifn_readramaddr(struct hifn_softc
*, int, u_int8_t
*);
159 static int hifn_writeramaddr(struct hifn_softc
*, int, u_int8_t
*);
160 static int hifn_dmamap_load_src(struct hifn_softc
*, struct hifn_command
*);
161 static int hifn_dmamap_load_dst(struct hifn_softc
*, struct hifn_command
*);
162 static int hifn_init_pubrng(struct hifn_softc
*);
163 static void hifn_tick(unsigned long arg
);
164 static void hifn_abort(struct hifn_softc
*);
165 static void hifn_alloc_slot(struct hifn_softc
*, int *, int *, int *, int *);
167 static void hifn_write_reg_0(struct hifn_softc
*, bus_size_t
, u_int32_t
);
168 static void hifn_write_reg_1(struct hifn_softc
*, bus_size_t
, u_int32_t
);
170 #ifdef CONFIG_OCF_RANDOMHARVEST
171 static int hifn_read_random(void *arg
, u_int32_t
*buf
, int len
);
174 #define HIFN_MAX_CHIPS 8
175 static struct hifn_softc
*hifn_chip_idx
[HIFN_MAX_CHIPS
];
177 static __inline u_int32_t
178 READ_REG_0(struct hifn_softc
*sc
, bus_size_t reg
)
180 u_int32_t v
= readl(sc
->sc_bar0
+ reg
);
181 sc
->sc_bar0_lastreg
= (bus_size_t
) -1;
184 #define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
186 static __inline u_int32_t
187 READ_REG_1(struct hifn_softc
*sc
, bus_size_t reg
)
189 u_int32_t v
= readl(sc
->sc_bar1
+ reg
);
190 sc
->sc_bar1_lastreg
= (bus_size_t
) -1;
193 #define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
196 * map in a given buffer (great on some arches :-)
200 pci_map_uio(struct hifn_softc
*sc
, struct hifn_operand
*buf
, struct uio
*uio
)
202 struct iovec
*iov
= uio
->uio_iov
;
204 DPRINTF("%s()\n", __FUNCTION__
);
207 for (buf
->nsegs
= 0; buf
->nsegs
< uio
->uio_iovcnt
; ) {
208 buf
->segs
[buf
->nsegs
].ds_addr
= pci_map_single(sc
->sc_pcidev
,
209 iov
->iov_base
, iov
->iov_len
,
210 PCI_DMA_BIDIRECTIONAL
);
211 buf
->segs
[buf
->nsegs
].ds_len
= iov
->iov_len
;
212 buf
->mapsize
+= iov
->iov_len
;
216 /* identify this buffer by the first segment */
217 buf
->map
= (void *) buf
->segs
[0].ds_addr
;
222 * map in a given sk_buff
226 pci_map_skb(struct hifn_softc
*sc
,struct hifn_operand
*buf
,struct sk_buff
*skb
)
230 DPRINTF("%s()\n", __FUNCTION__
);
234 buf
->segs
[0].ds_addr
= pci_map_single(sc
->sc_pcidev
,
235 skb
->data
, skb_headlen(skb
), PCI_DMA_BIDIRECTIONAL
);
236 buf
->segs
[0].ds_len
= skb_headlen(skb
);
237 buf
->mapsize
+= buf
->segs
[0].ds_len
;
241 for (i
= 0; i
< skb_shinfo(skb
)->nr_frags
; ) {
242 buf
->segs
[buf
->nsegs
].ds_len
= skb_shinfo(skb
)->frags
[i
].size
;
243 buf
->segs
[buf
->nsegs
].ds_addr
= pci_map_single(sc
->sc_pcidev
,
244 page_address(skb_shinfo(skb
)->frags
[i
].page
) +
245 skb_shinfo(skb
)->frags
[i
].page_offset
,
246 buf
->segs
[buf
->nsegs
].ds_len
, PCI_DMA_BIDIRECTIONAL
);
247 buf
->mapsize
+= buf
->segs
[buf
->nsegs
].ds_len
;
251 /* identify this buffer by the first segment */
252 buf
->map
= (void *) buf
->segs
[0].ds_addr
;
257 * map in a given contiguous buffer
261 pci_map_buf(struct hifn_softc
*sc
,struct hifn_operand
*buf
, void *b
, int len
)
263 DPRINTF("%s()\n", __FUNCTION__
);
266 buf
->segs
[0].ds_addr
= pci_map_single(sc
->sc_pcidev
,
267 b
, len
, PCI_DMA_BIDIRECTIONAL
);
268 buf
->segs
[0].ds_len
= len
;
269 buf
->mapsize
+= buf
->segs
[0].ds_len
;
272 /* identify this buffer by the first segment */
273 buf
->map
= (void *) buf
->segs
[0].ds_addr
;
277 #if 0 /* not needed at this time */
279 pci_sync_iov(struct hifn_softc
*sc
, struct hifn_operand
*buf
)
283 DPRINTF("%s()\n", __FUNCTION__
);
284 for (i
= 0; i
< buf
->nsegs
; i
++)
285 pci_dma_sync_single_for_cpu(sc
->sc_pcidev
, buf
->segs
[i
].ds_addr
,
286 buf
->segs
[i
].ds_len
, PCI_DMA_BIDIRECTIONAL
);
291 pci_unmap_buf(struct hifn_softc
*sc
, struct hifn_operand
*buf
)
294 DPRINTF("%s()\n", __FUNCTION__
);
295 for (i
= 0; i
< buf
->nsegs
; i
++) {
296 pci_unmap_single(sc
->sc_pcidev
, buf
->segs
[i
].ds_addr
,
297 buf
->segs
[i
].ds_len
, PCI_DMA_BIDIRECTIONAL
);
298 buf
->segs
[i
].ds_addr
= 0;
299 buf
->segs
[i
].ds_len
= 0;
307 hifn_partname(struct hifn_softc
*sc
)
309 /* XXX sprintf numbers when not decoded */
310 switch (pci_get_vendor(sc
->sc_pcidev
)) {
311 case PCI_VENDOR_HIFN
:
312 switch (pci_get_device(sc
->sc_pcidev
)) {
313 case PCI_PRODUCT_HIFN_6500
: return "Hifn 6500";
314 case PCI_PRODUCT_HIFN_7751
: return "Hifn 7751";
315 case PCI_PRODUCT_HIFN_7811
: return "Hifn 7811";
316 case PCI_PRODUCT_HIFN_7951
: return "Hifn 7951";
317 case PCI_PRODUCT_HIFN_7955
: return "Hifn 7955";
318 case PCI_PRODUCT_HIFN_7956
: return "Hifn 7956";
320 return "Hifn unknown-part";
321 case PCI_VENDOR_INVERTEX
:
322 switch (pci_get_device(sc
->sc_pcidev
)) {
323 case PCI_PRODUCT_INVERTEX_AEON
: return "Invertex AEON";
325 return "Invertex unknown-part";
326 case PCI_VENDOR_NETSEC
:
327 switch (pci_get_device(sc
->sc_pcidev
)) {
328 case PCI_PRODUCT_NETSEC_7751
: return "NetSec 7751";
330 return "NetSec unknown-part";
332 return "Unknown-vendor unknown-part";
336 checkmaxmin(struct pci_dev
*dev
, const char *what
, u_int v
, u_int min
, u_int max
)
338 struct hifn_softc
*sc
= pci_get_drvdata(dev
);
340 device_printf(sc
->sc_dev
, "Warning, %s %u out of range, "
341 "using max %u\n", what
, v
, max
);
343 } else if (v
< min
) {
344 device_printf(sc
->sc_dev
, "Warning, %s %u out of range, "
345 "using min %u\n", what
, v
, min
);
352 * Select PLL configuration for 795x parts. This is complicated in
353 * that we cannot determine the optimal parameters without user input.
354 * The reference clock is derived from an external clock through a
355 * multiplier. The external clock is either the host bus (i.e. PCI)
356 * or an external clock generator. When using the PCI bus we assume
357 * the clock is either 33 or 66 MHz; for an external source we cannot
360 * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
361 * for an external source, followed by the frequency. We calculate
362 * the appropriate multiplier and PLL register contents accordingly.
363 * When no configuration is given we default to "pci66" since that
364 * always will allow the card to work. If a card is using the PCI
365 * bus clock and in a 33MHz slot then it will be operating at half
366 * speed until the correct information is provided.
368 * We use a default setting of "ext66" because according to Mike Ham
369 * of HiFn, almost every board in existence has an external crystal
370 * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
371 * because PCI33 can have clocks from 0 to 33Mhz, and some have
372 * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
375 hifn_getpllconfig(struct pci_dev
*dev
, u_int
*pll
)
377 const char *pllspec
= hifn_pllconfig
;
378 u_int freq
, mul
, fl
, fh
;
386 if (strncmp(pllspec
, "ext", 3) == 0) {
388 pllconfig
|= HIFN_PLL_REF_SEL
;
389 switch (pci_get_device(dev
)) {
390 case PCI_PRODUCT_HIFN_7955
:
391 case PCI_PRODUCT_HIFN_7956
:
395 case PCI_PRODUCT_HIFN_7954
:
400 } else if (strncmp(pllspec
, "pci", 3) == 0)
402 freq
= strtoul(pllspec
, &nxt
, 10);
406 freq
= checkmaxmin(dev
, "frequency", freq
, fl
, fh
);
408 * Calculate multiplier. We target a Fck of 266 MHz,
409 * allowing only even values, possibly rounded down.
410 * Multipliers > 8 must set the charge pump current.
412 mul
= checkmaxmin(dev
, "PLL divisor", (266 / freq
) &~ 1, 2, 12);
413 pllconfig
|= (mul
/ 2 - 1) << HIFN_PLL_ND_SHIFT
;
415 pllconfig
|= HIFN_PLL_IS
;
420 * Attach an interface that successfully probed.
423 hifn_probe(struct pci_dev
*dev
, const struct pci_device_id
*ent
)
425 struct hifn_softc
*sc
= NULL
;
429 unsigned long mem_start
, mem_len
;
430 static int num_chips
= 0;
432 DPRINTF("%s()\n", __FUNCTION__
);
434 if (pci_enable_device(dev
) < 0)
437 #ifdef CONFIG_HAVE_PCI_SET_MWI
438 if (pci_set_mwi(dev
))
443 printk("hifn: found device with no IRQ assigned. check BIOS settings!");
444 pci_disable_device(dev
);
448 sc
= (struct hifn_softc
*) kmalloc(sizeof(*sc
), GFP_KERNEL
);
451 memset(sc
, 0, sizeof(*sc
));
453 softc_device_init(sc
, "hifn", num_chips
, hifn_methods
);
458 sc
->sc_num
= num_chips
++;
459 if (sc
->sc_num
< HIFN_MAX_CHIPS
)
460 hifn_chip_idx
[sc
->sc_num
] = sc
;
462 pci_set_drvdata(sc
->sc_pcidev
, sc
);
464 spin_lock_init(&sc
->sc_mtx
);
466 /* XXX handle power management */
469 * The 7951 and 795x have a random number generator and
470 * public key support; note this.
472 if (pci_get_vendor(dev
) == PCI_VENDOR_HIFN
&&
473 (pci_get_device(dev
) == PCI_PRODUCT_HIFN_7951
||
474 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7955
||
475 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7956
))
476 sc
->sc_flags
= HIFN_HAS_RNG
| HIFN_HAS_PUBLIC
;
478 * The 7811 has a random number generator and
479 * we also note it's identity 'cuz of some quirks.
481 if (pci_get_vendor(dev
) == PCI_VENDOR_HIFN
&&
482 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7811
)
483 sc
->sc_flags
|= HIFN_IS_7811
| HIFN_HAS_RNG
;
486 * The 795x parts support AES.
488 if (pci_get_vendor(dev
) == PCI_VENDOR_HIFN
&&
489 (pci_get_device(dev
) == PCI_PRODUCT_HIFN_7955
||
490 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7956
)) {
491 sc
->sc_flags
|= HIFN_IS_7956
| HIFN_HAS_AES
;
493 * Select PLL configuration. This depends on the
494 * bus and board design and must be manually configured
495 * if the default setting is unacceptable.
497 hifn_getpllconfig(dev
, &sc
->sc_pllconfig
);
501 * Setup PCI resources. Note that we record the bus
502 * tag and handle for each register mapping, this is
503 * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
504 * and WRITE_REG_1 macros throughout the driver.
506 mem_start
= pci_resource_start(sc
->sc_pcidev
, 0);
507 mem_len
= pci_resource_len(sc
->sc_pcidev
, 0);
508 sc
->sc_bar0
= (ocf_iomem_t
) ioremap(mem_start
, mem_len
);
510 device_printf(sc
->sc_dev
, "cannot map bar%d register space\n", 0);
513 sc
->sc_bar0_lastreg
= (bus_size_t
) -1;
515 mem_start
= pci_resource_start(sc
->sc_pcidev
, 1);
516 mem_len
= pci_resource_len(sc
->sc_pcidev
, 1);
517 sc
->sc_bar1
= (ocf_iomem_t
) ioremap(mem_start
, mem_len
);
519 device_printf(sc
->sc_dev
, "cannot map bar%d register space\n", 1);
522 sc
->sc_bar1_lastreg
= (bus_size_t
) -1;
524 /* fix up the bus size */
525 if (pci_set_dma_mask(dev
, DMA_32BIT_MASK
)) {
526 device_printf(sc
->sc_dev
, "No usable DMA configuration, aborting.\n");
529 if (pci_set_consistent_dma_mask(dev
, DMA_32BIT_MASK
)) {
530 device_printf(sc
->sc_dev
,
531 "No usable consistent DMA configuration, aborting.\n");
538 * Setup the area where the Hifn DMA's descriptors
539 * and associated data structures.
541 sc
->sc_dma
= (struct hifn_dma
*) pci_alloc_consistent(dev
,
543 &sc
->sc_dma_physaddr
);
545 device_printf(sc
->sc_dev
, "cannot alloc sc_dma\n");
548 bzero(sc
->sc_dma
, sizeof(*sc
->sc_dma
));
551 * Reset the board and do the ``secret handshake''
552 * to enable the crypto support. Then complete the
553 * initialization procedure by setting up the interrupt
554 * and hooking in to the system crypto support so we'll
555 * get used for system services like the crypto device,
556 * IPsec, RNG device, etc.
558 hifn_reset_board(sc
, 0);
560 if (hifn_enable_crypto(sc
) != 0) {
561 device_printf(sc
->sc_dev
, "crypto enabling failed\n");
567 hifn_init_pci_registers(sc
);
569 pci_set_master(sc
->sc_pcidev
);
571 /* XXX can't dynamically determine ram type for 795x; force dram */
572 if (sc
->sc_flags
& HIFN_IS_7956
)
573 sc
->sc_drammodel
= 1;
574 else if (hifn_ramtype(sc
))
577 if (sc
->sc_drammodel
== 0)
583 * Workaround for NetSec 7751 rev A: half ram size because two
584 * of the address lines were left floating
586 if (pci_get_vendor(dev
) == PCI_VENDOR_NETSEC
&&
587 pci_get_device(dev
) == PCI_PRODUCT_NETSEC_7751
&&
588 pci_get_revid(dev
) == 0x61) /*XXX???*/
589 sc
->sc_ramsize
>>= 1;
592 * Arrange the interrupt line.
594 rc
= request_irq(dev
->irq
, hifn_intr
, IRQF_SHARED
, "hifn", sc
);
596 device_printf(sc
->sc_dev
, "could not map interrupt: %d\n", rc
);
599 sc
->sc_irq
= dev
->irq
;
604 * NB: Keep only the low 16 bits; this masks the chip id
607 rev
= READ_REG_1(sc
, HIFN_1_REVID
) & 0xffff;
609 rseg
= sc
->sc_ramsize
/ 1024;
611 if (sc
->sc_ramsize
>= (1024 * 1024)) {
615 device_printf(sc
->sc_dev
, "%s, rev %u, %d%cB %cram",
616 hifn_partname(sc
), rev
,
617 rseg
, rbase
, sc
->sc_drammodel
? 'd' : 's');
618 if (sc
->sc_flags
& HIFN_IS_7956
)
619 printf(", pll=0x%x<%s clk, %ux mult>",
621 sc
->sc_pllconfig
& HIFN_PLL_REF_SEL
? "ext" : "pci",
622 2 + 2*((sc
->sc_pllconfig
& HIFN_PLL_ND
) >> 11));
625 sc
->sc_cid
= crypto_get_driverid(softc_get_device(sc
),CRYPTOCAP_F_HARDWARE
);
626 if (sc
->sc_cid
< 0) {
627 device_printf(sc
->sc_dev
, "could not get crypto driver id\n");
631 WRITE_REG_0(sc
, HIFN_0_PUCNFG
,
632 READ_REG_0(sc
, HIFN_0_PUCNFG
) | HIFN_PUCNFG_CHIPID
);
633 ena
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
636 case HIFN_PUSTAT_ENA_2
:
637 crypto_register(sc
->sc_cid
, CRYPTO_3DES_CBC
, 0, 0);
638 crypto_register(sc
->sc_cid
, CRYPTO_ARC4
, 0, 0);
639 if (sc
->sc_flags
& HIFN_HAS_AES
)
640 crypto_register(sc
->sc_cid
, CRYPTO_AES_CBC
, 0, 0);
642 case HIFN_PUSTAT_ENA_1
:
643 crypto_register(sc
->sc_cid
, CRYPTO_MD5
, 0, 0);
644 crypto_register(sc
->sc_cid
, CRYPTO_SHA1
, 0, 0);
645 crypto_register(sc
->sc_cid
, CRYPTO_MD5_HMAC
, 0, 0);
646 crypto_register(sc
->sc_cid
, CRYPTO_SHA1_HMAC
, 0, 0);
647 crypto_register(sc
->sc_cid
, CRYPTO_DES_CBC
, 0, 0);
651 if (sc
->sc_flags
& (HIFN_HAS_PUBLIC
| HIFN_HAS_RNG
))
652 hifn_init_pubrng(sc
);
654 init_timer(&sc
->sc_tickto
);
655 sc
->sc_tickto
.function
= hifn_tick
;
656 sc
->sc_tickto
.data
= (unsigned long) sc
->sc_num
;
657 mod_timer(&sc
->sc_tickto
, jiffies
+ HZ
);
663 crypto_unregister_all(sc
->sc_cid
);
664 if (sc
->sc_irq
!= -1)
665 free_irq(sc
->sc_irq
, sc
);
667 /* Turn off DMA polling */
668 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
669 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
671 pci_free_consistent(sc
->sc_pcidev
,
673 sc
->sc_dma
, sc
->sc_dma_physaddr
);
680 * Detach an interface that successfully probed.
683 hifn_remove(struct pci_dev
*dev
)
685 struct hifn_softc
*sc
= pci_get_drvdata(dev
);
686 unsigned long l_flags
;
688 DPRINTF("%s()\n", __FUNCTION__
);
690 KASSERT(sc
!= NULL
, ("hifn_detach: null software carrier!"));
692 /* disable interrupts */
694 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, 0);
697 /*XXX other resources */
698 del_timer_sync(&sc
->sc_tickto
);
700 /* Turn off DMA polling */
701 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
702 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
704 crypto_unregister_all(sc
->sc_cid
);
706 free_irq(sc
->sc_irq
, sc
);
708 pci_free_consistent(sc
->sc_pcidev
, sizeof(*sc
->sc_dma
),
709 sc
->sc_dma
, sc
->sc_dma_physaddr
);
714 hifn_init_pubrng(struct hifn_softc
*sc
)
718 DPRINTF("%s()\n", __FUNCTION__
);
720 if ((sc
->sc_flags
& HIFN_IS_7811
) == 0) {
721 /* Reset 7951 public key/rng engine */
722 WRITE_REG_1(sc
, HIFN_1_PUB_RESET
,
723 READ_REG_1(sc
, HIFN_1_PUB_RESET
) | HIFN_PUBRST_RESET
);
725 for (i
= 0; i
< 100; i
++) {
727 if ((READ_REG_1(sc
, HIFN_1_PUB_RESET
) &
728 HIFN_PUBRST_RESET
) == 0)
733 device_printf(sc
->sc_dev
, "public key init failed\n");
738 /* Enable the rng, if available */
739 #ifdef CONFIG_OCF_RANDOMHARVEST
740 if (sc
->sc_flags
& HIFN_HAS_RNG
) {
741 if (sc
->sc_flags
& HIFN_IS_7811
) {
743 r
= READ_REG_1(sc
, HIFN_1_7811_RNGENA
);
744 if (r
& HIFN_7811_RNGENA_ENA
) {
745 r
&= ~HIFN_7811_RNGENA_ENA
;
746 WRITE_REG_1(sc
, HIFN_1_7811_RNGENA
, r
);
748 WRITE_REG_1(sc
, HIFN_1_7811_RNGCFG
,
749 HIFN_7811_RNGCFG_DEFL
);
750 r
|= HIFN_7811_RNGENA_ENA
;
751 WRITE_REG_1(sc
, HIFN_1_7811_RNGENA
, r
);
753 WRITE_REG_1(sc
, HIFN_1_RNG_CONFIG
,
754 READ_REG_1(sc
, HIFN_1_RNG_CONFIG
) |
758 crypto_rregister(sc
->sc_cid
, hifn_read_random
, sc
);
762 /* Enable public key engine, if available */
763 if (sc
->sc_flags
& HIFN_HAS_PUBLIC
) {
764 WRITE_REG_1(sc
, HIFN_1_PUB_IEN
, HIFN_PUBIEN_DONE
);
765 sc
->sc_dmaier
|= HIFN_DMAIER_PUBDONE
;
766 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
767 #ifdef HIFN_VULCANDEV
768 sc
->sc_pkdev
= make_dev(&vulcanpk_cdevsw
, 0,
769 UID_ROOT
, GID_WHEEL
, 0666,
771 sc
->sc_pkdev
->si_drv1
= sc
;
778 #ifdef CONFIG_OCF_RANDOMHARVEST
780 hifn_read_random(void *arg
, u_int32_t
*buf
, int len
)
782 struct hifn_softc
*sc
= (struct hifn_softc
*) arg
;
789 if (sc
->sc_flags
& HIFN_IS_7811
) {
790 /* ONLY VALID ON 7811!!!! */
791 for (i
= 0; i
< 5; i
++) {
792 sts
= READ_REG_1(sc
, HIFN_1_7811_RNGSTS
);
793 if (sts
& HIFN_7811_RNGSTS_UFL
) {
794 device_printf(sc
->sc_dev
,
795 "RNG underflow: disabling\n");
796 /* DAVIDM perhaps return -1 */
799 if ((sts
& HIFN_7811_RNGSTS_RDY
) == 0)
803 * There are at least two words in the RNG FIFO
807 buf
[rc
++] = READ_REG_1(sc
, HIFN_1_7811_RNGDAT
);
809 buf
[rc
++] = READ_REG_1(sc
, HIFN_1_7811_RNGDAT
);
812 buf
[rc
++] = READ_REG_1(sc
, HIFN_1_RNG_DATA
);
814 /* NB: discard first data read */
815 if (sc
->sc_rngfirst
) {
822 #endif /* CONFIG_OCF_RANDOMHARVEST */
825 hifn_puc_wait(struct hifn_softc
*sc
)
828 int reg
= HIFN_0_PUCTRL
;
830 if (sc
->sc_flags
& HIFN_IS_7956
) {
831 reg
= HIFN_0_PUCTRL2
;
834 for (i
= 5000; i
> 0; i
--) {
836 if (!(READ_REG_0(sc
, reg
) & HIFN_PUCTRL_RESET
))
840 device_printf(sc
->sc_dev
, "proc unit did not reset(0x%x)\n",
841 READ_REG_0(sc
, HIFN_0_PUCTRL
));
845 * Reset the processing unit.
848 hifn_reset_puc(struct hifn_softc
*sc
)
850 /* Reset processing unit */
851 int reg
= HIFN_0_PUCTRL
;
853 if (sc
->sc_flags
& HIFN_IS_7956
) {
854 reg
= HIFN_0_PUCTRL2
;
856 WRITE_REG_0(sc
, reg
, HIFN_PUCTRL_DMAENA
);
862 * Set the Retry and TRDY registers; note that we set them to
863 * zero because the 7811 locks up when forced to retry (section
864 * 3.6 of "Specification Update SU-0014-04". Not clear if we
865 * should do this for all Hifn parts, but it doesn't seem to hurt.
868 hifn_set_retry(struct hifn_softc
*sc
)
870 DPRINTF("%s()\n", __FUNCTION__
);
871 /* NB: RETRY only responds to 8-bit reads/writes */
872 pci_write_config_byte(sc
->sc_pcidev
, HIFN_RETRY_TIMEOUT
, 0);
873 pci_write_config_dword(sc
->sc_pcidev
, HIFN_TRDY_TIMEOUT
, 0);
874 /* piggy back the cache line setting here */
875 pci_write_config_byte(sc
->sc_pcidev
, PCI_CACHE_LINE_SIZE
, hifn_cache_linesize
);
879 * Resets the board. Values in the regesters are left as is
880 * from the reset (i.e. initial values are assigned elsewhere).
883 hifn_reset_board(struct hifn_softc
*sc
, int full
)
887 DPRINTF("%s()\n", __FUNCTION__
);
889 * Set polling in the DMA configuration register to zero. 0x7 avoids
890 * resetting the board and zeros out the other fields.
892 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
893 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
896 * Now that polling has been disabled, we have to wait 1 ms
897 * before resetting the board.
901 /* Reset the DMA unit */
903 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MODE
);
906 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
,
907 HIFN_DMACNFG_MODE
| HIFN_DMACNFG_MSTRESET
);
911 KASSERT(sc
->sc_dma
!= NULL
, ("hifn_reset_board: null DMA tag!"));
912 bzero(sc
->sc_dma
, sizeof(*sc
->sc_dma
));
914 /* Bring dma unit out of reset */
915 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
916 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
921 if (sc
->sc_flags
& HIFN_IS_7811
) {
922 for (reg
= 0; reg
< 1000; reg
++) {
923 if (READ_REG_1(sc
, HIFN_1_7811_MIPSRST
) &
924 HIFN_MIPSRST_CRAMINIT
)
929 device_printf(sc
->sc_dev
, ": cram init timeout\n");
931 /* set up DMA configuration register #2 */
932 /* turn off all PK and BAR0 swaps */
933 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG2
,
934 (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT
)|
935 (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT
)|
936 (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT
)|
937 (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT
));
942 hifn_next_signature(u_int32_t a
, u_int cnt
)
947 for (i
= 0; i
< cnt
; i
++) {
957 a
= (v
& 1) ^ (a
<< 1);
965 * Checks to see if crypto is already enabled. If crypto isn't enable,
966 * "hifn_enable_crypto" is called to enable it. The check is important,
967 * as enabling crypto twice will lock the board.
970 hifn_enable_crypto(struct hifn_softc
*sc
)
972 u_int32_t dmacfg
, ramcfg
, encl
, addr
, i
;
973 char offtbl
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974 0x00, 0x00, 0x00, 0x00 };
976 DPRINTF("%s()\n", __FUNCTION__
);
978 ramcfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
);
979 dmacfg
= READ_REG_1(sc
, HIFN_1_DMA_CNFG
);
982 * The RAM config register's encrypt level bit needs to be set before
983 * every read performed on the encryption level register.
985 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
| HIFN_PUCNFG_CHIPID
);
987 encl
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
990 * Make sure we don't re-unlock. Two unlocks kills chip until the
993 if (encl
== HIFN_PUSTAT_ENA_1
|| encl
== HIFN_PUSTAT_ENA_2
) {
996 device_printf(sc
->sc_dev
,
997 "Strong crypto already enabled!\n");
1002 if (encl
!= 0 && encl
!= HIFN_PUSTAT_ENA_0
) {
1005 device_printf(sc
->sc_dev
,
1006 "Unknown encryption level 0x%x\n", encl
);
1011 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_UNLOCK
|
1012 HIFN_DMACNFG_MSTRESET
| HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
1014 addr
= READ_REG_1(sc
, HIFN_UNLOCK_SECRET1
);
1016 WRITE_REG_1(sc
, HIFN_UNLOCK_SECRET2
, 0);
1019 for (i
= 0; i
<= 12; i
++) {
1020 addr
= hifn_next_signature(addr
, offtbl
[i
] + 0x101);
1021 WRITE_REG_1(sc
, HIFN_UNLOCK_SECRET2
, addr
);
1026 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
| HIFN_PUCNFG_CHIPID
);
1027 encl
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
1031 if (encl
!= HIFN_PUSTAT_ENA_1
&& encl
!= HIFN_PUSTAT_ENA_2
)
1032 device_printf(sc
->sc_dev
, "Engine is permanently "
1033 "locked until next system reset!\n");
1035 device_printf(sc
->sc_dev
, "Engine enabled "
1041 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
);
1042 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, dmacfg
);
1045 case HIFN_PUSTAT_ENA_1
:
1046 case HIFN_PUSTAT_ENA_2
:
1048 case HIFN_PUSTAT_ENA_0
:
1050 device_printf(sc
->sc_dev
, "disabled\n");
1058 * Give initial values to the registers listed in the "Register Space"
1059 * section of the HIFN Software Development reference manual.
1062 hifn_init_pci_registers(struct hifn_softc
*sc
)
1064 DPRINTF("%s()\n", __FUNCTION__
);
1066 /* write fixed values needed by the Initialization registers */
1067 WRITE_REG_0(sc
, HIFN_0_PUCTRL
, HIFN_PUCTRL_DMAENA
);
1068 WRITE_REG_0(sc
, HIFN_0_FIFOCNFG
, HIFN_FIFOCNFG_THRESHOLD
);
1069 WRITE_REG_0(sc
, HIFN_0_PUIER
, HIFN_PUIER_DSTOVER
);
1071 /* write all 4 ring address registers */
1072 WRITE_REG_1(sc
, HIFN_1_DMA_CRAR
, sc
->sc_dma_physaddr
+
1073 offsetof(struct hifn_dma
, cmdr
[0]));
1074 WRITE_REG_1(sc
, HIFN_1_DMA_SRAR
, sc
->sc_dma_physaddr
+
1075 offsetof(struct hifn_dma
, srcr
[0]));
1076 WRITE_REG_1(sc
, HIFN_1_DMA_DRAR
, sc
->sc_dma_physaddr
+
1077 offsetof(struct hifn_dma
, dstr
[0]));
1078 WRITE_REG_1(sc
, HIFN_1_DMA_RRAR
, sc
->sc_dma_physaddr
+
1079 offsetof(struct hifn_dma
, resr
[0]));
1083 /* write status register */
1084 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1085 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
|
1086 HIFN_DMACSR_S_CTRL_DIS
| HIFN_DMACSR_C_CTRL_DIS
|
1087 HIFN_DMACSR_D_ABORT
| HIFN_DMACSR_D_DONE
| HIFN_DMACSR_D_LAST
|
1088 HIFN_DMACSR_D_WAIT
| HIFN_DMACSR_D_OVER
|
1089 HIFN_DMACSR_R_ABORT
| HIFN_DMACSR_R_DONE
| HIFN_DMACSR_R_LAST
|
1090 HIFN_DMACSR_R_WAIT
| HIFN_DMACSR_R_OVER
|
1091 HIFN_DMACSR_S_ABORT
| HIFN_DMACSR_S_DONE
| HIFN_DMACSR_S_LAST
|
1092 HIFN_DMACSR_S_WAIT
|
1093 HIFN_DMACSR_C_ABORT
| HIFN_DMACSR_C_DONE
| HIFN_DMACSR_C_LAST
|
1094 HIFN_DMACSR_C_WAIT
|
1095 HIFN_DMACSR_ENGINE
|
1096 ((sc
->sc_flags
& HIFN_HAS_PUBLIC
) ?
1097 HIFN_DMACSR_PUBDONE
: 0) |
1098 ((sc
->sc_flags
& HIFN_IS_7811
) ?
1099 HIFN_DMACSR_ILLW
| HIFN_DMACSR_ILLR
: 0));
1101 sc
->sc_d_busy
= sc
->sc_r_busy
= sc
->sc_s_busy
= sc
->sc_c_busy
= 0;
1102 sc
->sc_dmaier
|= HIFN_DMAIER_R_DONE
| HIFN_DMAIER_C_ABORT
|
1103 HIFN_DMAIER_D_OVER
| HIFN_DMAIER_R_OVER
|
1104 HIFN_DMAIER_S_ABORT
| HIFN_DMAIER_D_ABORT
| HIFN_DMAIER_R_ABORT
|
1105 ((sc
->sc_flags
& HIFN_IS_7811
) ?
1106 HIFN_DMAIER_ILLW
| HIFN_DMAIER_ILLR
: 0);
1107 sc
->sc_dmaier
&= ~HIFN_DMAIER_C_WAIT
;
1108 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
1111 if (sc
->sc_flags
& HIFN_IS_7956
) {
1114 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, HIFN_PUCNFG_COMPSING
|
1115 HIFN_PUCNFG_TCALLPHASES
|
1116 HIFN_PUCNFG_TCDRVTOTEM
| HIFN_PUCNFG_BUS32
);
1118 /* turn off the clocks and insure bypass is set */
1119 pll
= READ_REG_1(sc
, HIFN_1_PLL
);
1120 pll
= (pll
&~ (HIFN_PLL_PK_CLK_SEL
| HIFN_PLL_PE_CLK_SEL
))
1121 | HIFN_PLL_BP
| HIFN_PLL_MBSET
;
1122 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1123 DELAY(10*1000); /* 10ms */
1125 /* change configuration */
1126 pll
= (pll
&~ HIFN_PLL_CONFIG
) | sc
->sc_pllconfig
;
1127 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1128 DELAY(10*1000); /* 10ms */
1130 /* disable bypass */
1131 pll
&= ~HIFN_PLL_BP
;
1132 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1133 /* enable clocks with new configuration */
1134 pll
|= HIFN_PLL_PK_CLK_SEL
| HIFN_PLL_PE_CLK_SEL
;
1135 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1137 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, HIFN_PUCNFG_COMPSING
|
1138 HIFN_PUCNFG_DRFR_128
| HIFN_PUCNFG_TCALLPHASES
|
1139 HIFN_PUCNFG_TCDRVTOTEM
| HIFN_PUCNFG_BUS32
|
1140 (sc
->sc_drammodel
? HIFN_PUCNFG_DRAM
: HIFN_PUCNFG_SRAM
));
1143 WRITE_REG_0(sc
, HIFN_0_PUISR
, HIFN_PUISR_DSTOVER
);
1144 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
1145 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
| HIFN_DMACNFG_LAST
|
1146 ((HIFN_POLL_FREQUENCY
<< 16 ) & HIFN_DMACNFG_POLLFREQ
) |
1147 ((HIFN_POLL_SCALAR
<< 8) & HIFN_DMACNFG_POLLINVAL
));
1151 * The maximum number of sessions supported by the card
1152 * is dependent on the amount of context ram, which
1153 * encryption algorithms are enabled, and how compression
1154 * is configured. This should be configured before this
1155 * routine is called.
1158 hifn_sessions(struct hifn_softc
*sc
)
1163 DPRINTF("%s()\n", __FUNCTION__
);
1165 pucnfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
);
1167 if (pucnfg
& HIFN_PUCNFG_COMPSING
) {
1168 if (pucnfg
& HIFN_PUCNFG_ENCCNFG
)
1173 * 7955/7956 has internal context memory of 32K
1175 if (sc
->sc_flags
& HIFN_IS_7956
)
1176 sc
->sc_maxses
= 32768 / ctxsize
;
1179 ((sc
->sc_ramsize
- 32768) / ctxsize
);
1181 sc
->sc_maxses
= sc
->sc_ramsize
/ 16384;
1183 if (sc
->sc_maxses
> 2048)
1184 sc
->sc_maxses
= 2048;
1188 * Determine ram type (sram or dram). Board should be just out of a reset
1189 * state when this is called.
1192 hifn_ramtype(struct hifn_softc
*sc
)
1194 u_int8_t data
[8], dataexpect
[8];
1197 for (i
= 0; i
< sizeof(data
); i
++)
1198 data
[i
] = dataexpect
[i
] = 0x55;
1199 if (hifn_writeramaddr(sc
, 0, data
))
1201 if (hifn_readramaddr(sc
, 0, data
))
1203 if (bcmp(data
, dataexpect
, sizeof(data
)) != 0) {
1204 sc
->sc_drammodel
= 1;
1208 for (i
= 0; i
< sizeof(data
); i
++)
1209 data
[i
] = dataexpect
[i
] = 0xaa;
1210 if (hifn_writeramaddr(sc
, 0, data
))
1212 if (hifn_readramaddr(sc
, 0, data
))
1214 if (bcmp(data
, dataexpect
, sizeof(data
)) != 0) {
1215 sc
->sc_drammodel
= 1;
1222 #define HIFN_SRAM_MAX (32 << 20)
1223 #define HIFN_SRAM_STEP_SIZE 16384
1224 #define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
1227 hifn_sramsize(struct hifn_softc
*sc
)
1231 u_int8_t dataexpect
[sizeof(data
)];
1234 for (i
= 0; i
< sizeof(data
); i
++)
1235 data
[i
] = dataexpect
[i
] = i
^ 0x5a;
1237 for (i
= HIFN_SRAM_GRANULARITY
- 1; i
>= 0; i
--) {
1238 a
= i
* HIFN_SRAM_STEP_SIZE
;
1239 bcopy(&i
, data
, sizeof(i
));
1240 hifn_writeramaddr(sc
, a
, data
);
1243 for (i
= 0; i
< HIFN_SRAM_GRANULARITY
; i
++) {
1244 a
= i
* HIFN_SRAM_STEP_SIZE
;
1245 bcopy(&i
, dataexpect
, sizeof(i
));
1246 if (hifn_readramaddr(sc
, a
, data
) < 0)
1248 if (bcmp(data
, dataexpect
, sizeof(data
)) != 0)
1250 sc
->sc_ramsize
= a
+ HIFN_SRAM_STEP_SIZE
;
1257 * XXX For dram boards, one should really try all of the
1258 * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
1259 * is already set up correctly.
1262 hifn_dramsize(struct hifn_softc
*sc
)
1266 if (sc
->sc_flags
& HIFN_IS_7956
) {
1268 * 7955/7956 have a fixed internal ram of only 32K.
1270 sc
->sc_ramsize
= 32768;
1272 cnfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
) &
1273 HIFN_PUCNFG_DRAMMASK
;
1274 sc
->sc_ramsize
= 1 << ((cnfg
>> 13) + 18);
1280 hifn_alloc_slot(struct hifn_softc
*sc
, int *cmdp
, int *srcp
, int *dstp
, int *resp
)
1282 struct hifn_dma
*dma
= sc
->sc_dma
;
1284 DPRINTF("%s()\n", __FUNCTION__
);
1286 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
1288 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1290 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1291 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
1292 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1294 *cmdp
= dma
->cmdi
++;
1295 dma
->cmdk
= dma
->cmdi
;
1297 if (dma
->srci
== HIFN_D_SRC_RSIZE
) {
1299 dma
->srcr
[HIFN_D_SRC_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1301 dma
->srcr
[HIFN_D_SRC_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1302 HIFN_SRCR_SYNC(sc
, HIFN_D_SRC_RSIZE
,
1303 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1305 *srcp
= dma
->srci
++;
1306 dma
->srck
= dma
->srci
;
1308 if (dma
->dsti
== HIFN_D_DST_RSIZE
) {
1310 dma
->dstr
[HIFN_D_DST_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1312 dma
->dstr
[HIFN_D_DST_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1313 HIFN_DSTR_SYNC(sc
, HIFN_D_DST_RSIZE
,
1314 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1316 *dstp
= dma
->dsti
++;
1317 dma
->dstk
= dma
->dsti
;
1319 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
1321 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1323 dma
->resr
[HIFN_D_RES_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1324 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
1325 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1327 *resp
= dma
->resi
++;
1328 dma
->resk
= dma
->resi
;
1332 hifn_writeramaddr(struct hifn_softc
*sc
, int addr
, u_int8_t
*data
)
1334 struct hifn_dma
*dma
= sc
->sc_dma
;
1335 hifn_base_command_t wc
;
1336 const u_int32_t masks
= HIFN_D_VALID
| HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
;
1337 int r
, cmdi
, resi
, srci
, dsti
;
1339 DPRINTF("%s()\n", __FUNCTION__
);
1341 wc
.masks
= htole16(3 << 13);
1342 wc
.session_num
= htole16(addr
>> 14);
1343 wc
.total_source_count
= htole16(8);
1344 wc
.total_dest_count
= htole16(addr
& 0x3fff);
1346 hifn_alloc_slot(sc
, &cmdi
, &srci
, &dsti
, &resi
);
1348 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1349 HIFN_DMACSR_C_CTRL_ENA
| HIFN_DMACSR_S_CTRL_ENA
|
1350 HIFN_DMACSR_D_CTRL_ENA
| HIFN_DMACSR_R_CTRL_ENA
);
1352 /* build write command */
1353 bzero(dma
->command_bufs
[cmdi
], HIFN_MAX_COMMAND
);
1354 *(hifn_base_command_t
*)dma
->command_bufs
[cmdi
] = wc
;
1355 bcopy(data
, &dma
->test_src
, sizeof(dma
->test_src
));
1357 dma
->srcr
[srci
].p
= htole32(sc
->sc_dma_physaddr
1358 + offsetof(struct hifn_dma
, test_src
));
1359 dma
->dstr
[dsti
].p
= htole32(sc
->sc_dma_physaddr
1360 + offsetof(struct hifn_dma
, test_dst
));
1362 dma
->cmdr
[cmdi
].l
= htole32(16 | masks
);
1363 dma
->srcr
[srci
].l
= htole32(8 | masks
);
1364 dma
->dstr
[dsti
].l
= htole32(4 | masks
);
1365 dma
->resr
[resi
].l
= htole32(4 | masks
);
1367 for (r
= 10000; r
>= 0; r
--) {
1369 if ((dma
->resr
[resi
].l
& htole32(HIFN_D_VALID
)) == 0)
1373 device_printf(sc
->sc_dev
, "writeramaddr -- "
1374 "result[%d](addr %d) still valid\n", resi
, addr
);
1380 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1381 HIFN_DMACSR_C_CTRL_DIS
| HIFN_DMACSR_S_CTRL_DIS
|
1382 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
);
1388 hifn_readramaddr(struct hifn_softc
*sc
, int addr
, u_int8_t
*data
)
1390 struct hifn_dma
*dma
= sc
->sc_dma
;
1391 hifn_base_command_t rc
;
1392 const u_int32_t masks
= HIFN_D_VALID
| HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
;
1393 int r
, cmdi
, srci
, dsti
, resi
;
1395 DPRINTF("%s()\n", __FUNCTION__
);
1397 rc
.masks
= htole16(2 << 13);
1398 rc
.session_num
= htole16(addr
>> 14);
1399 rc
.total_source_count
= htole16(addr
& 0x3fff);
1400 rc
.total_dest_count
= htole16(8);
1402 hifn_alloc_slot(sc
, &cmdi
, &srci
, &dsti
, &resi
);
1404 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1405 HIFN_DMACSR_C_CTRL_ENA
| HIFN_DMACSR_S_CTRL_ENA
|
1406 HIFN_DMACSR_D_CTRL_ENA
| HIFN_DMACSR_R_CTRL_ENA
);
1408 bzero(dma
->command_bufs
[cmdi
], HIFN_MAX_COMMAND
);
1409 *(hifn_base_command_t
*)dma
->command_bufs
[cmdi
] = rc
;
1411 dma
->srcr
[srci
].p
= htole32(sc
->sc_dma_physaddr
+
1412 offsetof(struct hifn_dma
, test_src
));
1414 dma
->dstr
[dsti
].p
= htole32(sc
->sc_dma_physaddr
+
1415 offsetof(struct hifn_dma
, test_dst
));
1417 dma
->cmdr
[cmdi
].l
= htole32(8 | masks
);
1418 dma
->srcr
[srci
].l
= htole32(8 | masks
);
1419 dma
->dstr
[dsti
].l
= htole32(8 | masks
);
1420 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
| masks
);
1422 for (r
= 10000; r
>= 0; r
--) {
1424 if ((dma
->resr
[resi
].l
& htole32(HIFN_D_VALID
)) == 0)
1428 device_printf(sc
->sc_dev
, "readramaddr -- "
1429 "result[%d](addr %d) still valid\n", resi
, addr
);
1433 bcopy(&dma
->test_dst
, data
, sizeof(dma
->test_dst
));
1436 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1437 HIFN_DMACSR_C_CTRL_DIS
| HIFN_DMACSR_S_CTRL_DIS
|
1438 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
);
1444 * Initialize the descriptor rings.
1447 hifn_init_dma(struct hifn_softc
*sc
)
1449 struct hifn_dma
*dma
= sc
->sc_dma
;
1452 DPRINTF("%s()\n", __FUNCTION__
);
1456 /* initialize static pointer values */
1457 for (i
= 0; i
< HIFN_D_CMD_RSIZE
; i
++)
1458 dma
->cmdr
[i
].p
= htole32(sc
->sc_dma_physaddr
+
1459 offsetof(struct hifn_dma
, command_bufs
[i
][0]));
1460 for (i
= 0; i
< HIFN_D_RES_RSIZE
; i
++)
1461 dma
->resr
[i
].p
= htole32(sc
->sc_dma_physaddr
+
1462 offsetof(struct hifn_dma
, result_bufs
[i
][0]));
1464 dma
->cmdr
[HIFN_D_CMD_RSIZE
].p
=
1465 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, cmdr
[0]));
1466 dma
->srcr
[HIFN_D_SRC_RSIZE
].p
=
1467 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, srcr
[0]));
1468 dma
->dstr
[HIFN_D_DST_RSIZE
].p
=
1469 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, dstr
[0]));
1470 dma
->resr
[HIFN_D_RES_RSIZE
].p
=
1471 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, resr
[0]));
1473 dma
->cmdu
= dma
->srcu
= dma
->dstu
= dma
->resu
= 0;
1474 dma
->cmdi
= dma
->srci
= dma
->dsti
= dma
->resi
= 0;
1475 dma
->cmdk
= dma
->srck
= dma
->dstk
= dma
->resk
= 0;
1479 * Writes out the raw command buffer space. Returns the
1480 * command buffer size.
1483 hifn_write_command(struct hifn_command
*cmd
, u_int8_t
*buf
)
1485 struct hifn_softc
*sc
= NULL
;
1487 hifn_base_command_t
*base_cmd
;
1488 hifn_mac_command_t
*mac_cmd
;
1489 hifn_crypt_command_t
*cry_cmd
;
1490 int using_mac
, using_crypt
, len
, ivlen
;
1491 u_int32_t dlen
, slen
;
1493 DPRINTF("%s()\n", __FUNCTION__
);
1496 using_mac
= cmd
->base_masks
& HIFN_BASE_CMD_MAC
;
1497 using_crypt
= cmd
->base_masks
& HIFN_BASE_CMD_CRYPT
;
1499 base_cmd
= (hifn_base_command_t
*)buf_pos
;
1500 base_cmd
->masks
= htole16(cmd
->base_masks
);
1501 slen
= cmd
->src_mapsize
;
1503 dlen
= cmd
->dst_mapsize
- cmd
->sloplen
+ sizeof(u_int32_t
);
1505 dlen
= cmd
->dst_mapsize
;
1506 base_cmd
->total_source_count
= htole16(slen
& HIFN_BASE_CMD_LENMASK_LO
);
1507 base_cmd
->total_dest_count
= htole16(dlen
& HIFN_BASE_CMD_LENMASK_LO
);
1510 base_cmd
->session_num
= htole16(
1511 ((slen
<< HIFN_BASE_CMD_SRCLEN_S
) & HIFN_BASE_CMD_SRCLEN_M
) |
1512 ((dlen
<< HIFN_BASE_CMD_DSTLEN_S
) & HIFN_BASE_CMD_DSTLEN_M
));
1513 buf_pos
+= sizeof(hifn_base_command_t
);
1516 mac_cmd
= (hifn_mac_command_t
*)buf_pos
;
1517 dlen
= cmd
->maccrd
->crd_len
;
1518 mac_cmd
->source_count
= htole16(dlen
& 0xffff);
1520 mac_cmd
->masks
= htole16(cmd
->mac_masks
|
1521 ((dlen
<< HIFN_MAC_CMD_SRCLEN_S
) & HIFN_MAC_CMD_SRCLEN_M
));
1522 mac_cmd
->header_skip
= htole16(cmd
->maccrd
->crd_skip
);
1523 mac_cmd
->reserved
= 0;
1524 buf_pos
+= sizeof(hifn_mac_command_t
);
1528 cry_cmd
= (hifn_crypt_command_t
*)buf_pos
;
1529 dlen
= cmd
->enccrd
->crd_len
;
1530 cry_cmd
->source_count
= htole16(dlen
& 0xffff);
1532 cry_cmd
->masks
= htole16(cmd
->cry_masks
|
1533 ((dlen
<< HIFN_CRYPT_CMD_SRCLEN_S
) & HIFN_CRYPT_CMD_SRCLEN_M
));
1534 cry_cmd
->header_skip
= htole16(cmd
->enccrd
->crd_skip
);
1535 cry_cmd
->reserved
= 0;
1536 buf_pos
+= sizeof(hifn_crypt_command_t
);
1539 if (using_mac
&& cmd
->mac_masks
& HIFN_MAC_CMD_NEW_KEY
) {
1540 bcopy(cmd
->mac
, buf_pos
, HIFN_MAC_KEY_LENGTH
);
1541 buf_pos
+= HIFN_MAC_KEY_LENGTH
;
1544 if (using_crypt
&& cmd
->cry_masks
& HIFN_CRYPT_CMD_NEW_KEY
) {
1545 switch (cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) {
1546 case HIFN_CRYPT_CMD_ALG_3DES
:
1547 bcopy(cmd
->ck
, buf_pos
, HIFN_3DES_KEY_LENGTH
);
1548 buf_pos
+= HIFN_3DES_KEY_LENGTH
;
1550 case HIFN_CRYPT_CMD_ALG_DES
:
1551 bcopy(cmd
->ck
, buf_pos
, HIFN_DES_KEY_LENGTH
);
1552 buf_pos
+= HIFN_DES_KEY_LENGTH
;
1554 case HIFN_CRYPT_CMD_ALG_RC4
:
1559 clen
= MIN(cmd
->cklen
, len
);
1560 bcopy(cmd
->ck
, buf_pos
, clen
);
1567 case HIFN_CRYPT_CMD_ALG_AES
:
1569 * AES keys are variable 128, 192 and
1570 * 256 bits (16, 24 and 32 bytes).
1572 bcopy(cmd
->ck
, buf_pos
, cmd
->cklen
);
1573 buf_pos
+= cmd
->cklen
;
1578 if (using_crypt
&& cmd
->cry_masks
& HIFN_CRYPT_CMD_NEW_IV
) {
1579 switch (cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) {
1580 case HIFN_CRYPT_CMD_ALG_AES
:
1581 ivlen
= HIFN_AES_IV_LENGTH
;
1584 ivlen
= HIFN_IV_LENGTH
;
1587 bcopy(cmd
->iv
, buf_pos
, ivlen
);
1591 if ((cmd
->base_masks
& (HIFN_BASE_CMD_MAC
|HIFN_BASE_CMD_CRYPT
)) == 0) {
1596 return (buf_pos
- buf
);
1600 hifn_dmamap_aligned(struct hifn_operand
*op
)
1602 struct hifn_softc
*sc
= NULL
;
1605 DPRINTF("%s()\n", __FUNCTION__
);
1607 for (i
= 0; i
< op
->nsegs
; i
++) {
1608 if (op
->segs
[i
].ds_addr
& 3)
1610 if ((i
!= (op
->nsegs
- 1)) && (op
->segs
[i
].ds_len
& 3))
1617 hifn_dmamap_dstwrap(struct hifn_softc
*sc
, int idx
)
1619 struct hifn_dma
*dma
= sc
->sc_dma
;
1621 if (++idx
== HIFN_D_DST_RSIZE
) {
1622 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
| HIFN_D_JUMP
|
1623 HIFN_D_MASKDONEIRQ
);
1624 HIFN_DSTR_SYNC(sc
, idx
,
1625 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1632 hifn_dmamap_load_dst(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
1634 struct hifn_dma
*dma
= sc
->sc_dma
;
1635 struct hifn_operand
*dst
= &cmd
->dst
;
1637 int idx
, used
= 0, i
;
1639 DPRINTF("%s()\n", __FUNCTION__
);
1642 for (i
= 0; i
< dst
->nsegs
- 1; i
++) {
1643 dma
->dstr
[idx
].p
= htole32(dst
->segs
[i
].ds_addr
);
1644 dma
->dstr
[idx
].l
= htole32(HIFN_D_MASKDONEIRQ
| dst
->segs
[i
].ds_len
);
1646 dma
->dstr
[idx
].l
|= htole32(HIFN_D_VALID
);
1647 HIFN_DSTR_SYNC(sc
, idx
,
1648 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1651 idx
= hifn_dmamap_dstwrap(sc
, idx
);
1654 if (cmd
->sloplen
== 0) {
1655 p
= dst
->segs
[i
].ds_addr
;
1656 l
= HIFN_D_MASKDONEIRQ
| HIFN_D_LAST
|
1657 dst
->segs
[i
].ds_len
;
1659 p
= sc
->sc_dma_physaddr
+
1660 offsetof(struct hifn_dma
, slop
[cmd
->slopidx
]);
1661 l
= HIFN_D_MASKDONEIRQ
| HIFN_D_LAST
|
1664 if ((dst
->segs
[i
].ds_len
- cmd
->sloplen
) != 0) {
1665 dma
->dstr
[idx
].p
= htole32(dst
->segs
[i
].ds_addr
);
1666 dma
->dstr
[idx
].l
= htole32(HIFN_D_MASKDONEIRQ
|
1667 (dst
->segs
[i
].ds_len
- cmd
->sloplen
));
1669 dma
->dstr
[idx
].l
|= htole32(HIFN_D_VALID
);
1670 HIFN_DSTR_SYNC(sc
, idx
,
1671 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1674 idx
= hifn_dmamap_dstwrap(sc
, idx
);
1677 dma
->dstr
[idx
].p
= htole32(p
);
1678 dma
->dstr
[idx
].l
= htole32(l
);
1680 dma
->dstr
[idx
].l
|= htole32(HIFN_D_VALID
);
1681 HIFN_DSTR_SYNC(sc
, idx
, BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1684 idx
= hifn_dmamap_dstwrap(sc
, idx
);
1692 hifn_dmamap_srcwrap(struct hifn_softc
*sc
, int idx
)
1694 struct hifn_dma
*dma
= sc
->sc_dma
;
1696 if (++idx
== HIFN_D_SRC_RSIZE
) {
1697 dma
->srcr
[idx
].l
= htole32(HIFN_D_VALID
|
1698 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1699 HIFN_SRCR_SYNC(sc
, HIFN_D_SRC_RSIZE
,
1700 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1707 hifn_dmamap_load_src(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
1709 struct hifn_dma
*dma
= sc
->sc_dma
;
1710 struct hifn_operand
*src
= &cmd
->src
;
1714 DPRINTF("%s()\n", __FUNCTION__
);
1717 for (i
= 0; i
< src
->nsegs
; i
++) {
1718 if (i
== src
->nsegs
- 1)
1721 dma
->srcr
[idx
].p
= htole32(src
->segs
[i
].ds_addr
);
1722 dma
->srcr
[idx
].l
= htole32(src
->segs
[i
].ds_len
|
1723 HIFN_D_MASKDONEIRQ
| last
);
1725 dma
->srcr
[idx
].l
|= htole32(HIFN_D_VALID
);
1726 HIFN_SRCR_SYNC(sc
, idx
,
1727 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1729 idx
= hifn_dmamap_srcwrap(sc
, idx
);
1732 dma
->srcu
+= src
->nsegs
;
1739 struct hifn_softc
*sc
,
1740 struct hifn_command
*cmd
,
1741 struct cryptop
*crp
,
1744 struct hifn_dma
*dma
= sc
->sc_dma
;
1745 u_int32_t cmdlen
, csr
;
1746 int cmdi
, resi
, err
= 0;
1747 unsigned long l_flags
;
1749 DPRINTF("%s()\n", __FUNCTION__
);
1752 * need 1 cmd, and 1 res
1754 * NB: check this first since it's easy.
1757 if ((dma
->cmdu
+ 1) > HIFN_D_CMD_RSIZE
||
1758 (dma
->resu
+ 1) > HIFN_D_RES_RSIZE
) {
1761 device_printf(sc
->sc_dev
,
1762 "cmd/result exhaustion, cmdu %u resu %u\n",
1763 dma
->cmdu
, dma
->resu
);
1766 hifnstats
.hst_nomem_cr
++;
1767 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
1772 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
1773 if (pci_map_skb(sc
, &cmd
->src
, cmd
->src_skb
)) {
1774 hifnstats
.hst_nomem_load
++;
1778 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1779 if (pci_map_uio(sc
, &cmd
->src
, cmd
->src_io
)) {
1780 hifnstats
.hst_nomem_load
++;
1785 if (pci_map_buf(sc
, &cmd
->src
, cmd
->src_buf
, crp
->crp_ilen
)) {
1786 hifnstats
.hst_nomem_load
++;
1792 if (hifn_dmamap_aligned(&cmd
->src
)) {
1793 cmd
->sloplen
= cmd
->src_mapsize
& 3;
1794 cmd
->dst
= cmd
->src
;
1796 if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1797 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
1800 } else if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
1803 struct mbuf
*m
, *m0
, *mlast
;
1805 KASSERT(cmd
->dst_m
== cmd
->src_m
,
1806 ("hifn_crypto: dst_m initialized improperly"));
1807 hifnstats
.hst_unaligned
++;
1809 * Source is not aligned on a longword boundary.
1810 * Copy the data to insure alignment. If we fail
1811 * to allocate mbufs or clusters while doing this
1812 * we return ERESTART so the operation is requeued
1813 * at the crypto later, but only if there are
1814 * ops already posted to the hardware; otherwise we
1815 * have no guarantee that we'll be re-entered.
1817 totlen
= cmd
->src_mapsize
;
1818 if (cmd
->src_m
->m_flags
& M_PKTHDR
) {
1820 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
1821 if (m0
&& !m_dup_pkthdr(m0
, cmd
->src_m
, M_DONTWAIT
)) {
1827 MGET(m0
, M_DONTWAIT
, MT_DATA
);
1830 hifnstats
.hst_nomem_mbuf
++;
1831 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1834 if (totlen
>= MINCLSIZE
) {
1835 MCLGET(m0
, M_DONTWAIT
);
1836 if ((m0
->m_flags
& M_EXT
) == 0) {
1837 hifnstats
.hst_nomem_mcl
++;
1838 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1845 m0
->m_pkthdr
.len
= m0
->m_len
= len
;
1848 while (totlen
> 0) {
1849 MGET(m
, M_DONTWAIT
, MT_DATA
);
1851 hifnstats
.hst_nomem_mbuf
++;
1852 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1857 if (totlen
>= MINCLSIZE
) {
1858 MCLGET(m
, M_DONTWAIT
);
1859 if ((m
->m_flags
& M_EXT
) == 0) {
1860 hifnstats
.hst_nomem_mcl
++;
1861 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1870 m0
->m_pkthdr
.len
+= len
;
1878 device_printf(sc
->sc_dev
,
1879 "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
1880 __FILE__
, __LINE__
);
1885 device_printf(sc
->sc_dev
,
1886 "%s,%d: unaligned contig buffers not implemented\n",
1887 __FILE__
, __LINE__
);
1893 if (cmd
->dst_map
== NULL
) {
1894 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
1895 if (pci_map_skb(sc
, &cmd
->dst
, cmd
->dst_skb
)) {
1896 hifnstats
.hst_nomem_map
++;
1900 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1901 if (pci_map_uio(sc
, &cmd
->dst
, cmd
->dst_io
)) {
1902 hifnstats
.hst_nomem_load
++;
1907 if (pci_map_buf(sc
, &cmd
->dst
, cmd
->dst_buf
, crp
->crp_ilen
)) {
1908 hifnstats
.hst_nomem_load
++;
1917 device_printf(sc
->sc_dev
,
1918 "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
1919 READ_REG_1(sc
, HIFN_1_DMA_CSR
),
1920 READ_REG_1(sc
, HIFN_1_DMA_IER
),
1921 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
,
1922 cmd
->src_nsegs
, cmd
->dst_nsegs
);
1927 if (cmd
->src_map
== cmd
->dst_map
) {
1928 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
1929 BUS_DMASYNC_PREWRITE
|BUS_DMASYNC_PREREAD
);
1931 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
1932 BUS_DMASYNC_PREWRITE
);
1933 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
1934 BUS_DMASYNC_PREREAD
);
1939 * need N src, and N dst
1941 if ((dma
->srcu
+ cmd
->src_nsegs
) > HIFN_D_SRC_RSIZE
||
1942 (dma
->dstu
+ cmd
->dst_nsegs
+ 1) > HIFN_D_DST_RSIZE
) {
1945 device_printf(sc
->sc_dev
,
1946 "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
1947 dma
->srcu
, cmd
->src_nsegs
,
1948 dma
->dstu
, cmd
->dst_nsegs
);
1951 hifnstats
.hst_nomem_sd
++;
1956 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
1958 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1960 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1961 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
1962 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1965 cmdlen
= hifn_write_command(cmd
, dma
->command_bufs
[cmdi
]);
1966 HIFN_CMD_SYNC(sc
, cmdi
, BUS_DMASYNC_PREWRITE
);
1968 /* .p for command/result already set */
1969 dma
->cmdr
[cmdi
].l
= htole32(cmdlen
| HIFN_D_LAST
|
1970 HIFN_D_MASKDONEIRQ
);
1972 dma
->cmdr
[cmdi
].l
|= htole32(HIFN_D_VALID
);
1973 HIFN_CMDR_SYNC(sc
, cmdi
,
1974 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1978 * We don't worry about missing an interrupt (which a "command wait"
1979 * interrupt salvages us from), unless there is more than one command
1982 if (dma
->cmdu
> 1) {
1983 sc
->sc_dmaier
|= HIFN_DMAIER_C_WAIT
;
1984 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
1987 hifnstats
.hst_ipackets
++;
1988 hifnstats
.hst_ibytes
+= cmd
->src_mapsize
;
1990 hifn_dmamap_load_src(sc
, cmd
);
1993 * Unlike other descriptors, we don't mask done interrupt from
1994 * result descriptor.
1998 device_printf(sc
->sc_dev
, "load res\n");
2000 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
2002 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
2004 dma
->resr
[HIFN_D_RES_RSIZE
].l
|= htole32(HIFN_D_VALID
);
2005 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
2006 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2009 KASSERT(dma
->hifn_commands
[resi
] == NULL
,
2010 ("hifn_crypto: command slot %u busy", resi
));
2011 dma
->hifn_commands
[resi
] = cmd
;
2012 HIFN_RES_SYNC(sc
, resi
, BUS_DMASYNC_PREREAD
);
2013 if ((hint
& CRYPTO_HINT_MORE
) && sc
->sc_curbatch
< hifn_maxbatch
) {
2014 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
|
2015 HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
);
2017 dma
->resr
[resi
].l
|= htole32(HIFN_D_VALID
);
2019 if (sc
->sc_curbatch
> hifnstats
.hst_maxbatch
)
2020 hifnstats
.hst_maxbatch
= sc
->sc_curbatch
;
2021 hifnstats
.hst_totbatch
++;
2023 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
| HIFN_D_LAST
);
2025 dma
->resr
[resi
].l
|= htole32(HIFN_D_VALID
);
2026 sc
->sc_curbatch
= 0;
2028 HIFN_RESR_SYNC(sc
, resi
,
2029 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2033 cmd
->slopidx
= resi
;
2035 hifn_dmamap_load_dst(sc
, cmd
);
2038 if (sc
->sc_c_busy
== 0) {
2039 csr
|= HIFN_DMACSR_C_CTRL_ENA
;
2042 if (sc
->sc_s_busy
== 0) {
2043 csr
|= HIFN_DMACSR_S_CTRL_ENA
;
2046 if (sc
->sc_r_busy
== 0) {
2047 csr
|= HIFN_DMACSR_R_CTRL_ENA
;
2050 if (sc
->sc_d_busy
== 0) {
2051 csr
|= HIFN_DMACSR_D_CTRL_ENA
;
2055 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, csr
);
2059 device_printf(sc
->sc_dev
, "command: stat %8x ier %8x\n",
2060 READ_REG_1(sc
, HIFN_1_DMA_CSR
),
2061 READ_REG_1(sc
, HIFN_1_DMA_IER
));
2067 KASSERT(err
== 0, ("hifn_crypto: success with error %u", err
));
2068 return (err
); /* success */
2071 if (cmd
->src_map
!= cmd
->dst_map
)
2072 pci_unmap_buf(sc
, &cmd
->dst
);
2075 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
2076 if (cmd
->src_skb
!= cmd
->dst_skb
)
2078 m_freem(cmd
->dst_m
);
2080 device_printf(sc
->sc_dev
,
2081 "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
2082 __FILE__
, __LINE__
);
2085 pci_unmap_buf(sc
, &cmd
->src
);
2092 hifn_tick(unsigned long arg
)
2094 struct hifn_softc
*sc
;
2095 unsigned long l_flags
;
2097 if (arg
>= HIFN_MAX_CHIPS
)
2099 sc
= hifn_chip_idx
[arg
];
2104 if (sc
->sc_active
== 0) {
2105 struct hifn_dma
*dma
= sc
->sc_dma
;
2108 if (dma
->cmdu
== 0 && sc
->sc_c_busy
) {
2110 r
|= HIFN_DMACSR_C_CTRL_DIS
;
2112 if (dma
->srcu
== 0 && sc
->sc_s_busy
) {
2114 r
|= HIFN_DMACSR_S_CTRL_DIS
;
2116 if (dma
->dstu
== 0 && sc
->sc_d_busy
) {
2118 r
|= HIFN_DMACSR_D_CTRL_DIS
;
2120 if (dma
->resu
== 0 && sc
->sc_r_busy
) {
2122 r
|= HIFN_DMACSR_R_CTRL_DIS
;
2125 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, r
);
2129 mod_timer(&sc
->sc_tickto
, jiffies
+ HZ
);
2133 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
2134 hifn_intr(int irq
, void *arg
)
2136 hifn_intr(int irq
, void *arg
, struct pt_regs
*regs
)
2139 struct hifn_softc
*sc
= arg
;
2140 struct hifn_dma
*dma
;
2141 u_int32_t dmacsr
, restart
;
2143 unsigned long l_flags
;
2145 dmacsr
= READ_REG_1(sc
, HIFN_1_DMA_CSR
);
2147 /* Nothing in the DMA unit interrupted */
2148 if ((dmacsr
& sc
->sc_dmaier
) == 0)
2157 device_printf(sc
->sc_dev
,
2158 "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
2159 dmacsr
, READ_REG_1(sc
, HIFN_1_DMA_IER
), sc
->sc_dmaier
,
2160 dma
->cmdi
, dma
->srci
, dma
->dsti
, dma
->resi
,
2161 dma
->cmdk
, dma
->srck
, dma
->dstk
, dma
->resk
,
2162 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
);
2166 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, dmacsr
& sc
->sc_dmaier
);
2168 if ((sc
->sc_flags
& HIFN_HAS_PUBLIC
) &&
2169 (dmacsr
& HIFN_DMACSR_PUBDONE
))
2170 WRITE_REG_1(sc
, HIFN_1_PUB_STATUS
,
2171 READ_REG_1(sc
, HIFN_1_PUB_STATUS
) | HIFN_PUBSTS_DONE
);
2173 restart
= dmacsr
& (HIFN_DMACSR_D_OVER
| HIFN_DMACSR_R_OVER
);
2175 device_printf(sc
->sc_dev
, "overrun %x\n", dmacsr
);
2177 if (sc
->sc_flags
& HIFN_IS_7811
) {
2178 if (dmacsr
& HIFN_DMACSR_ILLR
)
2179 device_printf(sc
->sc_dev
, "illegal read\n");
2180 if (dmacsr
& HIFN_DMACSR_ILLW
)
2181 device_printf(sc
->sc_dev
, "illegal write\n");
2184 restart
= dmacsr
& (HIFN_DMACSR_C_ABORT
| HIFN_DMACSR_S_ABORT
|
2185 HIFN_DMACSR_D_ABORT
| HIFN_DMACSR_R_ABORT
);
2187 device_printf(sc
->sc_dev
, "abort, resetting.\n");
2188 hifnstats
.hst_abort
++;
2194 if ((dmacsr
& HIFN_DMACSR_C_WAIT
) && (dma
->cmdu
== 0)) {
2196 * If no slots to process and we receive a "waiting on
2197 * command" interrupt, we disable the "waiting on command"
2200 sc
->sc_dmaier
&= ~HIFN_DMAIER_C_WAIT
;
2201 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
2204 /* clear the rings */
2205 i
= dma
->resk
; u
= dma
->resu
;
2207 HIFN_RESR_SYNC(sc
, i
,
2208 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2209 if (dma
->resr
[i
].l
& htole32(HIFN_D_VALID
)) {
2210 HIFN_RESR_SYNC(sc
, i
,
2211 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2215 if (i
!= HIFN_D_RES_RSIZE
) {
2216 struct hifn_command
*cmd
;
2217 u_int8_t
*macbuf
= NULL
;
2219 HIFN_RES_SYNC(sc
, i
, BUS_DMASYNC_POSTREAD
);
2220 cmd
= dma
->hifn_commands
[i
];
2221 KASSERT(cmd
!= NULL
,
2222 ("hifn_intr: null command slot %u", i
));
2223 dma
->hifn_commands
[i
] = NULL
;
2225 if (cmd
->base_masks
& HIFN_BASE_CMD_MAC
) {
2226 macbuf
= dma
->result_bufs
[i
];
2230 hifn_callback(sc
, cmd
, macbuf
);
2231 hifnstats
.hst_opackets
++;
2235 if (++i
== (HIFN_D_RES_RSIZE
+ 1))
2238 dma
->resk
= i
; dma
->resu
= u
;
2240 i
= dma
->srck
; u
= dma
->srcu
;
2242 if (i
== HIFN_D_SRC_RSIZE
)
2244 HIFN_SRCR_SYNC(sc
, i
,
2245 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2246 if (dma
->srcr
[i
].l
& htole32(HIFN_D_VALID
)) {
2247 HIFN_SRCR_SYNC(sc
, i
,
2248 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2253 dma
->srck
= i
; dma
->srcu
= u
;
2255 i
= dma
->cmdk
; u
= dma
->cmdu
;
2257 HIFN_CMDR_SYNC(sc
, i
,
2258 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2259 if (dma
->cmdr
[i
].l
& htole32(HIFN_D_VALID
)) {
2260 HIFN_CMDR_SYNC(sc
, i
,
2261 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2264 if (i
!= HIFN_D_CMD_RSIZE
) {
2266 HIFN_CMD_SYNC(sc
, i
, BUS_DMASYNC_POSTWRITE
);
2268 if (++i
== (HIFN_D_CMD_RSIZE
+ 1))
2271 dma
->cmdk
= i
; dma
->cmdu
= u
;
2275 if (sc
->sc_needwakeup
) { /* XXX check high watermark */
2276 int wakeup
= sc
->sc_needwakeup
& (CRYPTO_SYMQ
|CRYPTO_ASYMQ
);
2279 device_printf(sc
->sc_dev
,
2280 "wakeup crypto (%x) u %d/%d/%d/%d\n",
2282 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
);
2284 sc
->sc_needwakeup
&= ~wakeup
;
2285 crypto_unblock(sc
->sc_cid
, wakeup
);
2292 * Allocate a new 'session' and return an encoded session id. 'sidp'
2293 * contains our registration id, and should contain an encoded session
2294 * id on successful allocation.
2297 hifn_newsession(device_t dev
, u_int32_t
*sidp
, struct cryptoini
*cri
)
2299 struct hifn_softc
*sc
= device_get_softc(dev
);
2300 struct cryptoini
*c
;
2301 int mac
= 0, cry
= 0, sesn
;
2302 struct hifn_session
*ses
= NULL
;
2303 unsigned long l_flags
;
2305 DPRINTF("%s()\n", __FUNCTION__
);
2307 KASSERT(sc
!= NULL
, ("hifn_newsession: null softc"));
2308 if (sidp
== NULL
|| cri
== NULL
|| sc
== NULL
) {
2309 DPRINTF("%s,%d: %s - EINVAL\n", __FILE__
, __LINE__
, __FUNCTION__
);
2314 if (sc
->sc_sessions
== NULL
) {
2315 ses
= sc
->sc_sessions
= (struct hifn_session
*)kmalloc(sizeof(*ses
),
2322 sc
->sc_nsessions
= 1;
2324 for (sesn
= 0; sesn
< sc
->sc_nsessions
; sesn
++) {
2325 if (!sc
->sc_sessions
[sesn
].hs_used
) {
2326 ses
= &sc
->sc_sessions
[sesn
];
2332 sesn
= sc
->sc_nsessions
;
2333 ses
= (struct hifn_session
*)kmalloc((sesn
+ 1) * sizeof(*ses
),
2339 bcopy(sc
->sc_sessions
, ses
, sesn
* sizeof(*ses
));
2340 bzero(sc
->sc_sessions
, sesn
* sizeof(*ses
));
2341 kfree(sc
->sc_sessions
);
2342 sc
->sc_sessions
= ses
;
2343 ses
= &sc
->sc_sessions
[sesn
];
2349 bzero(ses
, sizeof(*ses
));
2352 for (c
= cri
; c
!= NULL
; c
= c
->cri_next
) {
2353 switch (c
->cri_alg
) {
2356 case CRYPTO_MD5_HMAC
:
2357 case CRYPTO_SHA1_HMAC
:
2359 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2363 ses
->hs_mlen
= c
->cri_mlen
;
2364 if (ses
->hs_mlen
== 0) {
2365 switch (c
->cri_alg
) {
2367 case CRYPTO_MD5_HMAC
:
2371 case CRYPTO_SHA1_HMAC
:
2377 case CRYPTO_DES_CBC
:
2378 case CRYPTO_3DES_CBC
:
2379 case CRYPTO_AES_CBC
:
2380 /* XXX this may read fewer, does it matter? */
2381 read_random(ses
->hs_iv
,
2382 c
->cri_alg
== CRYPTO_AES_CBC
?
2383 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2387 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2393 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2397 if (mac
== 0 && cry
== 0) {
2398 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2402 *sidp
= HIFN_SID(device_get_unit(sc
->sc_dev
), sesn
);
2408 * Deallocate a session.
2409 * XXX this routine should run a zero'd mac/encrypt key into context ram.
2410 * XXX to blow away any keys already stored there.
2413 hifn_freesession(device_t dev
, u_int64_t tid
)
2415 struct hifn_softc
*sc
= device_get_softc(dev
);
2417 u_int32_t sid
= CRYPTO_SESID2LID(tid
);
2418 unsigned long l_flags
;
2420 DPRINTF("%s()\n", __FUNCTION__
);
2422 KASSERT(sc
!= NULL
, ("hifn_freesession: null softc"));
2424 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2429 session
= HIFN_SESSION(sid
);
2430 if (session
< sc
->sc_nsessions
) {
2431 bzero(&sc
->sc_sessions
[session
], sizeof(struct hifn_session
));
2434 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2443 hifn_process(device_t dev
, struct cryptop
*crp
, int hint
)
2445 struct hifn_softc
*sc
= device_get_softc(dev
);
2446 struct hifn_command
*cmd
= NULL
;
2447 int session
, err
, ivlen
;
2448 struct cryptodesc
*crd1
, *crd2
, *maccrd
, *enccrd
;
2450 DPRINTF("%s()\n", __FUNCTION__
);
2452 if (crp
== NULL
|| crp
->crp_callback
== NULL
) {
2453 hifnstats
.hst_invalid
++;
2454 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2457 session
= HIFN_SESSION(crp
->crp_sid
);
2459 if (sc
== NULL
|| session
>= sc
->sc_nsessions
) {
2460 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2465 cmd
= kmalloc(sizeof(struct hifn_command
), SLAB_ATOMIC
);
2467 hifnstats
.hst_nomem
++;
2471 memset(cmd
, 0, sizeof(*cmd
));
2473 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
2474 cmd
->src_skb
= (struct sk_buff
*)crp
->crp_buf
;
2475 cmd
->dst_skb
= (struct sk_buff
*)crp
->crp_buf
;
2476 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
2477 cmd
->src_io
= (struct uio
*)crp
->crp_buf
;
2478 cmd
->dst_io
= (struct uio
*)crp
->crp_buf
;
2480 cmd
->src_buf
= crp
->crp_buf
;
2481 cmd
->dst_buf
= crp
->crp_buf
;
2484 crd1
= crp
->crp_desc
;
2486 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2490 crd2
= crd1
->crd_next
;
2493 if (crd1
->crd_alg
== CRYPTO_MD5_HMAC
||
2494 crd1
->crd_alg
== CRYPTO_SHA1_HMAC
||
2495 crd1
->crd_alg
== CRYPTO_SHA1
||
2496 crd1
->crd_alg
== CRYPTO_MD5
) {
2499 } else if (crd1
->crd_alg
== CRYPTO_DES_CBC
||
2500 crd1
->crd_alg
== CRYPTO_3DES_CBC
||
2501 crd1
->crd_alg
== CRYPTO_AES_CBC
||
2502 crd1
->crd_alg
== CRYPTO_ARC4
) {
2503 if ((crd1
->crd_flags
& CRD_F_ENCRYPT
) == 0)
2504 cmd
->base_masks
|= HIFN_BASE_CMD_DECODE
;
2508 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2513 if ((crd1
->crd_alg
== CRYPTO_MD5_HMAC
||
2514 crd1
->crd_alg
== CRYPTO_SHA1_HMAC
||
2515 crd1
->crd_alg
== CRYPTO_MD5
||
2516 crd1
->crd_alg
== CRYPTO_SHA1
) &&
2517 (crd2
->crd_alg
== CRYPTO_DES_CBC
||
2518 crd2
->crd_alg
== CRYPTO_3DES_CBC
||
2519 crd2
->crd_alg
== CRYPTO_AES_CBC
||
2520 crd2
->crd_alg
== CRYPTO_ARC4
) &&
2521 ((crd2
->crd_flags
& CRD_F_ENCRYPT
) == 0)) {
2522 cmd
->base_masks
= HIFN_BASE_CMD_DECODE
;
2525 } else if ((crd1
->crd_alg
== CRYPTO_DES_CBC
||
2526 crd1
->crd_alg
== CRYPTO_ARC4
||
2527 crd1
->crd_alg
== CRYPTO_3DES_CBC
||
2528 crd1
->crd_alg
== CRYPTO_AES_CBC
) &&
2529 (crd2
->crd_alg
== CRYPTO_MD5_HMAC
||
2530 crd2
->crd_alg
== CRYPTO_SHA1_HMAC
||
2531 crd2
->crd_alg
== CRYPTO_MD5
||
2532 crd2
->crd_alg
== CRYPTO_SHA1
) &&
2533 (crd1
->crd_flags
& CRD_F_ENCRYPT
)) {
2538 * We cannot order the 7751 as requested
2540 DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
, crd1
->crd_alg
, crd2
->crd_alg
, crd1
->crd_flags
& CRD_F_ENCRYPT
);
2547 cmd
->enccrd
= enccrd
;
2548 cmd
->base_masks
|= HIFN_BASE_CMD_CRYPT
;
2549 switch (enccrd
->crd_alg
) {
2551 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_RC4
;
2553 case CRYPTO_DES_CBC
:
2554 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_DES
|
2555 HIFN_CRYPT_CMD_MODE_CBC
|
2556 HIFN_CRYPT_CMD_NEW_IV
;
2558 case CRYPTO_3DES_CBC
:
2559 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_3DES
|
2560 HIFN_CRYPT_CMD_MODE_CBC
|
2561 HIFN_CRYPT_CMD_NEW_IV
;
2563 case CRYPTO_AES_CBC
:
2564 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_AES
|
2565 HIFN_CRYPT_CMD_MODE_CBC
|
2566 HIFN_CRYPT_CMD_NEW_IV
;
2569 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2573 if (enccrd
->crd_alg
!= CRYPTO_ARC4
) {
2574 ivlen
= ((enccrd
->crd_alg
== CRYPTO_AES_CBC
) ?
2575 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2576 if (enccrd
->crd_flags
& CRD_F_ENCRYPT
) {
2577 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
2578 bcopy(enccrd
->crd_iv
, cmd
->iv
, ivlen
);
2580 bcopy(sc
->sc_sessions
[session
].hs_iv
,
2583 if ((enccrd
->crd_flags
& CRD_F_IV_PRESENT
)
2585 crypto_copyback(crp
->crp_flags
,
2586 crp
->crp_buf
, enccrd
->crd_inject
,
2590 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
2591 bcopy(enccrd
->crd_iv
, cmd
->iv
, ivlen
);
2593 crypto_copydata(crp
->crp_flags
,
2594 crp
->crp_buf
, enccrd
->crd_inject
,
2600 if (enccrd
->crd_flags
& CRD_F_KEY_EXPLICIT
)
2601 cmd
->cry_masks
|= HIFN_CRYPT_CMD_NEW_KEY
;
2602 cmd
->ck
= enccrd
->crd_key
;
2603 cmd
->cklen
= enccrd
->crd_klen
>> 3;
2604 cmd
->cry_masks
|= HIFN_CRYPT_CMD_NEW_KEY
;
2607 * Need to specify the size for the AES key in the masks.
2609 if ((cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) ==
2610 HIFN_CRYPT_CMD_ALG_AES
) {
2611 switch (cmd
->cklen
) {
2613 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_128
;
2616 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_192
;
2619 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_256
;
2622 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2630 cmd
->maccrd
= maccrd
;
2631 cmd
->base_masks
|= HIFN_BASE_CMD_MAC
;
2633 switch (maccrd
->crd_alg
) {
2635 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_MD5
|
2636 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HASH
|
2637 HIFN_MAC_CMD_POS_IPSEC
;
2639 case CRYPTO_MD5_HMAC
:
2640 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_MD5
|
2641 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HMAC
|
2642 HIFN_MAC_CMD_POS_IPSEC
| HIFN_MAC_CMD_TRUNC
;
2645 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_SHA1
|
2646 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HASH
|
2647 HIFN_MAC_CMD_POS_IPSEC
;
2649 case CRYPTO_SHA1_HMAC
:
2650 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_SHA1
|
2651 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HMAC
|
2652 HIFN_MAC_CMD_POS_IPSEC
| HIFN_MAC_CMD_TRUNC
;
2656 if (maccrd
->crd_alg
== CRYPTO_SHA1_HMAC
||
2657 maccrd
->crd_alg
== CRYPTO_MD5_HMAC
) {
2658 cmd
->mac_masks
|= HIFN_MAC_CMD_NEW_KEY
;
2659 bcopy(maccrd
->crd_key
, cmd
->mac
, maccrd
->crd_klen
>> 3);
2660 bzero(cmd
->mac
+ (maccrd
->crd_klen
>> 3),
2661 HIFN_MAC_KEY_LENGTH
- (maccrd
->crd_klen
>> 3));
2666 cmd
->session_num
= session
;
2669 err
= hifn_crypto(sc
, cmd
, crp
, hint
);
2672 } else if (err
== ERESTART
) {
2674 * There weren't enough resources to dispatch the request
2675 * to the part. Notify the caller so they'll requeue this
2676 * request and resubmit it again soon.
2680 device_printf(sc
->sc_dev
, "requeue request\n");
2683 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
2691 hifnstats
.hst_invalid
++;
2693 hifnstats
.hst_nomem
++;
2694 crp
->crp_etype
= err
;
2700 hifn_abort(struct hifn_softc
*sc
)
2702 struct hifn_dma
*dma
= sc
->sc_dma
;
2703 struct hifn_command
*cmd
;
2704 struct cryptop
*crp
;
2707 DPRINTF("%s()\n", __FUNCTION__
);
2709 i
= dma
->resk
; u
= dma
->resu
;
2711 cmd
= dma
->hifn_commands
[i
];
2712 KASSERT(cmd
!= NULL
, ("hifn_abort: null command slot %u", i
));
2713 dma
->hifn_commands
[i
] = NULL
;
2716 if ((dma
->resr
[i
].l
& htole32(HIFN_D_VALID
)) == 0) {
2717 /* Salvage what we can. */
2720 if (cmd
->base_masks
& HIFN_BASE_CMD_MAC
) {
2721 macbuf
= dma
->result_bufs
[i
];
2725 hifnstats
.hst_opackets
++;
2726 hifn_callback(sc
, cmd
, macbuf
);
2729 if (cmd
->src_map
== cmd
->dst_map
) {
2730 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2731 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
2733 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2734 BUS_DMASYNC_POSTWRITE
);
2735 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2736 BUS_DMASYNC_POSTREAD
);
2740 if (cmd
->src_skb
!= cmd
->dst_skb
) {
2742 m_freem(cmd
->src_m
);
2743 crp
->crp_buf
= (caddr_t
)cmd
->dst_m
;
2745 device_printf(sc
->sc_dev
,
2746 "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
2747 __FILE__
, __LINE__
);
2751 /* non-shared buffers cannot be restarted */
2752 if (cmd
->src_map
!= cmd
->dst_map
) {
2754 * XXX should be EAGAIN, delayed until
2757 crp
->crp_etype
= ENOMEM
;
2758 pci_unmap_buf(sc
, &cmd
->dst
);
2760 crp
->crp_etype
= ENOMEM
;
2762 pci_unmap_buf(sc
, &cmd
->src
);
2765 if (crp
->crp_etype
!= EAGAIN
)
2769 if (++i
== HIFN_D_RES_RSIZE
)
2773 dma
->resk
= i
; dma
->resu
= u
;
2775 hifn_reset_board(sc
, 1);
2777 hifn_init_pci_registers(sc
);
2781 hifn_callback(struct hifn_softc
*sc
, struct hifn_command
*cmd
, u_int8_t
*macbuf
)
2783 struct hifn_dma
*dma
= sc
->sc_dma
;
2784 struct cryptop
*crp
= cmd
->crp
;
2785 struct cryptodesc
*crd
;
2788 DPRINTF("%s()\n", __FUNCTION__
);
2791 if (cmd
->src_map
== cmd
->dst_map
) {
2792 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2793 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2795 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2796 BUS_DMASYNC_POSTWRITE
);
2797 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2798 BUS_DMASYNC_POSTREAD
);
2802 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
2803 if (cmd
->src_skb
!= cmd
->dst_skb
) {
2805 crp
->crp_buf
= (caddr_t
)cmd
->dst_m
;
2806 totlen
= cmd
->src_mapsize
;
2807 for (m
= cmd
->dst_m
; m
!= NULL
; m
= m
->m_next
) {
2808 if (totlen
< m
->m_len
) {
2814 cmd
->dst_m
->m_pkthdr
.len
= cmd
->src_m
->m_pkthdr
.len
;
2815 m_freem(cmd
->src_m
);
2817 device_printf(sc
->sc_dev
,
2818 "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
2819 __FILE__
, __LINE__
);
2824 if (cmd
->sloplen
!= 0) {
2825 crypto_copyback(crp
->crp_flags
, crp
->crp_buf
,
2826 cmd
->src_mapsize
- cmd
->sloplen
, cmd
->sloplen
,
2827 (caddr_t
)&dma
->slop
[cmd
->slopidx
]);
2830 i
= dma
->dstk
; u
= dma
->dstu
;
2832 if (i
== HIFN_D_DST_RSIZE
)
2835 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2836 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2838 if (dma
->dstr
[i
].l
& htole32(HIFN_D_VALID
)) {
2840 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2841 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2847 dma
->dstk
= i
; dma
->dstu
= u
;
2849 hifnstats
.hst_obytes
+= cmd
->dst_mapsize
;
2851 if ((cmd
->base_masks
& (HIFN_BASE_CMD_CRYPT
| HIFN_BASE_CMD_DECODE
)) ==
2852 HIFN_BASE_CMD_CRYPT
) {
2853 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
2854 if (crd
->crd_alg
!= CRYPTO_DES_CBC
&&
2855 crd
->crd_alg
!= CRYPTO_3DES_CBC
&&
2856 crd
->crd_alg
!= CRYPTO_AES_CBC
)
2858 ivlen
= ((crd
->crd_alg
== CRYPTO_AES_CBC
) ?
2859 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2860 crypto_copydata(crp
->crp_flags
, crp
->crp_buf
,
2861 crd
->crd_skip
+ crd
->crd_len
- ivlen
, ivlen
,
2862 cmd
->softc
->sc_sessions
[cmd
->session_num
].hs_iv
);
2867 if (macbuf
!= NULL
) {
2868 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
2871 if (crd
->crd_alg
!= CRYPTO_MD5
&&
2872 crd
->crd_alg
!= CRYPTO_SHA1
&&
2873 crd
->crd_alg
!= CRYPTO_MD5_HMAC
&&
2874 crd
->crd_alg
!= CRYPTO_SHA1_HMAC
) {
2877 len
= cmd
->softc
->sc_sessions
[cmd
->session_num
].hs_mlen
;
2878 crypto_copyback(crp
->crp_flags
, crp
->crp_buf
,
2879 crd
->crd_inject
, len
, macbuf
);
2884 if (cmd
->src_map
!= cmd
->dst_map
)
2885 pci_unmap_buf(sc
, &cmd
->dst
);
2886 pci_unmap_buf(sc
, &cmd
->src
);
2892 * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
2893 * and Group 1 registers; avoid conditions that could create
2894 * burst writes by doing a read in between the writes.
2896 * NB: The read we interpose is always to the same register;
2897 * we do this because reading from an arbitrary (e.g. last)
2898 * register may not always work.
2901 hifn_write_reg_0(struct hifn_softc
*sc
, bus_size_t reg
, u_int32_t val
)
2903 if (sc
->sc_flags
& HIFN_IS_7811
) {
2904 if (sc
->sc_bar0_lastreg
== reg
- 4)
2905 readl(sc
->sc_bar0
+ HIFN_0_PUCNFG
);
2906 sc
->sc_bar0_lastreg
= reg
;
2908 writel(val
, sc
->sc_bar0
+ reg
);
2912 hifn_write_reg_1(struct hifn_softc
*sc
, bus_size_t reg
, u_int32_t val
)
2914 if (sc
->sc_flags
& HIFN_IS_7811
) {
2915 if (sc
->sc_bar1_lastreg
== reg
- 4)
2916 readl(sc
->sc_bar1
+ HIFN_1_REVID
);
2917 sc
->sc_bar1_lastreg
= reg
;
2919 writel(val
, sc
->sc_bar1
+ reg
);
2923 static struct pci_device_id hifn_pci_tbl
[] = {
2924 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7951
,
2925 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2926 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7955
,
2927 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2928 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7956
,
2929 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2930 { PCI_VENDOR_NETSEC
, PCI_PRODUCT_NETSEC_7751
,
2931 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2932 { PCI_VENDOR_INVERTEX
, PCI_PRODUCT_INVERTEX_AEON
,
2933 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2934 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7811
,
2935 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2937 * Other vendors share this PCI ID as well, such as
2938 * http://www.powercrypt.com, and obviously they also
2941 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7751
,
2942 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2943 { 0, 0, 0, 0, 0, 0, }
2945 MODULE_DEVICE_TABLE(pci
, hifn_pci_tbl
);
2947 static struct pci_driver hifn_driver
= {
2949 .id_table
= hifn_pci_tbl
,
2950 .probe
= hifn_probe
,
2951 .remove
= hifn_remove
,
2952 /* add PM stuff here one day */
2955 static int __init
hifn_init (void)
2957 struct hifn_softc
*sc
= NULL
;
2960 DPRINTF("%s(%p)\n", __FUNCTION__
, hifn_init
);
2962 rc
= pci_register_driver(&hifn_driver
);
2963 pci_register_driver_compat(&hifn_driver
, rc
);
2968 static void __exit
hifn_exit (void)
2970 pci_unregister_driver(&hifn_driver
);
2973 module_init(hifn_init
);
2974 module_exit(hifn_exit
);
2976 MODULE_LICENSE("BSD");
2977 MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
2978 MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");