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 if (pci_set_mwi(dev
))
441 printk("hifn: found device with no IRQ assigned. check BIOS settings!");
442 pci_disable_device(dev
);
446 sc
= (struct hifn_softc
*) kmalloc(sizeof(*sc
), GFP_KERNEL
);
449 memset(sc
, 0, sizeof(*sc
));
451 softc_device_init(sc
, "hifn", num_chips
, hifn_methods
);
456 sc
->sc_num
= num_chips
++;
457 if (sc
->sc_num
< HIFN_MAX_CHIPS
)
458 hifn_chip_idx
[sc
->sc_num
] = sc
;
460 pci_set_drvdata(sc
->sc_pcidev
, sc
);
462 spin_lock_init(&sc
->sc_mtx
);
464 /* XXX handle power management */
467 * The 7951 and 795x have a random number generator and
468 * public key support; note this.
470 if (pci_get_vendor(dev
) == PCI_VENDOR_HIFN
&&
471 (pci_get_device(dev
) == PCI_PRODUCT_HIFN_7951
||
472 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7955
||
473 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7956
))
474 sc
->sc_flags
= HIFN_HAS_RNG
| HIFN_HAS_PUBLIC
;
476 * The 7811 has a random number generator and
477 * we also note it's identity 'cuz of some quirks.
479 if (pci_get_vendor(dev
) == PCI_VENDOR_HIFN
&&
480 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7811
)
481 sc
->sc_flags
|= HIFN_IS_7811
| HIFN_HAS_RNG
;
484 * The 795x parts support AES.
486 if (pci_get_vendor(dev
) == PCI_VENDOR_HIFN
&&
487 (pci_get_device(dev
) == PCI_PRODUCT_HIFN_7955
||
488 pci_get_device(dev
) == PCI_PRODUCT_HIFN_7956
)) {
489 sc
->sc_flags
|= HIFN_IS_7956
| HIFN_HAS_AES
;
491 * Select PLL configuration. This depends on the
492 * bus and board design and must be manually configured
493 * if the default setting is unacceptable.
495 hifn_getpllconfig(dev
, &sc
->sc_pllconfig
);
499 * Setup PCI resources. Note that we record the bus
500 * tag and handle for each register mapping, this is
501 * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
502 * and WRITE_REG_1 macros throughout the driver.
504 mem_start
= pci_resource_start(sc
->sc_pcidev
, 0);
505 mem_len
= pci_resource_len(sc
->sc_pcidev
, 0);
506 sc
->sc_bar0
= (ocf_iomem_t
) ioremap(mem_start
, mem_len
);
508 device_printf(sc
->sc_dev
, "cannot map bar%d register space\n", 0);
511 sc
->sc_bar0_lastreg
= (bus_size_t
) -1;
513 mem_start
= pci_resource_start(sc
->sc_pcidev
, 1);
514 mem_len
= pci_resource_len(sc
->sc_pcidev
, 1);
515 sc
->sc_bar1
= (ocf_iomem_t
) ioremap(mem_start
, mem_len
);
517 device_printf(sc
->sc_dev
, "cannot map bar%d register space\n", 1);
520 sc
->sc_bar1_lastreg
= (bus_size_t
) -1;
522 /* fix up the bus size */
523 if (pci_set_dma_mask(dev
, DMA_32BIT_MASK
)) {
524 device_printf(sc
->sc_dev
, "No usable DMA configuration, aborting.\n");
527 if (pci_set_consistent_dma_mask(dev
, DMA_32BIT_MASK
)) {
528 device_printf(sc
->sc_dev
,
529 "No usable consistent DMA configuration, aborting.\n");
536 * Setup the area where the Hifn DMA's descriptors
537 * and associated data structures.
539 sc
->sc_dma
= (struct hifn_dma
*) pci_alloc_consistent(dev
,
541 &sc
->sc_dma_physaddr
);
543 device_printf(sc
->sc_dev
, "cannot alloc sc_dma\n");
546 bzero(sc
->sc_dma
, sizeof(*sc
->sc_dma
));
549 * Reset the board and do the ``secret handshake''
550 * to enable the crypto support. Then complete the
551 * initialization procedure by setting up the interrupt
552 * and hooking in to the system crypto support so we'll
553 * get used for system services like the crypto device,
554 * IPsec, RNG device, etc.
556 hifn_reset_board(sc
, 0);
558 if (hifn_enable_crypto(sc
) != 0) {
559 device_printf(sc
->sc_dev
, "crypto enabling failed\n");
565 hifn_init_pci_registers(sc
);
567 pci_set_master(sc
->sc_pcidev
);
569 /* XXX can't dynamically determine ram type for 795x; force dram */
570 if (sc
->sc_flags
& HIFN_IS_7956
)
571 sc
->sc_drammodel
= 1;
572 else if (hifn_ramtype(sc
))
575 if (sc
->sc_drammodel
== 0)
581 * Workaround for NetSec 7751 rev A: half ram size because two
582 * of the address lines were left floating
584 if (pci_get_vendor(dev
) == PCI_VENDOR_NETSEC
&&
585 pci_get_device(dev
) == PCI_PRODUCT_NETSEC_7751
&&
586 pci_get_revid(dev
) == 0x61) /*XXX???*/
587 sc
->sc_ramsize
>>= 1;
590 * Arrange the interrupt line.
592 rc
= request_irq(dev
->irq
, hifn_intr
, IRQF_SHARED
, "hifn", sc
);
594 device_printf(sc
->sc_dev
, "could not map interrupt: %d\n", rc
);
597 sc
->sc_irq
= dev
->irq
;
602 * NB: Keep only the low 16 bits; this masks the chip id
605 rev
= READ_REG_1(sc
, HIFN_1_REVID
) & 0xffff;
607 rseg
= sc
->sc_ramsize
/ 1024;
609 if (sc
->sc_ramsize
>= (1024 * 1024)) {
613 device_printf(sc
->sc_dev
, "%s, rev %u, %d%cB %cram",
614 hifn_partname(sc
), rev
,
615 rseg
, rbase
, sc
->sc_drammodel
? 'd' : 's');
616 if (sc
->sc_flags
& HIFN_IS_7956
)
617 printf(", pll=0x%x<%s clk, %ux mult>",
619 sc
->sc_pllconfig
& HIFN_PLL_REF_SEL
? "ext" : "pci",
620 2 + 2*((sc
->sc_pllconfig
& HIFN_PLL_ND
) >> 11));
623 sc
->sc_cid
= crypto_get_driverid(softc_get_device(sc
),CRYPTOCAP_F_HARDWARE
);
624 if (sc
->sc_cid
< 0) {
625 device_printf(sc
->sc_dev
, "could not get crypto driver id\n");
629 WRITE_REG_0(sc
, HIFN_0_PUCNFG
,
630 READ_REG_0(sc
, HIFN_0_PUCNFG
) | HIFN_PUCNFG_CHIPID
);
631 ena
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
634 case HIFN_PUSTAT_ENA_2
:
635 crypto_register(sc
->sc_cid
, CRYPTO_3DES_CBC
, 0, 0);
636 crypto_register(sc
->sc_cid
, CRYPTO_ARC4
, 0, 0);
637 if (sc
->sc_flags
& HIFN_HAS_AES
)
638 crypto_register(sc
->sc_cid
, CRYPTO_AES_CBC
, 0, 0);
640 case HIFN_PUSTAT_ENA_1
:
641 crypto_register(sc
->sc_cid
, CRYPTO_MD5
, 0, 0);
642 crypto_register(sc
->sc_cid
, CRYPTO_SHA1
, 0, 0);
643 crypto_register(sc
->sc_cid
, CRYPTO_MD5_HMAC
, 0, 0);
644 crypto_register(sc
->sc_cid
, CRYPTO_SHA1_HMAC
, 0, 0);
645 crypto_register(sc
->sc_cid
, CRYPTO_DES_CBC
, 0, 0);
649 if (sc
->sc_flags
& (HIFN_HAS_PUBLIC
| HIFN_HAS_RNG
))
650 hifn_init_pubrng(sc
);
652 init_timer(&sc
->sc_tickto
);
653 sc
->sc_tickto
.function
= hifn_tick
;
654 sc
->sc_tickto
.data
= (unsigned long) sc
->sc_num
;
655 mod_timer(&sc
->sc_tickto
, jiffies
+ HZ
);
661 crypto_unregister_all(sc
->sc_cid
);
662 if (sc
->sc_irq
!= -1)
663 free_irq(sc
->sc_irq
, sc
);
665 /* Turn off DMA polling */
666 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
667 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
669 pci_free_consistent(sc
->sc_pcidev
,
671 sc
->sc_dma
, sc
->sc_dma_physaddr
);
678 * Detach an interface that successfully probed.
681 hifn_remove(struct pci_dev
*dev
)
683 struct hifn_softc
*sc
= pci_get_drvdata(dev
);
684 unsigned long l_flags
;
686 DPRINTF("%s()\n", __FUNCTION__
);
688 KASSERT(sc
!= NULL
, ("hifn_detach: null software carrier!"));
690 /* disable interrupts */
692 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, 0);
695 /*XXX other resources */
696 del_timer_sync(&sc
->sc_tickto
);
698 /* Turn off DMA polling */
699 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
700 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
702 crypto_unregister_all(sc
->sc_cid
);
704 free_irq(sc
->sc_irq
, sc
);
706 pci_free_consistent(sc
->sc_pcidev
, sizeof(*sc
->sc_dma
),
707 sc
->sc_dma
, sc
->sc_dma_physaddr
);
712 hifn_init_pubrng(struct hifn_softc
*sc
)
716 DPRINTF("%s()\n", __FUNCTION__
);
718 if ((sc
->sc_flags
& HIFN_IS_7811
) == 0) {
719 /* Reset 7951 public key/rng engine */
720 WRITE_REG_1(sc
, HIFN_1_PUB_RESET
,
721 READ_REG_1(sc
, HIFN_1_PUB_RESET
) | HIFN_PUBRST_RESET
);
723 for (i
= 0; i
< 100; i
++) {
725 if ((READ_REG_1(sc
, HIFN_1_PUB_RESET
) &
726 HIFN_PUBRST_RESET
) == 0)
731 device_printf(sc
->sc_dev
, "public key init failed\n");
736 /* Enable the rng, if available */
737 #ifdef CONFIG_OCF_RANDOMHARVEST
738 if (sc
->sc_flags
& HIFN_HAS_RNG
) {
739 if (sc
->sc_flags
& HIFN_IS_7811
) {
741 r
= READ_REG_1(sc
, HIFN_1_7811_RNGENA
);
742 if (r
& HIFN_7811_RNGENA_ENA
) {
743 r
&= ~HIFN_7811_RNGENA_ENA
;
744 WRITE_REG_1(sc
, HIFN_1_7811_RNGENA
, r
);
746 WRITE_REG_1(sc
, HIFN_1_7811_RNGCFG
,
747 HIFN_7811_RNGCFG_DEFL
);
748 r
|= HIFN_7811_RNGENA_ENA
;
749 WRITE_REG_1(sc
, HIFN_1_7811_RNGENA
, r
);
751 WRITE_REG_1(sc
, HIFN_1_RNG_CONFIG
,
752 READ_REG_1(sc
, HIFN_1_RNG_CONFIG
) |
756 crypto_rregister(sc
->sc_cid
, hifn_read_random
, sc
);
760 /* Enable public key engine, if available */
761 if (sc
->sc_flags
& HIFN_HAS_PUBLIC
) {
762 WRITE_REG_1(sc
, HIFN_1_PUB_IEN
, HIFN_PUBIEN_DONE
);
763 sc
->sc_dmaier
|= HIFN_DMAIER_PUBDONE
;
764 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
765 #ifdef HIFN_VULCANDEV
766 sc
->sc_pkdev
= make_dev(&vulcanpk_cdevsw
, 0,
767 UID_ROOT
, GID_WHEEL
, 0666,
769 sc
->sc_pkdev
->si_drv1
= sc
;
776 #ifdef CONFIG_OCF_RANDOMHARVEST
778 hifn_read_random(void *arg
, u_int32_t
*buf
, int len
)
780 struct hifn_softc
*sc
= (struct hifn_softc
*) arg
;
787 if (sc
->sc_flags
& HIFN_IS_7811
) {
788 /* ONLY VALID ON 7811!!!! */
789 for (i
= 0; i
< 5; i
++) {
790 sts
= READ_REG_1(sc
, HIFN_1_7811_RNGSTS
);
791 if (sts
& HIFN_7811_RNGSTS_UFL
) {
792 device_printf(sc
->sc_dev
,
793 "RNG underflow: disabling\n");
794 /* DAVIDM perhaps return -1 */
797 if ((sts
& HIFN_7811_RNGSTS_RDY
) == 0)
801 * There are at least two words in the RNG FIFO
805 buf
[rc
++] = READ_REG_1(sc
, HIFN_1_7811_RNGDAT
);
807 buf
[rc
++] = READ_REG_1(sc
, HIFN_1_7811_RNGDAT
);
810 buf
[rc
++] = READ_REG_1(sc
, HIFN_1_RNG_DATA
);
812 /* NB: discard first data read */
813 if (sc
->sc_rngfirst
) {
820 #endif /* CONFIG_OCF_RANDOMHARVEST */
823 hifn_puc_wait(struct hifn_softc
*sc
)
826 int reg
= HIFN_0_PUCTRL
;
828 if (sc
->sc_flags
& HIFN_IS_7956
) {
829 reg
= HIFN_0_PUCTRL2
;
832 for (i
= 5000; i
> 0; i
--) {
834 if (!(READ_REG_0(sc
, reg
) & HIFN_PUCTRL_RESET
))
838 device_printf(sc
->sc_dev
, "proc unit did not reset(0x%x)\n",
839 READ_REG_0(sc
, HIFN_0_PUCTRL
));
843 * Reset the processing unit.
846 hifn_reset_puc(struct hifn_softc
*sc
)
848 /* Reset processing unit */
849 int reg
= HIFN_0_PUCTRL
;
851 if (sc
->sc_flags
& HIFN_IS_7956
) {
852 reg
= HIFN_0_PUCTRL2
;
854 WRITE_REG_0(sc
, reg
, HIFN_PUCTRL_DMAENA
);
860 * Set the Retry and TRDY registers; note that we set them to
861 * zero because the 7811 locks up when forced to retry (section
862 * 3.6 of "Specification Update SU-0014-04". Not clear if we
863 * should do this for all Hifn parts, but it doesn't seem to hurt.
866 hifn_set_retry(struct hifn_softc
*sc
)
868 DPRINTF("%s()\n", __FUNCTION__
);
869 /* NB: RETRY only responds to 8-bit reads/writes */
870 pci_write_config_byte(sc
->sc_pcidev
, HIFN_RETRY_TIMEOUT
, 0);
871 pci_write_config_dword(sc
->sc_pcidev
, HIFN_TRDY_TIMEOUT
, 0);
872 /* piggy back the cache line setting here */
873 pci_write_config_byte(sc
->sc_pcidev
, PCI_CACHE_LINE_SIZE
, hifn_cache_linesize
);
877 * Resets the board. Values in the regesters are left as is
878 * from the reset (i.e. initial values are assigned elsewhere).
881 hifn_reset_board(struct hifn_softc
*sc
, int full
)
885 DPRINTF("%s()\n", __FUNCTION__
);
887 * Set polling in the DMA configuration register to zero. 0x7 avoids
888 * resetting the board and zeros out the other fields.
890 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
891 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
894 * Now that polling has been disabled, we have to wait 1 ms
895 * before resetting the board.
899 /* Reset the DMA unit */
901 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MODE
);
904 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
,
905 HIFN_DMACNFG_MODE
| HIFN_DMACNFG_MSTRESET
);
909 KASSERT(sc
->sc_dma
!= NULL
, ("hifn_reset_board: null DMA tag!"));
910 bzero(sc
->sc_dma
, sizeof(*sc
->sc_dma
));
912 /* Bring dma unit out of reset */
913 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
914 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
919 if (sc
->sc_flags
& HIFN_IS_7811
) {
920 for (reg
= 0; reg
< 1000; reg
++) {
921 if (READ_REG_1(sc
, HIFN_1_7811_MIPSRST
) &
922 HIFN_MIPSRST_CRAMINIT
)
927 device_printf(sc
->sc_dev
, ": cram init timeout\n");
929 /* set up DMA configuration register #2 */
930 /* turn off all PK and BAR0 swaps */
931 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG2
,
932 (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT
)|
933 (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT
)|
934 (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT
)|
935 (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT
));
940 hifn_next_signature(u_int32_t a
, u_int cnt
)
945 for (i
= 0; i
< cnt
; i
++) {
955 a
= (v
& 1) ^ (a
<< 1);
963 * Checks to see if crypto is already enabled. If crypto isn't enable,
964 * "hifn_enable_crypto" is called to enable it. The check is important,
965 * as enabling crypto twice will lock the board.
968 hifn_enable_crypto(struct hifn_softc
*sc
)
970 u_int32_t dmacfg
, ramcfg
, encl
, addr
, i
;
971 char offtbl
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
972 0x00, 0x00, 0x00, 0x00 };
974 DPRINTF("%s()\n", __FUNCTION__
);
976 ramcfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
);
977 dmacfg
= READ_REG_1(sc
, HIFN_1_DMA_CNFG
);
980 * The RAM config register's encrypt level bit needs to be set before
981 * every read performed on the encryption level register.
983 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
| HIFN_PUCNFG_CHIPID
);
985 encl
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
988 * Make sure we don't re-unlock. Two unlocks kills chip until the
991 if (encl
== HIFN_PUSTAT_ENA_1
|| encl
== HIFN_PUSTAT_ENA_2
) {
994 device_printf(sc
->sc_dev
,
995 "Strong crypto already enabled!\n");
1000 if (encl
!= 0 && encl
!= HIFN_PUSTAT_ENA_0
) {
1003 device_printf(sc
->sc_dev
,
1004 "Unknown encryption level 0x%x\n", encl
);
1009 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_UNLOCK
|
1010 HIFN_DMACNFG_MSTRESET
| HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
1012 addr
= READ_REG_1(sc
, HIFN_UNLOCK_SECRET1
);
1014 WRITE_REG_1(sc
, HIFN_UNLOCK_SECRET2
, 0);
1017 for (i
= 0; i
<= 12; i
++) {
1018 addr
= hifn_next_signature(addr
, offtbl
[i
] + 0x101);
1019 WRITE_REG_1(sc
, HIFN_UNLOCK_SECRET2
, addr
);
1024 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
| HIFN_PUCNFG_CHIPID
);
1025 encl
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
1029 if (encl
!= HIFN_PUSTAT_ENA_1
&& encl
!= HIFN_PUSTAT_ENA_2
)
1030 device_printf(sc
->sc_dev
, "Engine is permanently "
1031 "locked until next system reset!\n");
1033 device_printf(sc
->sc_dev
, "Engine enabled "
1039 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
);
1040 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, dmacfg
);
1043 case HIFN_PUSTAT_ENA_1
:
1044 case HIFN_PUSTAT_ENA_2
:
1046 case HIFN_PUSTAT_ENA_0
:
1048 device_printf(sc
->sc_dev
, "disabled\n");
1056 * Give initial values to the registers listed in the "Register Space"
1057 * section of the HIFN Software Development reference manual.
1060 hifn_init_pci_registers(struct hifn_softc
*sc
)
1062 DPRINTF("%s()\n", __FUNCTION__
);
1064 /* write fixed values needed by the Initialization registers */
1065 WRITE_REG_0(sc
, HIFN_0_PUCTRL
, HIFN_PUCTRL_DMAENA
);
1066 WRITE_REG_0(sc
, HIFN_0_FIFOCNFG
, HIFN_FIFOCNFG_THRESHOLD
);
1067 WRITE_REG_0(sc
, HIFN_0_PUIER
, HIFN_PUIER_DSTOVER
);
1069 /* write all 4 ring address registers */
1070 WRITE_REG_1(sc
, HIFN_1_DMA_CRAR
, sc
->sc_dma_physaddr
+
1071 offsetof(struct hifn_dma
, cmdr
[0]));
1072 WRITE_REG_1(sc
, HIFN_1_DMA_SRAR
, sc
->sc_dma_physaddr
+
1073 offsetof(struct hifn_dma
, srcr
[0]));
1074 WRITE_REG_1(sc
, HIFN_1_DMA_DRAR
, sc
->sc_dma_physaddr
+
1075 offsetof(struct hifn_dma
, dstr
[0]));
1076 WRITE_REG_1(sc
, HIFN_1_DMA_RRAR
, sc
->sc_dma_physaddr
+
1077 offsetof(struct hifn_dma
, resr
[0]));
1081 /* write status register */
1082 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1083 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
|
1084 HIFN_DMACSR_S_CTRL_DIS
| HIFN_DMACSR_C_CTRL_DIS
|
1085 HIFN_DMACSR_D_ABORT
| HIFN_DMACSR_D_DONE
| HIFN_DMACSR_D_LAST
|
1086 HIFN_DMACSR_D_WAIT
| HIFN_DMACSR_D_OVER
|
1087 HIFN_DMACSR_R_ABORT
| HIFN_DMACSR_R_DONE
| HIFN_DMACSR_R_LAST
|
1088 HIFN_DMACSR_R_WAIT
| HIFN_DMACSR_R_OVER
|
1089 HIFN_DMACSR_S_ABORT
| HIFN_DMACSR_S_DONE
| HIFN_DMACSR_S_LAST
|
1090 HIFN_DMACSR_S_WAIT
|
1091 HIFN_DMACSR_C_ABORT
| HIFN_DMACSR_C_DONE
| HIFN_DMACSR_C_LAST
|
1092 HIFN_DMACSR_C_WAIT
|
1093 HIFN_DMACSR_ENGINE
|
1094 ((sc
->sc_flags
& HIFN_HAS_PUBLIC
) ?
1095 HIFN_DMACSR_PUBDONE
: 0) |
1096 ((sc
->sc_flags
& HIFN_IS_7811
) ?
1097 HIFN_DMACSR_ILLW
| HIFN_DMACSR_ILLR
: 0));
1099 sc
->sc_d_busy
= sc
->sc_r_busy
= sc
->sc_s_busy
= sc
->sc_c_busy
= 0;
1100 sc
->sc_dmaier
|= HIFN_DMAIER_R_DONE
| HIFN_DMAIER_C_ABORT
|
1101 HIFN_DMAIER_D_OVER
| HIFN_DMAIER_R_OVER
|
1102 HIFN_DMAIER_S_ABORT
| HIFN_DMAIER_D_ABORT
| HIFN_DMAIER_R_ABORT
|
1103 ((sc
->sc_flags
& HIFN_IS_7811
) ?
1104 HIFN_DMAIER_ILLW
| HIFN_DMAIER_ILLR
: 0);
1105 sc
->sc_dmaier
&= ~HIFN_DMAIER_C_WAIT
;
1106 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
1109 if (sc
->sc_flags
& HIFN_IS_7956
) {
1112 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, HIFN_PUCNFG_COMPSING
|
1113 HIFN_PUCNFG_TCALLPHASES
|
1114 HIFN_PUCNFG_TCDRVTOTEM
| HIFN_PUCNFG_BUS32
);
1116 /* turn off the clocks and insure bypass is set */
1117 pll
= READ_REG_1(sc
, HIFN_1_PLL
);
1118 pll
= (pll
&~ (HIFN_PLL_PK_CLK_SEL
| HIFN_PLL_PE_CLK_SEL
))
1119 | HIFN_PLL_BP
| HIFN_PLL_MBSET
;
1120 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1121 DELAY(10*1000); /* 10ms */
1123 /* change configuration */
1124 pll
= (pll
&~ HIFN_PLL_CONFIG
) | sc
->sc_pllconfig
;
1125 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1126 DELAY(10*1000); /* 10ms */
1128 /* disable bypass */
1129 pll
&= ~HIFN_PLL_BP
;
1130 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1131 /* enable clocks with new configuration */
1132 pll
|= HIFN_PLL_PK_CLK_SEL
| HIFN_PLL_PE_CLK_SEL
;
1133 WRITE_REG_1(sc
, HIFN_1_PLL
, pll
);
1135 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, HIFN_PUCNFG_COMPSING
|
1136 HIFN_PUCNFG_DRFR_128
| HIFN_PUCNFG_TCALLPHASES
|
1137 HIFN_PUCNFG_TCDRVTOTEM
| HIFN_PUCNFG_BUS32
|
1138 (sc
->sc_drammodel
? HIFN_PUCNFG_DRAM
: HIFN_PUCNFG_SRAM
));
1141 WRITE_REG_0(sc
, HIFN_0_PUISR
, HIFN_PUISR_DSTOVER
);
1142 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
1143 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
| HIFN_DMACNFG_LAST
|
1144 ((HIFN_POLL_FREQUENCY
<< 16 ) & HIFN_DMACNFG_POLLFREQ
) |
1145 ((HIFN_POLL_SCALAR
<< 8) & HIFN_DMACNFG_POLLINVAL
));
1149 * The maximum number of sessions supported by the card
1150 * is dependent on the amount of context ram, which
1151 * encryption algorithms are enabled, and how compression
1152 * is configured. This should be configured before this
1153 * routine is called.
1156 hifn_sessions(struct hifn_softc
*sc
)
1161 DPRINTF("%s()\n", __FUNCTION__
);
1163 pucnfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
);
1165 if (pucnfg
& HIFN_PUCNFG_COMPSING
) {
1166 if (pucnfg
& HIFN_PUCNFG_ENCCNFG
)
1171 * 7955/7956 has internal context memory of 32K
1173 if (sc
->sc_flags
& HIFN_IS_7956
)
1174 sc
->sc_maxses
= 32768 / ctxsize
;
1177 ((sc
->sc_ramsize
- 32768) / ctxsize
);
1179 sc
->sc_maxses
= sc
->sc_ramsize
/ 16384;
1181 if (sc
->sc_maxses
> 2048)
1182 sc
->sc_maxses
= 2048;
1186 * Determine ram type (sram or dram). Board should be just out of a reset
1187 * state when this is called.
1190 hifn_ramtype(struct hifn_softc
*sc
)
1192 u_int8_t data
[8], dataexpect
[8];
1195 for (i
= 0; i
< sizeof(data
); i
++)
1196 data
[i
] = dataexpect
[i
] = 0x55;
1197 if (hifn_writeramaddr(sc
, 0, data
))
1199 if (hifn_readramaddr(sc
, 0, data
))
1201 if (bcmp(data
, dataexpect
, sizeof(data
)) != 0) {
1202 sc
->sc_drammodel
= 1;
1206 for (i
= 0; i
< sizeof(data
); i
++)
1207 data
[i
] = dataexpect
[i
] = 0xaa;
1208 if (hifn_writeramaddr(sc
, 0, data
))
1210 if (hifn_readramaddr(sc
, 0, data
))
1212 if (bcmp(data
, dataexpect
, sizeof(data
)) != 0) {
1213 sc
->sc_drammodel
= 1;
1220 #define HIFN_SRAM_MAX (32 << 20)
1221 #define HIFN_SRAM_STEP_SIZE 16384
1222 #define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
1225 hifn_sramsize(struct hifn_softc
*sc
)
1229 u_int8_t dataexpect
[sizeof(data
)];
1232 for (i
= 0; i
< sizeof(data
); i
++)
1233 data
[i
] = dataexpect
[i
] = i
^ 0x5a;
1235 for (i
= HIFN_SRAM_GRANULARITY
- 1; i
>= 0; i
--) {
1236 a
= i
* HIFN_SRAM_STEP_SIZE
;
1237 bcopy(&i
, data
, sizeof(i
));
1238 hifn_writeramaddr(sc
, a
, data
);
1241 for (i
= 0; i
< HIFN_SRAM_GRANULARITY
; i
++) {
1242 a
= i
* HIFN_SRAM_STEP_SIZE
;
1243 bcopy(&i
, dataexpect
, sizeof(i
));
1244 if (hifn_readramaddr(sc
, a
, data
) < 0)
1246 if (bcmp(data
, dataexpect
, sizeof(data
)) != 0)
1248 sc
->sc_ramsize
= a
+ HIFN_SRAM_STEP_SIZE
;
1255 * XXX For dram boards, one should really try all of the
1256 * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
1257 * is already set up correctly.
1260 hifn_dramsize(struct hifn_softc
*sc
)
1264 if (sc
->sc_flags
& HIFN_IS_7956
) {
1266 * 7955/7956 have a fixed internal ram of only 32K.
1268 sc
->sc_ramsize
= 32768;
1270 cnfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
) &
1271 HIFN_PUCNFG_DRAMMASK
;
1272 sc
->sc_ramsize
= 1 << ((cnfg
>> 13) + 18);
1278 hifn_alloc_slot(struct hifn_softc
*sc
, int *cmdp
, int *srcp
, int *dstp
, int *resp
)
1280 struct hifn_dma
*dma
= sc
->sc_dma
;
1282 DPRINTF("%s()\n", __FUNCTION__
);
1284 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
1286 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1288 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1289 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
1290 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1292 *cmdp
= dma
->cmdi
++;
1293 dma
->cmdk
= dma
->cmdi
;
1295 if (dma
->srci
== HIFN_D_SRC_RSIZE
) {
1297 dma
->srcr
[HIFN_D_SRC_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1299 dma
->srcr
[HIFN_D_SRC_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1300 HIFN_SRCR_SYNC(sc
, HIFN_D_SRC_RSIZE
,
1301 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1303 *srcp
= dma
->srci
++;
1304 dma
->srck
= dma
->srci
;
1306 if (dma
->dsti
== HIFN_D_DST_RSIZE
) {
1308 dma
->dstr
[HIFN_D_DST_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1310 dma
->dstr
[HIFN_D_DST_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1311 HIFN_DSTR_SYNC(sc
, HIFN_D_DST_RSIZE
,
1312 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1314 *dstp
= dma
->dsti
++;
1315 dma
->dstk
= dma
->dsti
;
1317 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
1319 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1321 dma
->resr
[HIFN_D_RES_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1322 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
1323 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1325 *resp
= dma
->resi
++;
1326 dma
->resk
= dma
->resi
;
1330 hifn_writeramaddr(struct hifn_softc
*sc
, int addr
, u_int8_t
*data
)
1332 struct hifn_dma
*dma
= sc
->sc_dma
;
1333 hifn_base_command_t wc
;
1334 const u_int32_t masks
= HIFN_D_VALID
| HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
;
1335 int r
, cmdi
, resi
, srci
, dsti
;
1337 DPRINTF("%s()\n", __FUNCTION__
);
1339 wc
.masks
= htole16(3 << 13);
1340 wc
.session_num
= htole16(addr
>> 14);
1341 wc
.total_source_count
= htole16(8);
1342 wc
.total_dest_count
= htole16(addr
& 0x3fff);
1344 hifn_alloc_slot(sc
, &cmdi
, &srci
, &dsti
, &resi
);
1346 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1347 HIFN_DMACSR_C_CTRL_ENA
| HIFN_DMACSR_S_CTRL_ENA
|
1348 HIFN_DMACSR_D_CTRL_ENA
| HIFN_DMACSR_R_CTRL_ENA
);
1350 /* build write command */
1351 bzero(dma
->command_bufs
[cmdi
], HIFN_MAX_COMMAND
);
1352 *(hifn_base_command_t
*)dma
->command_bufs
[cmdi
] = wc
;
1353 bcopy(data
, &dma
->test_src
, sizeof(dma
->test_src
));
1355 dma
->srcr
[srci
].p
= htole32(sc
->sc_dma_physaddr
1356 + offsetof(struct hifn_dma
, test_src
));
1357 dma
->dstr
[dsti
].p
= htole32(sc
->sc_dma_physaddr
1358 + offsetof(struct hifn_dma
, test_dst
));
1360 dma
->cmdr
[cmdi
].l
= htole32(16 | masks
);
1361 dma
->srcr
[srci
].l
= htole32(8 | masks
);
1362 dma
->dstr
[dsti
].l
= htole32(4 | masks
);
1363 dma
->resr
[resi
].l
= htole32(4 | masks
);
1365 for (r
= 10000; r
>= 0; r
--) {
1367 if ((dma
->resr
[resi
].l
& htole32(HIFN_D_VALID
)) == 0)
1371 device_printf(sc
->sc_dev
, "writeramaddr -- "
1372 "result[%d](addr %d) still valid\n", resi
, addr
);
1378 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1379 HIFN_DMACSR_C_CTRL_DIS
| HIFN_DMACSR_S_CTRL_DIS
|
1380 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
);
1386 hifn_readramaddr(struct hifn_softc
*sc
, int addr
, u_int8_t
*data
)
1388 struct hifn_dma
*dma
= sc
->sc_dma
;
1389 hifn_base_command_t rc
;
1390 const u_int32_t masks
= HIFN_D_VALID
| HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
;
1391 int r
, cmdi
, srci
, dsti
, resi
;
1393 DPRINTF("%s()\n", __FUNCTION__
);
1395 rc
.masks
= htole16(2 << 13);
1396 rc
.session_num
= htole16(addr
>> 14);
1397 rc
.total_source_count
= htole16(addr
& 0x3fff);
1398 rc
.total_dest_count
= htole16(8);
1400 hifn_alloc_slot(sc
, &cmdi
, &srci
, &dsti
, &resi
);
1402 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1403 HIFN_DMACSR_C_CTRL_ENA
| HIFN_DMACSR_S_CTRL_ENA
|
1404 HIFN_DMACSR_D_CTRL_ENA
| HIFN_DMACSR_R_CTRL_ENA
);
1406 bzero(dma
->command_bufs
[cmdi
], HIFN_MAX_COMMAND
);
1407 *(hifn_base_command_t
*)dma
->command_bufs
[cmdi
] = rc
;
1409 dma
->srcr
[srci
].p
= htole32(sc
->sc_dma_physaddr
+
1410 offsetof(struct hifn_dma
, test_src
));
1412 dma
->dstr
[dsti
].p
= htole32(sc
->sc_dma_physaddr
+
1413 offsetof(struct hifn_dma
, test_dst
));
1415 dma
->cmdr
[cmdi
].l
= htole32(8 | masks
);
1416 dma
->srcr
[srci
].l
= htole32(8 | masks
);
1417 dma
->dstr
[dsti
].l
= htole32(8 | masks
);
1418 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
| masks
);
1420 for (r
= 10000; r
>= 0; r
--) {
1422 if ((dma
->resr
[resi
].l
& htole32(HIFN_D_VALID
)) == 0)
1426 device_printf(sc
->sc_dev
, "readramaddr -- "
1427 "result[%d](addr %d) still valid\n", resi
, addr
);
1431 bcopy(&dma
->test_dst
, data
, sizeof(dma
->test_dst
));
1434 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1435 HIFN_DMACSR_C_CTRL_DIS
| HIFN_DMACSR_S_CTRL_DIS
|
1436 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
);
1442 * Initialize the descriptor rings.
1445 hifn_init_dma(struct hifn_softc
*sc
)
1447 struct hifn_dma
*dma
= sc
->sc_dma
;
1450 DPRINTF("%s()\n", __FUNCTION__
);
1454 /* initialize static pointer values */
1455 for (i
= 0; i
< HIFN_D_CMD_RSIZE
; i
++)
1456 dma
->cmdr
[i
].p
= htole32(sc
->sc_dma_physaddr
+
1457 offsetof(struct hifn_dma
, command_bufs
[i
][0]));
1458 for (i
= 0; i
< HIFN_D_RES_RSIZE
; i
++)
1459 dma
->resr
[i
].p
= htole32(sc
->sc_dma_physaddr
+
1460 offsetof(struct hifn_dma
, result_bufs
[i
][0]));
1462 dma
->cmdr
[HIFN_D_CMD_RSIZE
].p
=
1463 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, cmdr
[0]));
1464 dma
->srcr
[HIFN_D_SRC_RSIZE
].p
=
1465 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, srcr
[0]));
1466 dma
->dstr
[HIFN_D_DST_RSIZE
].p
=
1467 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, dstr
[0]));
1468 dma
->resr
[HIFN_D_RES_RSIZE
].p
=
1469 htole32(sc
->sc_dma_physaddr
+ offsetof(struct hifn_dma
, resr
[0]));
1471 dma
->cmdu
= dma
->srcu
= dma
->dstu
= dma
->resu
= 0;
1472 dma
->cmdi
= dma
->srci
= dma
->dsti
= dma
->resi
= 0;
1473 dma
->cmdk
= dma
->srck
= dma
->dstk
= dma
->resk
= 0;
1477 * Writes out the raw command buffer space. Returns the
1478 * command buffer size.
1481 hifn_write_command(struct hifn_command
*cmd
, u_int8_t
*buf
)
1483 struct hifn_softc
*sc
= NULL
;
1485 hifn_base_command_t
*base_cmd
;
1486 hifn_mac_command_t
*mac_cmd
;
1487 hifn_crypt_command_t
*cry_cmd
;
1488 int using_mac
, using_crypt
, len
, ivlen
;
1489 u_int32_t dlen
, slen
;
1491 DPRINTF("%s()\n", __FUNCTION__
);
1494 using_mac
= cmd
->base_masks
& HIFN_BASE_CMD_MAC
;
1495 using_crypt
= cmd
->base_masks
& HIFN_BASE_CMD_CRYPT
;
1497 base_cmd
= (hifn_base_command_t
*)buf_pos
;
1498 base_cmd
->masks
= htole16(cmd
->base_masks
);
1499 slen
= cmd
->src_mapsize
;
1501 dlen
= cmd
->dst_mapsize
- cmd
->sloplen
+ sizeof(u_int32_t
);
1503 dlen
= cmd
->dst_mapsize
;
1504 base_cmd
->total_source_count
= htole16(slen
& HIFN_BASE_CMD_LENMASK_LO
);
1505 base_cmd
->total_dest_count
= htole16(dlen
& HIFN_BASE_CMD_LENMASK_LO
);
1508 base_cmd
->session_num
= htole16(
1509 ((slen
<< HIFN_BASE_CMD_SRCLEN_S
) & HIFN_BASE_CMD_SRCLEN_M
) |
1510 ((dlen
<< HIFN_BASE_CMD_DSTLEN_S
) & HIFN_BASE_CMD_DSTLEN_M
));
1511 buf_pos
+= sizeof(hifn_base_command_t
);
1514 mac_cmd
= (hifn_mac_command_t
*)buf_pos
;
1515 dlen
= cmd
->maccrd
->crd_len
;
1516 mac_cmd
->source_count
= htole16(dlen
& 0xffff);
1518 mac_cmd
->masks
= htole16(cmd
->mac_masks
|
1519 ((dlen
<< HIFN_MAC_CMD_SRCLEN_S
) & HIFN_MAC_CMD_SRCLEN_M
));
1520 mac_cmd
->header_skip
= htole16(cmd
->maccrd
->crd_skip
);
1521 mac_cmd
->reserved
= 0;
1522 buf_pos
+= sizeof(hifn_mac_command_t
);
1526 cry_cmd
= (hifn_crypt_command_t
*)buf_pos
;
1527 dlen
= cmd
->enccrd
->crd_len
;
1528 cry_cmd
->source_count
= htole16(dlen
& 0xffff);
1530 cry_cmd
->masks
= htole16(cmd
->cry_masks
|
1531 ((dlen
<< HIFN_CRYPT_CMD_SRCLEN_S
) & HIFN_CRYPT_CMD_SRCLEN_M
));
1532 cry_cmd
->header_skip
= htole16(cmd
->enccrd
->crd_skip
);
1533 cry_cmd
->reserved
= 0;
1534 buf_pos
+= sizeof(hifn_crypt_command_t
);
1537 if (using_mac
&& cmd
->mac_masks
& HIFN_MAC_CMD_NEW_KEY
) {
1538 bcopy(cmd
->mac
, buf_pos
, HIFN_MAC_KEY_LENGTH
);
1539 buf_pos
+= HIFN_MAC_KEY_LENGTH
;
1542 if (using_crypt
&& cmd
->cry_masks
& HIFN_CRYPT_CMD_NEW_KEY
) {
1543 switch (cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) {
1544 case HIFN_CRYPT_CMD_ALG_3DES
:
1545 bcopy(cmd
->ck
, buf_pos
, HIFN_3DES_KEY_LENGTH
);
1546 buf_pos
+= HIFN_3DES_KEY_LENGTH
;
1548 case HIFN_CRYPT_CMD_ALG_DES
:
1549 bcopy(cmd
->ck
, buf_pos
, HIFN_DES_KEY_LENGTH
);
1550 buf_pos
+= HIFN_DES_KEY_LENGTH
;
1552 case HIFN_CRYPT_CMD_ALG_RC4
:
1557 clen
= MIN(cmd
->cklen
, len
);
1558 bcopy(cmd
->ck
, buf_pos
, clen
);
1565 case HIFN_CRYPT_CMD_ALG_AES
:
1567 * AES keys are variable 128, 192 and
1568 * 256 bits (16, 24 and 32 bytes).
1570 bcopy(cmd
->ck
, buf_pos
, cmd
->cklen
);
1571 buf_pos
+= cmd
->cklen
;
1576 if (using_crypt
&& cmd
->cry_masks
& HIFN_CRYPT_CMD_NEW_IV
) {
1577 switch (cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) {
1578 case HIFN_CRYPT_CMD_ALG_AES
:
1579 ivlen
= HIFN_AES_IV_LENGTH
;
1582 ivlen
= HIFN_IV_LENGTH
;
1585 bcopy(cmd
->iv
, buf_pos
, ivlen
);
1589 if ((cmd
->base_masks
& (HIFN_BASE_CMD_MAC
|HIFN_BASE_CMD_CRYPT
)) == 0) {
1594 return (buf_pos
- buf
);
1598 hifn_dmamap_aligned(struct hifn_operand
*op
)
1600 struct hifn_softc
*sc
= NULL
;
1603 DPRINTF("%s()\n", __FUNCTION__
);
1605 for (i
= 0; i
< op
->nsegs
; i
++) {
1606 if (op
->segs
[i
].ds_addr
& 3)
1608 if ((i
!= (op
->nsegs
- 1)) && (op
->segs
[i
].ds_len
& 3))
1615 hifn_dmamap_dstwrap(struct hifn_softc
*sc
, int idx
)
1617 struct hifn_dma
*dma
= sc
->sc_dma
;
1619 if (++idx
== HIFN_D_DST_RSIZE
) {
1620 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
| HIFN_D_JUMP
|
1621 HIFN_D_MASKDONEIRQ
);
1622 HIFN_DSTR_SYNC(sc
, idx
,
1623 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1630 hifn_dmamap_load_dst(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
1632 struct hifn_dma
*dma
= sc
->sc_dma
;
1633 struct hifn_operand
*dst
= &cmd
->dst
;
1635 int idx
, used
= 0, i
;
1637 DPRINTF("%s()\n", __FUNCTION__
);
1640 for (i
= 0; i
< dst
->nsegs
- 1; i
++) {
1641 dma
->dstr
[idx
].p
= htole32(dst
->segs
[i
].ds_addr
);
1642 dma
->dstr
[idx
].l
= htole32(HIFN_D_MASKDONEIRQ
| dst
->segs
[i
].ds_len
);
1644 dma
->dstr
[idx
].l
|= htole32(HIFN_D_VALID
);
1645 HIFN_DSTR_SYNC(sc
, idx
,
1646 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1649 idx
= hifn_dmamap_dstwrap(sc
, idx
);
1652 if (cmd
->sloplen
== 0) {
1653 p
= dst
->segs
[i
].ds_addr
;
1654 l
= HIFN_D_MASKDONEIRQ
| HIFN_D_LAST
|
1655 dst
->segs
[i
].ds_len
;
1657 p
= sc
->sc_dma_physaddr
+
1658 offsetof(struct hifn_dma
, slop
[cmd
->slopidx
]);
1659 l
= HIFN_D_MASKDONEIRQ
| HIFN_D_LAST
|
1662 if ((dst
->segs
[i
].ds_len
- cmd
->sloplen
) != 0) {
1663 dma
->dstr
[idx
].p
= htole32(dst
->segs
[i
].ds_addr
);
1664 dma
->dstr
[idx
].l
= htole32(HIFN_D_MASKDONEIRQ
|
1665 (dst
->segs
[i
].ds_len
- cmd
->sloplen
));
1667 dma
->dstr
[idx
].l
|= htole32(HIFN_D_VALID
);
1668 HIFN_DSTR_SYNC(sc
, idx
,
1669 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1672 idx
= hifn_dmamap_dstwrap(sc
, idx
);
1675 dma
->dstr
[idx
].p
= htole32(p
);
1676 dma
->dstr
[idx
].l
= htole32(l
);
1678 dma
->dstr
[idx
].l
|= htole32(HIFN_D_VALID
);
1679 HIFN_DSTR_SYNC(sc
, idx
, BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1682 idx
= hifn_dmamap_dstwrap(sc
, idx
);
1690 hifn_dmamap_srcwrap(struct hifn_softc
*sc
, int idx
)
1692 struct hifn_dma
*dma
= sc
->sc_dma
;
1694 if (++idx
== HIFN_D_SRC_RSIZE
) {
1695 dma
->srcr
[idx
].l
= htole32(HIFN_D_VALID
|
1696 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1697 HIFN_SRCR_SYNC(sc
, HIFN_D_SRC_RSIZE
,
1698 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1705 hifn_dmamap_load_src(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
1707 struct hifn_dma
*dma
= sc
->sc_dma
;
1708 struct hifn_operand
*src
= &cmd
->src
;
1712 DPRINTF("%s()\n", __FUNCTION__
);
1715 for (i
= 0; i
< src
->nsegs
; i
++) {
1716 if (i
== src
->nsegs
- 1)
1719 dma
->srcr
[idx
].p
= htole32(src
->segs
[i
].ds_addr
);
1720 dma
->srcr
[idx
].l
= htole32(src
->segs
[i
].ds_len
|
1721 HIFN_D_MASKDONEIRQ
| last
);
1723 dma
->srcr
[idx
].l
|= htole32(HIFN_D_VALID
);
1724 HIFN_SRCR_SYNC(sc
, idx
,
1725 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1727 idx
= hifn_dmamap_srcwrap(sc
, idx
);
1730 dma
->srcu
+= src
->nsegs
;
1737 struct hifn_softc
*sc
,
1738 struct hifn_command
*cmd
,
1739 struct cryptop
*crp
,
1742 struct hifn_dma
*dma
= sc
->sc_dma
;
1743 u_int32_t cmdlen
, csr
;
1744 int cmdi
, resi
, err
= 0;
1745 unsigned long l_flags
;
1747 DPRINTF("%s()\n", __FUNCTION__
);
1750 * need 1 cmd, and 1 res
1752 * NB: check this first since it's easy.
1755 if ((dma
->cmdu
+ 1) > HIFN_D_CMD_RSIZE
||
1756 (dma
->resu
+ 1) > HIFN_D_RES_RSIZE
) {
1759 device_printf(sc
->sc_dev
,
1760 "cmd/result exhaustion, cmdu %u resu %u\n",
1761 dma
->cmdu
, dma
->resu
);
1764 hifnstats
.hst_nomem_cr
++;
1765 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
1770 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
1771 if (pci_map_skb(sc
, &cmd
->src
, cmd
->src_skb
)) {
1772 hifnstats
.hst_nomem_load
++;
1776 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1777 if (pci_map_uio(sc
, &cmd
->src
, cmd
->src_io
)) {
1778 hifnstats
.hst_nomem_load
++;
1783 if (pci_map_buf(sc
, &cmd
->src
, cmd
->src_buf
, crp
->crp_ilen
)) {
1784 hifnstats
.hst_nomem_load
++;
1790 if (hifn_dmamap_aligned(&cmd
->src
)) {
1791 cmd
->sloplen
= cmd
->src_mapsize
& 3;
1792 cmd
->dst
= cmd
->src
;
1794 if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1795 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
1798 } else if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
1801 struct mbuf
*m
, *m0
, *mlast
;
1803 KASSERT(cmd
->dst_m
== cmd
->src_m
,
1804 ("hifn_crypto: dst_m initialized improperly"));
1805 hifnstats
.hst_unaligned
++;
1807 * Source is not aligned on a longword boundary.
1808 * Copy the data to insure alignment. If we fail
1809 * to allocate mbufs or clusters while doing this
1810 * we return ERESTART so the operation is requeued
1811 * at the crypto later, but only if there are
1812 * ops already posted to the hardware; otherwise we
1813 * have no guarantee that we'll be re-entered.
1815 totlen
= cmd
->src_mapsize
;
1816 if (cmd
->src_m
->m_flags
& M_PKTHDR
) {
1818 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
1819 if (m0
&& !m_dup_pkthdr(m0
, cmd
->src_m
, M_DONTWAIT
)) {
1825 MGET(m0
, M_DONTWAIT
, MT_DATA
);
1828 hifnstats
.hst_nomem_mbuf
++;
1829 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1832 if (totlen
>= MINCLSIZE
) {
1833 MCLGET(m0
, M_DONTWAIT
);
1834 if ((m0
->m_flags
& M_EXT
) == 0) {
1835 hifnstats
.hst_nomem_mcl
++;
1836 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1843 m0
->m_pkthdr
.len
= m0
->m_len
= len
;
1846 while (totlen
> 0) {
1847 MGET(m
, M_DONTWAIT
, MT_DATA
);
1849 hifnstats
.hst_nomem_mbuf
++;
1850 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1855 if (totlen
>= MINCLSIZE
) {
1856 MCLGET(m
, M_DONTWAIT
);
1857 if ((m
->m_flags
& M_EXT
) == 0) {
1858 hifnstats
.hst_nomem_mcl
++;
1859 err
= dma
->cmdu
? ERESTART
: ENOMEM
;
1868 m0
->m_pkthdr
.len
+= len
;
1876 device_printf(sc
->sc_dev
,
1877 "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
1878 __FILE__
, __LINE__
);
1883 device_printf(sc
->sc_dev
,
1884 "%s,%d: unaligned contig buffers not implemented\n",
1885 __FILE__
, __LINE__
);
1891 if (cmd
->dst_map
== NULL
) {
1892 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
1893 if (pci_map_skb(sc
, &cmd
->dst
, cmd
->dst_skb
)) {
1894 hifnstats
.hst_nomem_map
++;
1898 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1899 if (pci_map_uio(sc
, &cmd
->dst
, cmd
->dst_io
)) {
1900 hifnstats
.hst_nomem_load
++;
1905 if (pci_map_buf(sc
, &cmd
->dst
, cmd
->dst_buf
, crp
->crp_ilen
)) {
1906 hifnstats
.hst_nomem_load
++;
1915 device_printf(sc
->sc_dev
,
1916 "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
1917 READ_REG_1(sc
, HIFN_1_DMA_CSR
),
1918 READ_REG_1(sc
, HIFN_1_DMA_IER
),
1919 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
,
1920 cmd
->src_nsegs
, cmd
->dst_nsegs
);
1925 if (cmd
->src_map
== cmd
->dst_map
) {
1926 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
1927 BUS_DMASYNC_PREWRITE
|BUS_DMASYNC_PREREAD
);
1929 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
1930 BUS_DMASYNC_PREWRITE
);
1931 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
1932 BUS_DMASYNC_PREREAD
);
1937 * need N src, and N dst
1939 if ((dma
->srcu
+ cmd
->src_nsegs
) > HIFN_D_SRC_RSIZE
||
1940 (dma
->dstu
+ cmd
->dst_nsegs
+ 1) > HIFN_D_DST_RSIZE
) {
1943 device_printf(sc
->sc_dev
,
1944 "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
1945 dma
->srcu
, cmd
->src_nsegs
,
1946 dma
->dstu
, cmd
->dst_nsegs
);
1949 hifnstats
.hst_nomem_sd
++;
1954 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
1956 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
1958 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
|= htole32(HIFN_D_VALID
);
1959 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
1960 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1963 cmdlen
= hifn_write_command(cmd
, dma
->command_bufs
[cmdi
]);
1964 HIFN_CMD_SYNC(sc
, cmdi
, BUS_DMASYNC_PREWRITE
);
1966 /* .p for command/result already set */
1967 dma
->cmdr
[cmdi
].l
= htole32(cmdlen
| HIFN_D_LAST
|
1968 HIFN_D_MASKDONEIRQ
);
1970 dma
->cmdr
[cmdi
].l
|= htole32(HIFN_D_VALID
);
1971 HIFN_CMDR_SYNC(sc
, cmdi
,
1972 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1976 * We don't worry about missing an interrupt (which a "command wait"
1977 * interrupt salvages us from), unless there is more than one command
1980 if (dma
->cmdu
> 1) {
1981 sc
->sc_dmaier
|= HIFN_DMAIER_C_WAIT
;
1982 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
1985 hifnstats
.hst_ipackets
++;
1986 hifnstats
.hst_ibytes
+= cmd
->src_mapsize
;
1988 hifn_dmamap_load_src(sc
, cmd
);
1991 * Unlike other descriptors, we don't mask done interrupt from
1992 * result descriptor.
1996 device_printf(sc
->sc_dev
, "load res\n");
1998 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
2000 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_JUMP
|HIFN_D_MASKDONEIRQ
);
2002 dma
->resr
[HIFN_D_RES_RSIZE
].l
|= htole32(HIFN_D_VALID
);
2003 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
2004 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2007 KASSERT(dma
->hifn_commands
[resi
] == NULL
,
2008 ("hifn_crypto: command slot %u busy", resi
));
2009 dma
->hifn_commands
[resi
] = cmd
;
2010 HIFN_RES_SYNC(sc
, resi
, BUS_DMASYNC_PREREAD
);
2011 if ((hint
& CRYPTO_HINT_MORE
) && sc
->sc_curbatch
< hifn_maxbatch
) {
2012 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
|
2013 HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
);
2015 dma
->resr
[resi
].l
|= htole32(HIFN_D_VALID
);
2017 if (sc
->sc_curbatch
> hifnstats
.hst_maxbatch
)
2018 hifnstats
.hst_maxbatch
= sc
->sc_curbatch
;
2019 hifnstats
.hst_totbatch
++;
2021 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
| HIFN_D_LAST
);
2023 dma
->resr
[resi
].l
|= htole32(HIFN_D_VALID
);
2024 sc
->sc_curbatch
= 0;
2026 HIFN_RESR_SYNC(sc
, resi
,
2027 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2031 cmd
->slopidx
= resi
;
2033 hifn_dmamap_load_dst(sc
, cmd
);
2036 if (sc
->sc_c_busy
== 0) {
2037 csr
|= HIFN_DMACSR_C_CTRL_ENA
;
2040 if (sc
->sc_s_busy
== 0) {
2041 csr
|= HIFN_DMACSR_S_CTRL_ENA
;
2044 if (sc
->sc_r_busy
== 0) {
2045 csr
|= HIFN_DMACSR_R_CTRL_ENA
;
2048 if (sc
->sc_d_busy
== 0) {
2049 csr
|= HIFN_DMACSR_D_CTRL_ENA
;
2053 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, csr
);
2057 device_printf(sc
->sc_dev
, "command: stat %8x ier %8x\n",
2058 READ_REG_1(sc
, HIFN_1_DMA_CSR
),
2059 READ_REG_1(sc
, HIFN_1_DMA_IER
));
2065 KASSERT(err
== 0, ("hifn_crypto: success with error %u", err
));
2066 return (err
); /* success */
2069 if (cmd
->src_map
!= cmd
->dst_map
)
2070 pci_unmap_buf(sc
, &cmd
->dst
);
2073 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
2074 if (cmd
->src_skb
!= cmd
->dst_skb
)
2076 m_freem(cmd
->dst_m
);
2078 device_printf(sc
->sc_dev
,
2079 "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
2080 __FILE__
, __LINE__
);
2083 pci_unmap_buf(sc
, &cmd
->src
);
2090 hifn_tick(unsigned long arg
)
2092 struct hifn_softc
*sc
;
2093 unsigned long l_flags
;
2095 if (arg
>= HIFN_MAX_CHIPS
)
2097 sc
= hifn_chip_idx
[arg
];
2102 if (sc
->sc_active
== 0) {
2103 struct hifn_dma
*dma
= sc
->sc_dma
;
2106 if (dma
->cmdu
== 0 && sc
->sc_c_busy
) {
2108 r
|= HIFN_DMACSR_C_CTRL_DIS
;
2110 if (dma
->srcu
== 0 && sc
->sc_s_busy
) {
2112 r
|= HIFN_DMACSR_S_CTRL_DIS
;
2114 if (dma
->dstu
== 0 && sc
->sc_d_busy
) {
2116 r
|= HIFN_DMACSR_D_CTRL_DIS
;
2118 if (dma
->resu
== 0 && sc
->sc_r_busy
) {
2120 r
|= HIFN_DMACSR_R_CTRL_DIS
;
2123 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, r
);
2127 mod_timer(&sc
->sc_tickto
, jiffies
+ HZ
);
2131 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
2132 hifn_intr(int irq
, void *arg
)
2134 hifn_intr(int irq
, void *arg
, struct pt_regs
*regs
)
2137 struct hifn_softc
*sc
= arg
;
2138 struct hifn_dma
*dma
;
2139 u_int32_t dmacsr
, restart
;
2141 unsigned long l_flags
;
2143 dmacsr
= READ_REG_1(sc
, HIFN_1_DMA_CSR
);
2145 /* Nothing in the DMA unit interrupted */
2146 if ((dmacsr
& sc
->sc_dmaier
) == 0)
2155 device_printf(sc
->sc_dev
,
2156 "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
2157 dmacsr
, READ_REG_1(sc
, HIFN_1_DMA_IER
), sc
->sc_dmaier
,
2158 dma
->cmdi
, dma
->srci
, dma
->dsti
, dma
->resi
,
2159 dma
->cmdk
, dma
->srck
, dma
->dstk
, dma
->resk
,
2160 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
);
2164 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, dmacsr
& sc
->sc_dmaier
);
2166 if ((sc
->sc_flags
& HIFN_HAS_PUBLIC
) &&
2167 (dmacsr
& HIFN_DMACSR_PUBDONE
))
2168 WRITE_REG_1(sc
, HIFN_1_PUB_STATUS
,
2169 READ_REG_1(sc
, HIFN_1_PUB_STATUS
) | HIFN_PUBSTS_DONE
);
2171 restart
= dmacsr
& (HIFN_DMACSR_D_OVER
| HIFN_DMACSR_R_OVER
);
2173 device_printf(sc
->sc_dev
, "overrun %x\n", dmacsr
);
2175 if (sc
->sc_flags
& HIFN_IS_7811
) {
2176 if (dmacsr
& HIFN_DMACSR_ILLR
)
2177 device_printf(sc
->sc_dev
, "illegal read\n");
2178 if (dmacsr
& HIFN_DMACSR_ILLW
)
2179 device_printf(sc
->sc_dev
, "illegal write\n");
2182 restart
= dmacsr
& (HIFN_DMACSR_C_ABORT
| HIFN_DMACSR_S_ABORT
|
2183 HIFN_DMACSR_D_ABORT
| HIFN_DMACSR_R_ABORT
);
2185 device_printf(sc
->sc_dev
, "abort, resetting.\n");
2186 hifnstats
.hst_abort
++;
2192 if ((dmacsr
& HIFN_DMACSR_C_WAIT
) && (dma
->cmdu
== 0)) {
2194 * If no slots to process and we receive a "waiting on
2195 * command" interrupt, we disable the "waiting on command"
2198 sc
->sc_dmaier
&= ~HIFN_DMAIER_C_WAIT
;
2199 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
2202 /* clear the rings */
2203 i
= dma
->resk
; u
= dma
->resu
;
2205 HIFN_RESR_SYNC(sc
, i
,
2206 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2207 if (dma
->resr
[i
].l
& htole32(HIFN_D_VALID
)) {
2208 HIFN_RESR_SYNC(sc
, i
,
2209 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2213 if (i
!= HIFN_D_RES_RSIZE
) {
2214 struct hifn_command
*cmd
;
2215 u_int8_t
*macbuf
= NULL
;
2217 HIFN_RES_SYNC(sc
, i
, BUS_DMASYNC_POSTREAD
);
2218 cmd
= dma
->hifn_commands
[i
];
2219 KASSERT(cmd
!= NULL
,
2220 ("hifn_intr: null command slot %u", i
));
2221 dma
->hifn_commands
[i
] = NULL
;
2223 if (cmd
->base_masks
& HIFN_BASE_CMD_MAC
) {
2224 macbuf
= dma
->result_bufs
[i
];
2228 hifn_callback(sc
, cmd
, macbuf
);
2229 hifnstats
.hst_opackets
++;
2233 if (++i
== (HIFN_D_RES_RSIZE
+ 1))
2236 dma
->resk
= i
; dma
->resu
= u
;
2238 i
= dma
->srck
; u
= dma
->srcu
;
2240 if (i
== HIFN_D_SRC_RSIZE
)
2242 HIFN_SRCR_SYNC(sc
, i
,
2243 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2244 if (dma
->srcr
[i
].l
& htole32(HIFN_D_VALID
)) {
2245 HIFN_SRCR_SYNC(sc
, i
,
2246 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2251 dma
->srck
= i
; dma
->srcu
= u
;
2253 i
= dma
->cmdk
; u
= dma
->cmdu
;
2255 HIFN_CMDR_SYNC(sc
, i
,
2256 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2257 if (dma
->cmdr
[i
].l
& htole32(HIFN_D_VALID
)) {
2258 HIFN_CMDR_SYNC(sc
, i
,
2259 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2262 if (i
!= HIFN_D_CMD_RSIZE
) {
2264 HIFN_CMD_SYNC(sc
, i
, BUS_DMASYNC_POSTWRITE
);
2266 if (++i
== (HIFN_D_CMD_RSIZE
+ 1))
2269 dma
->cmdk
= i
; dma
->cmdu
= u
;
2273 if (sc
->sc_needwakeup
) { /* XXX check high watermark */
2274 int wakeup
= sc
->sc_needwakeup
& (CRYPTO_SYMQ
|CRYPTO_ASYMQ
);
2277 device_printf(sc
->sc_dev
,
2278 "wakeup crypto (%x) u %d/%d/%d/%d\n",
2280 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
);
2282 sc
->sc_needwakeup
&= ~wakeup
;
2283 crypto_unblock(sc
->sc_cid
, wakeup
);
2290 * Allocate a new 'session' and return an encoded session id. 'sidp'
2291 * contains our registration id, and should contain an encoded session
2292 * id on successful allocation.
2295 hifn_newsession(device_t dev
, u_int32_t
*sidp
, struct cryptoini
*cri
)
2297 struct hifn_softc
*sc
= device_get_softc(dev
);
2298 struct cryptoini
*c
;
2299 int mac
= 0, cry
= 0, sesn
;
2300 struct hifn_session
*ses
= NULL
;
2301 unsigned long l_flags
;
2303 DPRINTF("%s()\n", __FUNCTION__
);
2305 KASSERT(sc
!= NULL
, ("hifn_newsession: null softc"));
2306 if (sidp
== NULL
|| cri
== NULL
|| sc
== NULL
) {
2307 DPRINTF("%s,%d: %s - EINVAL\n", __FILE__
, __LINE__
, __FUNCTION__
);
2312 if (sc
->sc_sessions
== NULL
) {
2313 ses
= sc
->sc_sessions
= (struct hifn_session
*)kmalloc(sizeof(*ses
),
2320 sc
->sc_nsessions
= 1;
2322 for (sesn
= 0; sesn
< sc
->sc_nsessions
; sesn
++) {
2323 if (!sc
->sc_sessions
[sesn
].hs_used
) {
2324 ses
= &sc
->sc_sessions
[sesn
];
2330 sesn
= sc
->sc_nsessions
;
2331 ses
= (struct hifn_session
*)kmalloc((sesn
+ 1) * sizeof(*ses
),
2337 bcopy(sc
->sc_sessions
, ses
, sesn
* sizeof(*ses
));
2338 bzero(sc
->sc_sessions
, sesn
* sizeof(*ses
));
2339 kfree(sc
->sc_sessions
);
2340 sc
->sc_sessions
= ses
;
2341 ses
= &sc
->sc_sessions
[sesn
];
2347 bzero(ses
, sizeof(*ses
));
2350 for (c
= cri
; c
!= NULL
; c
= c
->cri_next
) {
2351 switch (c
->cri_alg
) {
2354 case CRYPTO_MD5_HMAC
:
2355 case CRYPTO_SHA1_HMAC
:
2357 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2361 ses
->hs_mlen
= c
->cri_mlen
;
2362 if (ses
->hs_mlen
== 0) {
2363 switch (c
->cri_alg
) {
2365 case CRYPTO_MD5_HMAC
:
2369 case CRYPTO_SHA1_HMAC
:
2375 case CRYPTO_DES_CBC
:
2376 case CRYPTO_3DES_CBC
:
2377 case CRYPTO_AES_CBC
:
2378 /* XXX this may read fewer, does it matter? */
2379 read_random(ses
->hs_iv
,
2380 c
->cri_alg
== CRYPTO_AES_CBC
?
2381 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2385 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2391 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2395 if (mac
== 0 && cry
== 0) {
2396 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2400 *sidp
= HIFN_SID(device_get_unit(sc
->sc_dev
), sesn
);
2406 * Deallocate a session.
2407 * XXX this routine should run a zero'd mac/encrypt key into context ram.
2408 * XXX to blow away any keys already stored there.
2411 hifn_freesession(device_t dev
, u_int64_t tid
)
2413 struct hifn_softc
*sc
= device_get_softc(dev
);
2415 u_int32_t sid
= CRYPTO_SESID2LID(tid
);
2416 unsigned long l_flags
;
2418 DPRINTF("%s()\n", __FUNCTION__
);
2420 KASSERT(sc
!= NULL
, ("hifn_freesession: null softc"));
2422 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2427 session
= HIFN_SESSION(sid
);
2428 if (session
< sc
->sc_nsessions
) {
2429 bzero(&sc
->sc_sessions
[session
], sizeof(struct hifn_session
));
2432 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2441 hifn_process(device_t dev
, struct cryptop
*crp
, int hint
)
2443 struct hifn_softc
*sc
= device_get_softc(dev
);
2444 struct hifn_command
*cmd
= NULL
;
2445 int session
, err
, ivlen
;
2446 struct cryptodesc
*crd1
, *crd2
, *maccrd
, *enccrd
;
2448 DPRINTF("%s()\n", __FUNCTION__
);
2450 if (crp
== NULL
|| crp
->crp_callback
== NULL
) {
2451 hifnstats
.hst_invalid
++;
2452 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2455 session
= HIFN_SESSION(crp
->crp_sid
);
2457 if (sc
== NULL
|| session
>= sc
->sc_nsessions
) {
2458 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2463 cmd
= kmalloc(sizeof(struct hifn_command
), SLAB_ATOMIC
);
2465 hifnstats
.hst_nomem
++;
2469 memset(cmd
, 0, sizeof(*cmd
));
2471 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
2472 cmd
->src_skb
= (struct sk_buff
*)crp
->crp_buf
;
2473 cmd
->dst_skb
= (struct sk_buff
*)crp
->crp_buf
;
2474 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
2475 cmd
->src_io
= (struct uio
*)crp
->crp_buf
;
2476 cmd
->dst_io
= (struct uio
*)crp
->crp_buf
;
2478 cmd
->src_buf
= crp
->crp_buf
;
2479 cmd
->dst_buf
= crp
->crp_buf
;
2482 crd1
= crp
->crp_desc
;
2484 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2488 crd2
= crd1
->crd_next
;
2491 if (crd1
->crd_alg
== CRYPTO_MD5_HMAC
||
2492 crd1
->crd_alg
== CRYPTO_SHA1_HMAC
||
2493 crd1
->crd_alg
== CRYPTO_SHA1
||
2494 crd1
->crd_alg
== CRYPTO_MD5
) {
2497 } else if (crd1
->crd_alg
== CRYPTO_DES_CBC
||
2498 crd1
->crd_alg
== CRYPTO_3DES_CBC
||
2499 crd1
->crd_alg
== CRYPTO_AES_CBC
||
2500 crd1
->crd_alg
== CRYPTO_ARC4
) {
2501 if ((crd1
->crd_flags
& CRD_F_ENCRYPT
) == 0)
2502 cmd
->base_masks
|= HIFN_BASE_CMD_DECODE
;
2506 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2511 if ((crd1
->crd_alg
== CRYPTO_MD5_HMAC
||
2512 crd1
->crd_alg
== CRYPTO_SHA1_HMAC
||
2513 crd1
->crd_alg
== CRYPTO_MD5
||
2514 crd1
->crd_alg
== CRYPTO_SHA1
) &&
2515 (crd2
->crd_alg
== CRYPTO_DES_CBC
||
2516 crd2
->crd_alg
== CRYPTO_3DES_CBC
||
2517 crd2
->crd_alg
== CRYPTO_AES_CBC
||
2518 crd2
->crd_alg
== CRYPTO_ARC4
) &&
2519 ((crd2
->crd_flags
& CRD_F_ENCRYPT
) == 0)) {
2520 cmd
->base_masks
= HIFN_BASE_CMD_DECODE
;
2523 } else if ((crd1
->crd_alg
== CRYPTO_DES_CBC
||
2524 crd1
->crd_alg
== CRYPTO_ARC4
||
2525 crd1
->crd_alg
== CRYPTO_3DES_CBC
||
2526 crd1
->crd_alg
== CRYPTO_AES_CBC
) &&
2527 (crd2
->crd_alg
== CRYPTO_MD5_HMAC
||
2528 crd2
->crd_alg
== CRYPTO_SHA1_HMAC
||
2529 crd2
->crd_alg
== CRYPTO_MD5
||
2530 crd2
->crd_alg
== CRYPTO_SHA1
) &&
2531 (crd1
->crd_flags
& CRD_F_ENCRYPT
)) {
2536 * We cannot order the 7751 as requested
2538 DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
, crd1
->crd_alg
, crd2
->crd_alg
, crd1
->crd_flags
& CRD_F_ENCRYPT
);
2545 cmd
->enccrd
= enccrd
;
2546 cmd
->base_masks
|= HIFN_BASE_CMD_CRYPT
;
2547 switch (enccrd
->crd_alg
) {
2549 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_RC4
;
2551 case CRYPTO_DES_CBC
:
2552 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_DES
|
2553 HIFN_CRYPT_CMD_MODE_CBC
|
2554 HIFN_CRYPT_CMD_NEW_IV
;
2556 case CRYPTO_3DES_CBC
:
2557 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_3DES
|
2558 HIFN_CRYPT_CMD_MODE_CBC
|
2559 HIFN_CRYPT_CMD_NEW_IV
;
2561 case CRYPTO_AES_CBC
:
2562 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_AES
|
2563 HIFN_CRYPT_CMD_MODE_CBC
|
2564 HIFN_CRYPT_CMD_NEW_IV
;
2567 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2571 if (enccrd
->crd_alg
!= CRYPTO_ARC4
) {
2572 ivlen
= ((enccrd
->crd_alg
== CRYPTO_AES_CBC
) ?
2573 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2574 if (enccrd
->crd_flags
& CRD_F_ENCRYPT
) {
2575 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
2576 bcopy(enccrd
->crd_iv
, cmd
->iv
, ivlen
);
2578 bcopy(sc
->sc_sessions
[session
].hs_iv
,
2581 if ((enccrd
->crd_flags
& CRD_F_IV_PRESENT
)
2583 crypto_copyback(crp
->crp_flags
,
2584 crp
->crp_buf
, enccrd
->crd_inject
,
2588 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
2589 bcopy(enccrd
->crd_iv
, cmd
->iv
, ivlen
);
2591 crypto_copydata(crp
->crp_flags
,
2592 crp
->crp_buf
, enccrd
->crd_inject
,
2598 if (enccrd
->crd_flags
& CRD_F_KEY_EXPLICIT
)
2599 cmd
->cry_masks
|= HIFN_CRYPT_CMD_NEW_KEY
;
2600 cmd
->ck
= enccrd
->crd_key
;
2601 cmd
->cklen
= enccrd
->crd_klen
>> 3;
2602 cmd
->cry_masks
|= HIFN_CRYPT_CMD_NEW_KEY
;
2605 * Need to specify the size for the AES key in the masks.
2607 if ((cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) ==
2608 HIFN_CRYPT_CMD_ALG_AES
) {
2609 switch (cmd
->cklen
) {
2611 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_128
;
2614 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_192
;
2617 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_256
;
2620 DPRINTF("%s,%d: %s - EINVAL\n",__FILE__
,__LINE__
,__FUNCTION__
);
2628 cmd
->maccrd
= maccrd
;
2629 cmd
->base_masks
|= HIFN_BASE_CMD_MAC
;
2631 switch (maccrd
->crd_alg
) {
2633 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_MD5
|
2634 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HASH
|
2635 HIFN_MAC_CMD_POS_IPSEC
;
2637 case CRYPTO_MD5_HMAC
:
2638 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_MD5
|
2639 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HMAC
|
2640 HIFN_MAC_CMD_POS_IPSEC
| HIFN_MAC_CMD_TRUNC
;
2643 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_SHA1
|
2644 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HASH
|
2645 HIFN_MAC_CMD_POS_IPSEC
;
2647 case CRYPTO_SHA1_HMAC
:
2648 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_SHA1
|
2649 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HMAC
|
2650 HIFN_MAC_CMD_POS_IPSEC
| HIFN_MAC_CMD_TRUNC
;
2654 if (maccrd
->crd_alg
== CRYPTO_SHA1_HMAC
||
2655 maccrd
->crd_alg
== CRYPTO_MD5_HMAC
) {
2656 cmd
->mac_masks
|= HIFN_MAC_CMD_NEW_KEY
;
2657 bcopy(maccrd
->crd_key
, cmd
->mac
, maccrd
->crd_klen
>> 3);
2658 bzero(cmd
->mac
+ (maccrd
->crd_klen
>> 3),
2659 HIFN_MAC_KEY_LENGTH
- (maccrd
->crd_klen
>> 3));
2664 cmd
->session_num
= session
;
2667 err
= hifn_crypto(sc
, cmd
, crp
, hint
);
2670 } else if (err
== ERESTART
) {
2672 * There weren't enough resources to dispatch the request
2673 * to the part. Notify the caller so they'll requeue this
2674 * request and resubmit it again soon.
2678 device_printf(sc
->sc_dev
, "requeue request\n");
2681 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
2689 hifnstats
.hst_invalid
++;
2691 hifnstats
.hst_nomem
++;
2692 crp
->crp_etype
= err
;
2698 hifn_abort(struct hifn_softc
*sc
)
2700 struct hifn_dma
*dma
= sc
->sc_dma
;
2701 struct hifn_command
*cmd
;
2702 struct cryptop
*crp
;
2705 DPRINTF("%s()\n", __FUNCTION__
);
2707 i
= dma
->resk
; u
= dma
->resu
;
2709 cmd
= dma
->hifn_commands
[i
];
2710 KASSERT(cmd
!= NULL
, ("hifn_abort: null command slot %u", i
));
2711 dma
->hifn_commands
[i
] = NULL
;
2714 if ((dma
->resr
[i
].l
& htole32(HIFN_D_VALID
)) == 0) {
2715 /* Salvage what we can. */
2718 if (cmd
->base_masks
& HIFN_BASE_CMD_MAC
) {
2719 macbuf
= dma
->result_bufs
[i
];
2723 hifnstats
.hst_opackets
++;
2724 hifn_callback(sc
, cmd
, macbuf
);
2727 if (cmd
->src_map
== cmd
->dst_map
) {
2728 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2729 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
2731 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2732 BUS_DMASYNC_POSTWRITE
);
2733 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2734 BUS_DMASYNC_POSTREAD
);
2738 if (cmd
->src_skb
!= cmd
->dst_skb
) {
2740 m_freem(cmd
->src_m
);
2741 crp
->crp_buf
= (caddr_t
)cmd
->dst_m
;
2743 device_printf(sc
->sc_dev
,
2744 "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
2745 __FILE__
, __LINE__
);
2749 /* non-shared buffers cannot be restarted */
2750 if (cmd
->src_map
!= cmd
->dst_map
) {
2752 * XXX should be EAGAIN, delayed until
2755 crp
->crp_etype
= ENOMEM
;
2756 pci_unmap_buf(sc
, &cmd
->dst
);
2758 crp
->crp_etype
= ENOMEM
;
2760 pci_unmap_buf(sc
, &cmd
->src
);
2763 if (crp
->crp_etype
!= EAGAIN
)
2767 if (++i
== HIFN_D_RES_RSIZE
)
2771 dma
->resk
= i
; dma
->resu
= u
;
2773 hifn_reset_board(sc
, 1);
2775 hifn_init_pci_registers(sc
);
2779 hifn_callback(struct hifn_softc
*sc
, struct hifn_command
*cmd
, u_int8_t
*macbuf
)
2781 struct hifn_dma
*dma
= sc
->sc_dma
;
2782 struct cryptop
*crp
= cmd
->crp
;
2783 struct cryptodesc
*crd
;
2786 DPRINTF("%s()\n", __FUNCTION__
);
2789 if (cmd
->src_map
== cmd
->dst_map
) {
2790 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2791 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2793 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2794 BUS_DMASYNC_POSTWRITE
);
2795 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2796 BUS_DMASYNC_POSTREAD
);
2800 if (crp
->crp_flags
& CRYPTO_F_SKBUF
) {
2801 if (cmd
->src_skb
!= cmd
->dst_skb
) {
2803 crp
->crp_buf
= (caddr_t
)cmd
->dst_m
;
2804 totlen
= cmd
->src_mapsize
;
2805 for (m
= cmd
->dst_m
; m
!= NULL
; m
= m
->m_next
) {
2806 if (totlen
< m
->m_len
) {
2812 cmd
->dst_m
->m_pkthdr
.len
= cmd
->src_m
->m_pkthdr
.len
;
2813 m_freem(cmd
->src_m
);
2815 device_printf(sc
->sc_dev
,
2816 "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
2817 __FILE__
, __LINE__
);
2822 if (cmd
->sloplen
!= 0) {
2823 crypto_copyback(crp
->crp_flags
, crp
->crp_buf
,
2824 cmd
->src_mapsize
- cmd
->sloplen
, cmd
->sloplen
,
2825 (caddr_t
)&dma
->slop
[cmd
->slopidx
]);
2828 i
= dma
->dstk
; u
= dma
->dstu
;
2830 if (i
== HIFN_D_DST_RSIZE
)
2833 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2834 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2836 if (dma
->dstr
[i
].l
& htole32(HIFN_D_VALID
)) {
2838 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2839 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2845 dma
->dstk
= i
; dma
->dstu
= u
;
2847 hifnstats
.hst_obytes
+= cmd
->dst_mapsize
;
2849 if ((cmd
->base_masks
& (HIFN_BASE_CMD_CRYPT
| HIFN_BASE_CMD_DECODE
)) ==
2850 HIFN_BASE_CMD_CRYPT
) {
2851 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
2852 if (crd
->crd_alg
!= CRYPTO_DES_CBC
&&
2853 crd
->crd_alg
!= CRYPTO_3DES_CBC
&&
2854 crd
->crd_alg
!= CRYPTO_AES_CBC
)
2856 ivlen
= ((crd
->crd_alg
== CRYPTO_AES_CBC
) ?
2857 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2858 crypto_copydata(crp
->crp_flags
, crp
->crp_buf
,
2859 crd
->crd_skip
+ crd
->crd_len
- ivlen
, ivlen
,
2860 cmd
->softc
->sc_sessions
[cmd
->session_num
].hs_iv
);
2865 if (macbuf
!= NULL
) {
2866 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
2869 if (crd
->crd_alg
!= CRYPTO_MD5
&&
2870 crd
->crd_alg
!= CRYPTO_SHA1
&&
2871 crd
->crd_alg
!= CRYPTO_MD5_HMAC
&&
2872 crd
->crd_alg
!= CRYPTO_SHA1_HMAC
) {
2875 len
= cmd
->softc
->sc_sessions
[cmd
->session_num
].hs_mlen
;
2876 crypto_copyback(crp
->crp_flags
, crp
->crp_buf
,
2877 crd
->crd_inject
, len
, macbuf
);
2882 if (cmd
->src_map
!= cmd
->dst_map
)
2883 pci_unmap_buf(sc
, &cmd
->dst
);
2884 pci_unmap_buf(sc
, &cmd
->src
);
2890 * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
2891 * and Group 1 registers; avoid conditions that could create
2892 * burst writes by doing a read in between the writes.
2894 * NB: The read we interpose is always to the same register;
2895 * we do this because reading from an arbitrary (e.g. last)
2896 * register may not always work.
2899 hifn_write_reg_0(struct hifn_softc
*sc
, bus_size_t reg
, u_int32_t val
)
2901 if (sc
->sc_flags
& HIFN_IS_7811
) {
2902 if (sc
->sc_bar0_lastreg
== reg
- 4)
2903 readl(sc
->sc_bar0
+ HIFN_0_PUCNFG
);
2904 sc
->sc_bar0_lastreg
= reg
;
2906 writel(val
, sc
->sc_bar0
+ reg
);
2910 hifn_write_reg_1(struct hifn_softc
*sc
, bus_size_t reg
, u_int32_t val
)
2912 if (sc
->sc_flags
& HIFN_IS_7811
) {
2913 if (sc
->sc_bar1_lastreg
== reg
- 4)
2914 readl(sc
->sc_bar1
+ HIFN_1_REVID
);
2915 sc
->sc_bar1_lastreg
= reg
;
2917 writel(val
, sc
->sc_bar1
+ reg
);
2921 static struct pci_device_id hifn_pci_tbl
[] = {
2922 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7951
,
2923 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2924 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7955
,
2925 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2926 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7956
,
2927 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2928 { PCI_VENDOR_NETSEC
, PCI_PRODUCT_NETSEC_7751
,
2929 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2930 { PCI_VENDOR_INVERTEX
, PCI_PRODUCT_INVERTEX_AEON
,
2931 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2932 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7811
,
2933 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2935 * Other vendors share this PCI ID as well, such as
2936 * http://www.powercrypt.com, and obviously they also
2939 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7751
,
2940 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, },
2941 { 0, 0, 0, 0, 0, 0, }
2943 MODULE_DEVICE_TABLE(pci
, hifn_pci_tbl
);
2945 static struct pci_driver hifn_driver
= {
2947 .id_table
= hifn_pci_tbl
,
2948 .probe
= hifn_probe
,
2949 .remove
= hifn_remove
,
2950 /* add PM stuff here one day */
2953 static int __init
hifn_init (void)
2955 struct hifn_softc
*sc
= NULL
;
2958 DPRINTF("%s(%p)\n", __FUNCTION__
, hifn_init
);
2960 rc
= pci_register_driver(&hifn_driver
);
2961 pci_register_driver_compat(&hifn_driver
, rc
);
2966 static void __exit
hifn_exit (void)
2968 pci_unregister_driver(&hifn_driver
);
2971 module_init(hifn_init
);
2972 module_exit(hifn_exit
);
2974 MODULE_LICENSE("BSD");
2975 MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
2976 MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");