1 /* $NetBSD: hifn7751.c,v 1.42 2009/04/28 22:43:50 dyoung Exp $ */
2 /* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */
3 /* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */
6 * Invertex AEON / Hifn 7751 driver
7 * Copyright (c) 1999 Invertex Inc. All rights reserved.
8 * Copyright (c) 1999 Theo de Raadt
9 * Copyright (c) 2000-2001 Network Security Technologies, Inc.
10 * http://www.netsec.net
11 * Copyright (c) 2003 Hifn Inc.
13 * This driver is based on a previous driver by Invertex, for which they
14 * requested: Please send any comments, feedback, bug-fixes, or feature
15 * requests to software@invertex.com.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. The name of the author may not be used to endorse or promote products
27 * derived from this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
34 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 * Effort sponsored in part by the Defense Advanced Research Projects
41 * Agency (DARPA) and Air Force Research Laboratory, Air Force
42 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
47 * Driver for various Hifn pre-HIPP encryption processors.
50 #include <sys/cdefs.h>
51 __KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.42 2009/04/28 22:43:50 dyoung Exp $");
56 #error hifn7751 requires rnd pseudo-devices
60 #include <sys/param.h>
61 #include <sys/systm.h>
63 #include <sys/errno.h>
64 #include <sys/malloc.h>
65 #include <sys/kernel.h>
67 #include <sys/device.h>
69 #include <uvm/uvm_extern.h>
73 #include <crypto/crypto.h>
74 #include <dev/rndvar.h>
76 #include <opencrypto/cryptodev.h>
80 #include <dev/pci/pcireg.h>
81 #include <dev/pci/pcivar.h>
82 #include <dev/pci/pcidevs.h>
84 #include <dev/pci/hifn7751reg.h>
85 #include <dev/pci/hifn7751var.h>
90 #define M_DUP_PKTHDR M_COPY_PKTHDR /* XXX */
94 extern int hifn_debug
; /* patchable */
99 #define HAVE_CRYPTO_LZS /* OpenBSD OCF supports CRYPTO_COMP_LZS */
103 * Prototypes and count for the pci_device structure
106 static int hifn_probe((struct device
*, void *, void *);
108 static int hifn_probe(device_t
, cfdata_t
, void *);
110 static void hifn_attach(device_t
, device_t
, void *);
112 CFATTACH_DECL(hifn
, sizeof(struct hifn_softc
),
113 hifn_probe
, hifn_attach
, NULL
, NULL
);
116 struct cfdriver hifn_cd
= {
121 static void hifn_reset_board(struct hifn_softc
*, int);
122 static void hifn_reset_puc(struct hifn_softc
*);
123 static void hifn_puc_wait(struct hifn_softc
*);
124 static const char *hifn_enable_crypto(struct hifn_softc
*, pcireg_t
);
125 static void hifn_set_retry(struct hifn_softc
*);
126 static void hifn_init_dma(struct hifn_softc
*);
127 static void hifn_init_pci_registers(struct hifn_softc
*);
128 static int hifn_sramsize(struct hifn_softc
*);
129 static int hifn_dramsize(struct hifn_softc
*);
130 static int hifn_ramtype(struct hifn_softc
*);
131 static void hifn_sessions(struct hifn_softc
*);
132 static int hifn_intr(void *);
133 static u_int
hifn_write_command(struct hifn_command
*, u_int8_t
*);
134 static u_int32_t
hifn_next_signature(u_int32_t a
, u_int cnt
);
135 static int hifn_newsession(void*, u_int32_t
*, struct cryptoini
*);
136 static int hifn_freesession(void*, u_int64_t
);
137 static int hifn_process(void*, struct cryptop
*, int);
138 static void hifn_callback(struct hifn_softc
*, struct hifn_command
*,
140 static int hifn_crypto(struct hifn_softc
*, struct hifn_command
*,
141 struct cryptop
*, int);
142 static int hifn_readramaddr(struct hifn_softc
*, int, u_int8_t
*);
143 static int hifn_writeramaddr(struct hifn_softc
*, int, u_int8_t
*);
144 static int hifn_dmamap_aligned(bus_dmamap_t
);
145 static int hifn_dmamap_load_src(struct hifn_softc
*,
146 struct hifn_command
*);
147 static int hifn_dmamap_load_dst(struct hifn_softc
*,
148 struct hifn_command
*);
149 static int hifn_init_pubrng(struct hifn_softc
*);
150 static void hifn_rng(void *);
151 static void hifn_tick(void *);
152 static void hifn_abort(struct hifn_softc
*);
153 static void hifn_alloc_slot(struct hifn_softc
*, int *, int *, int *,
155 static void hifn_write_4(struct hifn_softc
*, int, bus_size_t
, u_int32_t
);
156 static u_int32_t
hifn_read_4(struct hifn_softc
*, int, bus_size_t
);
157 #ifdef HAVE_CRYPTO_LZS
158 static int hifn_compression(struct hifn_softc
*, struct cryptop
*,
159 struct hifn_command
*);
160 static struct mbuf
*hifn_mkmbuf_chain(int, struct mbuf
*);
161 static int hifn_compress_enter(struct hifn_softc
*, struct hifn_command
*);
162 static void hifn_callback_comp(struct hifn_softc
*, struct hifn_command
*,
164 #endif /* HAVE_CRYPTO_LZS */
167 struct hifn_stats hifnstats
;
169 static const struct hifn_product
{
170 pci_vendor_id_t hifn_vendor
;
171 pci_product_id_t hifn_product
;
173 const char *hifn_name
;
174 } hifn_products
[] = {
175 { PCI_VENDOR_INVERTEX
, PCI_PRODUCT_INVERTEX_AEON
,
180 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7751
,
184 { PCI_VENDOR_NETSEC
, PCI_PRODUCT_NETSEC_7751
,
189 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7811
,
190 HIFN_IS_7811
| HIFN_HAS_RNG
| HIFN_HAS_LEDS
| HIFN_NO_BURSTWRITE
,
194 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7951
,
195 HIFN_HAS_RNG
| HIFN_HAS_PUBLIC
,
199 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7955
,
200 HIFN_HAS_RNG
| HIFN_HAS_PUBLIC
| HIFN_IS_7956
| HIFN_HAS_AES
,
204 { PCI_VENDOR_HIFN
, PCI_PRODUCT_HIFN_7956
,
205 HIFN_HAS_RNG
| HIFN_HAS_PUBLIC
| HIFN_IS_7956
| HIFN_HAS_AES
,
216 static const struct hifn_product
*
217 hifn_lookup(const struct pci_attach_args
*pa
)
219 const struct hifn_product
*hp
;
221 for (hp
= hifn_products
; hp
->hifn_name
!= NULL
; hp
++) {
222 if (PCI_VENDOR(pa
->pa_id
) == hp
->hifn_vendor
&&
223 PCI_PRODUCT(pa
->pa_id
) == hp
->hifn_product
)
230 hifn_probe(device_t parent
, cfdata_t match
, void *aux
)
232 struct pci_attach_args
*pa
= aux
;
234 if (hifn_lookup(pa
) != NULL
)
241 hifn_attach(device_t parent
, device_t self
, void *aux
)
243 struct hifn_softc
*sc
= device_private(self
);
244 struct pci_attach_args
*pa
= aux
;
245 const struct hifn_product
*hp
;
246 pci_chipset_tag_t pc
= pa
->pa_pc
;
247 pci_intr_handle_t ih
;
248 const char *intrstr
= NULL
;
251 bus_size_t iosize0
, iosize1
;
254 bus_dma_segment_t seg
;
259 hp
= hifn_lookup(pa
);
262 panic("hifn_attach: impossible");
265 aprint_naive(": Crypto processor\n");
266 aprint_normal(": %s, rev. %d\n", hp
->hifn_name
,
267 PCI_REVISION(pa
->pa_class
));
269 sc
->sc_pci_pc
= pa
->pa_pc
;
270 sc
->sc_pci_tag
= pa
->pa_tag
;
272 sc
->sc_flags
= hp
->hifn_flags
;
274 cmd
= pci_conf_read(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
275 cmd
|= PCI_COMMAND_MASTER_ENABLE
;
276 pci_conf_write(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
, cmd
);
278 if (pci_mapreg_map(pa
, HIFN_BAR0
, PCI_MAPREG_TYPE_MEM
, 0,
279 &sc
->sc_st0
, &sc
->sc_sh0
, NULL
, &iosize0
)) {
280 aprint_error_dev(&sc
->sc_dv
, "can't map mem space %d\n", 0);
284 if (pci_mapreg_map(pa
, HIFN_BAR1
, PCI_MAPREG_TYPE_MEM
, 0,
285 &sc
->sc_st1
, &sc
->sc_sh1
, NULL
, &iosize1
)) {
286 aprint_error_dev(&sc
->sc_dv
, "can't find mem space %d\n", 1);
292 if (sc
->sc_flags
& HIFN_NO_BURSTWRITE
) {
293 sc
->sc_waw_lastgroup
= -1;
294 sc
->sc_waw_lastreg
= 1;
297 sc
->sc_dmat
= pa
->pa_dmat
;
298 if (bus_dmamem_alloc(sc
->sc_dmat
, sizeof(*sc
->sc_dma
), PAGE_SIZE
, 0,
299 &seg
, 1, &rseg
, BUS_DMA_NOWAIT
)) {
300 aprint_error_dev(&sc
->sc_dv
, "can't alloc DMA buffer\n");
303 if (bus_dmamem_map(sc
->sc_dmat
, &seg
, rseg
, sizeof(*sc
->sc_dma
), &kva
,
305 aprint_error_dev(&sc
->sc_dv
, "can't map DMA buffers (%lu bytes)\n",
306 (u_long
)sizeof(*sc
->sc_dma
));
307 bus_dmamem_free(sc
->sc_dmat
, &seg
, rseg
);
310 if (bus_dmamap_create(sc
->sc_dmat
, sizeof(*sc
->sc_dma
), 1,
311 sizeof(*sc
->sc_dma
), 0, BUS_DMA_NOWAIT
, &dmamap
)) {
312 aprint_error_dev(&sc
->sc_dv
, "can't create DMA map\n");
313 bus_dmamem_unmap(sc
->sc_dmat
, kva
, sizeof(*sc
->sc_dma
));
314 bus_dmamem_free(sc
->sc_dmat
, &seg
, rseg
);
317 if (bus_dmamap_load(sc
->sc_dmat
, dmamap
, kva
, sizeof(*sc
->sc_dma
),
318 NULL
, BUS_DMA_NOWAIT
)) {
319 aprint_error_dev(&sc
->sc_dv
, "can't load DMA map\n");
320 bus_dmamap_destroy(sc
->sc_dmat
, dmamap
);
321 bus_dmamem_unmap(sc
->sc_dmat
, kva
, sizeof(*sc
->sc_dma
));
322 bus_dmamem_free(sc
->sc_dmat
, &seg
, rseg
);
325 sc
->sc_dmamap
= dmamap
;
326 sc
->sc_dma
= (struct hifn_dma
*)kva
;
327 memset(sc
->sc_dma
, 0, sizeof(*sc
->sc_dma
));
329 hifn_reset_board(sc
, 0);
331 if ((hifncap
= hifn_enable_crypto(sc
, pa
->pa_id
)) == NULL
) {
332 aprint_error_dev(&sc
->sc_dv
, "crypto enabling failed\n");
338 hifn_init_pci_registers(sc
);
340 /* XXX can't dynamically determine ram type for 795x; force dram */
341 if (sc
->sc_flags
& HIFN_IS_7956
)
342 sc
->sc_drammodel
= 1;
343 else if (hifn_ramtype(sc
))
346 if (sc
->sc_drammodel
== 0)
352 * Workaround for NetSec 7751 rev A: half ram size because two
353 * of the address lines were left floating
355 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_NETSEC
&&
356 PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_NETSEC_7751
&&
357 PCI_REVISION(pa
->pa_class
) == 0x61)
358 sc
->sc_ramsize
>>= 1;
360 if (pci_intr_map(pa
, &ih
)) {
361 aprint_error_dev(&sc
->sc_dv
, "couldn't map interrupt\n");
364 intrstr
= pci_intr_string(pc
, ih
);
366 sc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_NET
, hifn_intr
, sc
,
369 sc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_NET
, hifn_intr
, sc
);
371 if (sc
->sc_ih
== NULL
) {
372 aprint_error_dev(&sc
->sc_dv
, "couldn't establish interrupt\n");
374 aprint_error(" at %s", intrstr
);
381 rseg
= sc
->sc_ramsize
/ 1024;
383 if (sc
->sc_ramsize
>= (1024 * 1024)) {
387 aprint_normal_dev(&sc
->sc_dv
, "%s, %d%cB %cram, interrupting at %s\n",
388 hifncap
, rseg
, rbase
,
389 sc
->sc_drammodel
? 'd' : 's', intrstr
);
391 sc
->sc_cid
= crypto_get_driverid(0);
392 if (sc
->sc_cid
< 0) {
393 aprint_error_dev(&sc
->sc_dv
, "couldn't get crypto driver id\n");
397 WRITE_REG_0(sc
, HIFN_0_PUCNFG
,
398 READ_REG_0(sc
, HIFN_0_PUCNFG
) | HIFN_PUCNFG_CHIPID
);
399 ena
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
402 case HIFN_PUSTAT_ENA_2
:
403 crypto_register(sc
->sc_cid
, CRYPTO_3DES_CBC
, 0, 0,
404 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
405 crypto_register(sc
->sc_cid
, CRYPTO_ARC4
, 0, 0,
406 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
407 if (sc
->sc_flags
& HIFN_HAS_AES
)
408 crypto_register(sc
->sc_cid
, CRYPTO_AES_CBC
, 0, 0,
409 hifn_newsession
, hifn_freesession
,
412 case HIFN_PUSTAT_ENA_1
:
413 crypto_register(sc
->sc_cid
, CRYPTO_MD5
, 0, 0,
414 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
415 crypto_register(sc
->sc_cid
, CRYPTO_SHA1
, 0, 0,
416 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
417 crypto_register(sc
->sc_cid
, CRYPTO_MD5_HMAC_96
, 0, 0,
418 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
419 crypto_register(sc
->sc_cid
, CRYPTO_SHA1_HMAC_96
, 0, 0,
420 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
421 crypto_register(sc
->sc_cid
, CRYPTO_DES_CBC
, 0, 0,
422 hifn_newsession
, hifn_freesession
, hifn_process
, sc
);
426 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
, 0,
427 sc
->sc_dmamap
->dm_mapsize
,
428 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
430 if (sc
->sc_flags
& (HIFN_HAS_PUBLIC
| HIFN_HAS_RNG
))
431 hifn_init_pubrng(sc
);
434 timeout_set(&sc
->sc_tickto
, hifn_tick
, sc
);
435 timeout_add(&sc
->sc_tickto
, hz
);
437 callout_init(&sc
->sc_tickto
, 0);
438 callout_reset(&sc
->sc_tickto
, hz
, hifn_tick
, sc
);
443 pci_intr_disestablish(pc
, sc
->sc_ih
);
445 bus_dmamap_unload(sc
->sc_dmat
, dmamap
);
446 bus_dmamap_destroy(sc
->sc_dmat
, dmamap
);
447 bus_dmamem_unmap(sc
->sc_dmat
, kva
, sizeof(*sc
->sc_dma
));
448 bus_dmamem_free(sc
->sc_dmat
, &seg
, rseg
);
450 /* Turn off DMA polling */
451 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
452 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
455 bus_space_unmap(sc
->sc_st1
, sc
->sc_sh1
, iosize1
);
457 bus_space_unmap(sc
->sc_st0
, sc
->sc_sh0
, iosize0
);
461 hifn_init_pubrng(struct hifn_softc
*sc
)
466 if ((sc
->sc_flags
& HIFN_IS_7811
) == 0) {
467 /* Reset 7951 public key/rng engine */
468 WRITE_REG_1(sc
, HIFN_1_PUB_RESET
,
469 READ_REG_1(sc
, HIFN_1_PUB_RESET
) | HIFN_PUBRST_RESET
);
471 for (i
= 0; i
< 100; i
++) {
473 if ((READ_REG_1(sc
, HIFN_1_PUB_RESET
) &
474 HIFN_PUBRST_RESET
) == 0)
479 printf("%s: public key init failed\n",
480 device_xname(&sc
->sc_dv
));
485 /* Enable the rng, if available */
486 if (sc
->sc_flags
& HIFN_HAS_RNG
) {
487 if (sc
->sc_flags
& HIFN_IS_7811
) {
488 r
= READ_REG_1(sc
, HIFN_1_7811_RNGENA
);
489 if (r
& HIFN_7811_RNGENA_ENA
) {
490 r
&= ~HIFN_7811_RNGENA_ENA
;
491 WRITE_REG_1(sc
, HIFN_1_7811_RNGENA
, r
);
493 WRITE_REG_1(sc
, HIFN_1_7811_RNGCFG
,
494 HIFN_7811_RNGCFG_DEFL
);
495 r
|= HIFN_7811_RNGENA_ENA
;
496 WRITE_REG_1(sc
, HIFN_1_7811_RNGENA
, r
);
498 WRITE_REG_1(sc
, HIFN_1_RNG_CONFIG
,
499 READ_REG_1(sc
, HIFN_1_RNG_CONFIG
) |
503 * The Hifn RNG documentation states that at their
504 * recommended "conservative" RNG config values,
505 * the RNG must warm up for 0.4s before providing
506 * data that meet their worst-case estimate of 0.06
507 * bits of random data per output register bit.
513 * XXX Careful! The use of RND_FLAG_NO_ESTIMATE
514 * XXX here is unobvious: we later feed raw bits
515 * XXX into the "entropy pool" with rnd_add_data,
516 * XXX explicitly supplying an entropy estimate.
517 * XXX In this context, NO_ESTIMATE serves only
518 * XXX to prevent rnd_add_data from trying to
519 * XXX use the *time at which we added the data*
520 * XXX as entropy, which is not a good idea since
521 * XXX we add data periodically from a callout.
523 rnd_attach_source(&sc
->sc_rnd_source
, device_xname(&sc
->sc_dv
),
524 RND_TYPE_RNG
, RND_FLAG_NO_ESTIMATE
);
529 sc
->sc_rnghz
= hz
/ 100;
533 timeout_set(&sc
->sc_rngto
, hifn_rng
, sc
);
534 #else /* !__OpenBSD__ */
535 callout_init(&sc
->sc_rngto
, 0);
536 #endif /* !__OpenBSD__ */
539 /* Enable public key engine, if available */
540 if (sc
->sc_flags
& HIFN_HAS_PUBLIC
) {
541 WRITE_REG_1(sc
, HIFN_1_PUB_IEN
, HIFN_PUBIEN_DONE
);
542 sc
->sc_dmaier
|= HIFN_DMAIER_PUBDONE
;
543 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
546 /* Call directly into the RNG once to prime the pool. */
547 hifn_rng(sc
); /* Sets callout/timeout at end */
555 struct hifn_softc
*sc
= vsc
;
557 u_int32_t num
[HIFN_RNG_BITSPER
* RND_ENTROPY_THRESHOLD
];
564 if (sc
->sc_flags
& HIFN_IS_7811
) {
565 for (i
= 0; i
< 5; i
++) { /* XXX why 5? */
566 sts
= READ_REG_1(sc
, HIFN_1_7811_RNGSTS
);
567 if (sts
& HIFN_7811_RNGSTS_UFL
) {
568 printf("%s: RNG underflow: disabling\n",
569 device_xname(&sc
->sc_dv
));
572 if ((sts
& HIFN_7811_RNGSTS_RDY
) == 0)
576 * There are at least two words in the RNG FIFO
579 num
[0] = READ_REG_1(sc
, HIFN_1_7811_RNGDAT
);
580 num
[1] = READ_REG_1(sc
, HIFN_1_7811_RNGDAT
);
585 rnd_add_data(&sc
->sc_rnd_source
, num
,
587 (2 * sizeof(num
[0]) * NBBY
) /
591 * XXX This is a really bad idea.
592 * XXX Hifn estimate as little as 0.06
593 * XXX actual bits of entropy per output
594 * XXX register bit. How can we tell the
595 * XXX kernel RNG subsystem we're handing
596 * XXX it 64 "true" random bits, for any
597 * XXX sane value of "true"?
599 * XXX The right thing to do here, if we
600 * XXX cannot supply an estimate ourselves,
601 * XXX would be to hash the bits locally.
603 add_true_randomness(num
[0]);
604 add_true_randomness(num
[1]);
610 /* First time through, try to help fill the pool. */
611 int nwords
= sc
->sc_rngfirst
?
612 sizeof(num
) / sizeof(num
[0]) : 4;
617 * We must be *extremely* careful here. The Hifn
618 * 795x differ from the published 6500 RNG design
619 * in more ways than the obvious lack of the output
620 * FIFO and LFSR control registers. In fact, there
621 * is only one LFSR, instead of the 6500's two, and
622 * it's 32 bits, not 31.
624 * Further, a block diagram obtained from Hifn shows
625 * a very curious latching of this register: the LFSR
626 * rotates at a frequency of RNG_Clk / 8, but the
627 * RNG_Data register is latched at a frequency of
628 * RNG_Clk, which means that it is possible for
629 * consecutive reads of the RNG_Data register to read
630 * identical state from the LFSR. The simplest
631 * workaround seems to be to read eight samples from
632 * the register for each one that we use. Since each
633 * read must require at least one PCI cycle, and
634 * RNG_Clk is at least PCI_Clk, this is safe.
638 if (sc
->sc_rngfirst
) {
643 for(i
= 0 ; i
< nwords
* 8; i
++)
645 volatile u_int32_t regtmp
;
646 regtmp
= READ_REG_1(sc
, HIFN_1_RNG_DATA
);
650 rnd_add_data(&sc
->sc_rnd_source
, num
,
651 nwords
* sizeof(num
[0]),
652 (nwords
* sizeof(num
[0]) * NBBY
) /
655 /* XXX a bad idea; see 7811 block above */
656 add_true_randomness(num
[0]);
661 timeout_add(&sc
->sc_rngto
, sc
->sc_rnghz
);
663 callout_reset(&sc
->sc_rngto
, sc
->sc_rnghz
, hifn_rng
, sc
);
668 hifn_puc_wait(struct hifn_softc
*sc
)
672 for (i
= 5000; i
> 0; i
--) {
674 if (!(READ_REG_0(sc
, HIFN_0_PUCTRL
) & HIFN_PUCTRL_RESET
))
678 printf("%s: proc unit did not reset\n", device_xname(&sc
->sc_dv
));
682 * Reset the processing unit.
685 hifn_reset_puc(struct hifn_softc
*sc
)
687 /* Reset processing unit */
688 WRITE_REG_0(sc
, HIFN_0_PUCTRL
, HIFN_PUCTRL_DMAENA
);
693 hifn_set_retry(struct hifn_softc
*sc
)
697 r
= pci_conf_read(sc
->sc_pci_pc
, sc
->sc_pci_tag
, HIFN_TRDY_TIMEOUT
);
699 pci_conf_write(sc
->sc_pci_pc
, sc
->sc_pci_tag
, HIFN_TRDY_TIMEOUT
, r
);
703 * Resets the board. Values in the regesters are left as is
704 * from the reset (i.e. initial values are assigned elsewhere).
707 hifn_reset_board(struct hifn_softc
*sc
, int full
)
712 * Set polling in the DMA configuration register to zero. 0x7 avoids
713 * resetting the board and zeros out the other fields.
715 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
716 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
719 * Now that polling has been disabled, we have to wait 1 ms
720 * before resetting the board.
724 /* Reset the DMA unit */
726 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MODE
);
729 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
,
730 HIFN_DMACNFG_MODE
| HIFN_DMACNFG_MSTRESET
);
734 memset(sc
->sc_dma
, 0, sizeof(*sc
->sc_dma
));
736 /* Bring dma unit out of reset */
737 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
738 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
744 if (sc
->sc_flags
& HIFN_IS_7811
) {
745 for (reg
= 0; reg
< 1000; reg
++) {
746 if (READ_REG_1(sc
, HIFN_1_7811_MIPSRST
) &
747 HIFN_MIPSRST_CRAMINIT
)
752 printf(": cram init timeout\n");
757 hifn_next_signature(u_int32_t a
, u_int cnt
)
762 for (i
= 0; i
< cnt
; i
++) {
772 a
= (v
& 1) ^ (a
<< 1);
778 static struct pci2id
{
785 PCI_PRODUCT_HIFN_7951
,
786 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787 0x00, 0x00, 0x00, 0x00, 0x00 }
790 PCI_PRODUCT_HIFN_7955
,
791 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x00, 0x00, 0x00 }
795 PCI_PRODUCT_HIFN_7956
,
796 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797 0x00, 0x00, 0x00, 0x00, 0x00 }
800 PCI_PRODUCT_NETSEC_7751
,
801 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802 0x00, 0x00, 0x00, 0x00, 0x00 }
805 PCI_PRODUCT_INVERTEX_AEON
,
806 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00 }
810 PCI_PRODUCT_HIFN_7811
,
811 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0x00, 0x00, 0x00 }
815 * Other vendors share this PCI ID as well, such as
816 * http://www.powercrypt.com, and obviously they also
820 PCI_PRODUCT_HIFN_7751
,
821 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
822 0x00, 0x00, 0x00, 0x00, 0x00 }
827 * Checks to see if crypto is already enabled. If crypto isn't enable,
828 * "hifn_enable_crypto" is called to enable it. The check is important,
829 * as enabling crypto twice will lock the board.
832 hifn_enable_crypto(struct hifn_softc
*sc
, pcireg_t pciid
)
834 u_int32_t dmacfg
, ramcfg
, encl
, addr
, i
;
835 const char *offtbl
= NULL
;
837 for (i
= 0; i
< sizeof(pci2id
)/sizeof(pci2id
[0]); i
++) {
838 if (pci2id
[i
].pci_vendor
== PCI_VENDOR(pciid
) &&
839 pci2id
[i
].pci_prod
== PCI_PRODUCT(pciid
)) {
840 offtbl
= pci2id
[i
].card_id
;
845 if (offtbl
== NULL
) {
847 aprint_debug_dev(&sc
->sc_dv
, "Unknown card!\n");
852 ramcfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
);
853 dmacfg
= READ_REG_1(sc
, HIFN_1_DMA_CNFG
);
856 * The RAM config register's encrypt level bit needs to be set before
857 * every read performed on the encryption level register.
859 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
| HIFN_PUCNFG_CHIPID
);
861 encl
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
864 * Make sure we don't re-unlock. Two unlocks kills chip until the
867 if (encl
== HIFN_PUSTAT_ENA_1
|| encl
== HIFN_PUSTAT_ENA_2
) {
869 aprint_debug_dev(&sc
->sc_dv
, "Strong Crypto already enabled!\n");
874 if (encl
!= 0 && encl
!= HIFN_PUSTAT_ENA_0
) {
876 aprint_debug_dev(&sc
->sc_dv
, "Unknown encryption level\n");
881 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_UNLOCK
|
882 HIFN_DMACNFG_MSTRESET
| HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
);
884 addr
= READ_REG_1(sc
, HIFN_1_UNLOCK_SECRET1
);
886 WRITE_REG_1(sc
, HIFN_1_UNLOCK_SECRET2
, 0);
889 for (i
= 0; i
<= 12; i
++) {
890 addr
= hifn_next_signature(addr
, offtbl
[i
] + 0x101);
891 WRITE_REG_1(sc
, HIFN_1_UNLOCK_SECRET2
, addr
);
896 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
| HIFN_PUCNFG_CHIPID
);
897 encl
= READ_REG_0(sc
, HIFN_0_PUSTAT
) & HIFN_PUSTAT_CHIPENA
;
900 if (encl
!= HIFN_PUSTAT_ENA_1
&& encl
!= HIFN_PUSTAT_ENA_2
)
901 aprint_debug("Encryption engine is permanently locked until next system reset.");
903 aprint_debug("Encryption engine enabled successfully!");
907 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, ramcfg
);
908 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, dmacfg
);
911 case HIFN_PUSTAT_ENA_0
:
912 return ("LZS-only (no encr/auth)");
914 case HIFN_PUSTAT_ENA_1
:
917 case HIFN_PUSTAT_ENA_2
:
918 if (sc
->sc_flags
& HIFN_HAS_AES
)
930 * Give initial values to the registers listed in the "Register Space"
931 * section of the HIFN Software Development reference manual.
934 hifn_init_pci_registers(struct hifn_softc
*sc
)
936 /* write fixed values needed by the Initialization registers */
937 WRITE_REG_0(sc
, HIFN_0_PUCTRL
, HIFN_PUCTRL_DMAENA
);
938 WRITE_REG_0(sc
, HIFN_0_FIFOCNFG
, HIFN_FIFOCNFG_THRESHOLD
);
939 WRITE_REG_0(sc
, HIFN_0_PUIER
, HIFN_PUIER_DSTOVER
);
941 /* write all 4 ring address registers */
942 WRITE_REG_1(sc
, HIFN_1_DMA_CRAR
, sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
943 offsetof(struct hifn_dma
, cmdr
[0]));
944 WRITE_REG_1(sc
, HIFN_1_DMA_SRAR
, sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
945 offsetof(struct hifn_dma
, srcr
[0]));
946 WRITE_REG_1(sc
, HIFN_1_DMA_DRAR
, sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
947 offsetof(struct hifn_dma
, dstr
[0]));
948 WRITE_REG_1(sc
, HIFN_1_DMA_RRAR
, sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
949 offsetof(struct hifn_dma
, resr
[0]));
953 /* write status register */
954 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
955 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
|
956 HIFN_DMACSR_S_CTRL_DIS
| HIFN_DMACSR_C_CTRL_DIS
|
957 HIFN_DMACSR_D_ABORT
| HIFN_DMACSR_D_DONE
| HIFN_DMACSR_D_LAST
|
958 HIFN_DMACSR_D_WAIT
| HIFN_DMACSR_D_OVER
|
959 HIFN_DMACSR_R_ABORT
| HIFN_DMACSR_R_DONE
| HIFN_DMACSR_R_LAST
|
960 HIFN_DMACSR_R_WAIT
| HIFN_DMACSR_R_OVER
|
961 HIFN_DMACSR_S_ABORT
| HIFN_DMACSR_S_DONE
| HIFN_DMACSR_S_LAST
|
963 HIFN_DMACSR_C_ABORT
| HIFN_DMACSR_C_DONE
| HIFN_DMACSR_C_LAST
|
966 ((sc
->sc_flags
& HIFN_HAS_PUBLIC
) ?
967 HIFN_DMACSR_PUBDONE
: 0) |
968 ((sc
->sc_flags
& HIFN_IS_7811
) ?
969 HIFN_DMACSR_ILLW
| HIFN_DMACSR_ILLR
: 0));
971 sc
->sc_d_busy
= sc
->sc_r_busy
= sc
->sc_s_busy
= sc
->sc_c_busy
= 0;
972 sc
->sc_dmaier
|= HIFN_DMAIER_R_DONE
| HIFN_DMAIER_C_ABORT
|
973 HIFN_DMAIER_D_OVER
| HIFN_DMAIER_R_OVER
|
974 HIFN_DMAIER_S_ABORT
| HIFN_DMAIER_D_ABORT
| HIFN_DMAIER_R_ABORT
|
976 ((sc
->sc_flags
& HIFN_IS_7811
) ?
977 HIFN_DMAIER_ILLW
| HIFN_DMAIER_ILLR
: 0);
978 sc
->sc_dmaier
&= ~HIFN_DMAIER_C_WAIT
;
979 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
980 CLR_LED(sc
, HIFN_MIPSRST_LED0
| HIFN_MIPSRST_LED1
| HIFN_MIPSRST_LED2
);
982 if (sc
->sc_flags
& HIFN_IS_7956
) {
983 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, HIFN_PUCNFG_COMPSING
|
984 HIFN_PUCNFG_TCALLPHASES
|
985 HIFN_PUCNFG_TCDRVTOTEM
| HIFN_PUCNFG_BUS32
);
986 WRITE_REG_1(sc
, HIFN_1_PLL
, HIFN_PLL_7956
);
988 WRITE_REG_0(sc
, HIFN_0_PUCNFG
, HIFN_PUCNFG_COMPSING
|
989 HIFN_PUCNFG_DRFR_128
| HIFN_PUCNFG_TCALLPHASES
|
990 HIFN_PUCNFG_TCDRVTOTEM
| HIFN_PUCNFG_BUS32
|
991 (sc
->sc_drammodel
? HIFN_PUCNFG_DRAM
: HIFN_PUCNFG_SRAM
));
994 WRITE_REG_0(sc
, HIFN_0_PUISR
, HIFN_PUISR_DSTOVER
);
995 WRITE_REG_1(sc
, HIFN_1_DMA_CNFG
, HIFN_DMACNFG_MSTRESET
|
996 HIFN_DMACNFG_DMARESET
| HIFN_DMACNFG_MODE
| HIFN_DMACNFG_LAST
|
997 ((HIFN_POLL_FREQUENCY
<< 16 ) & HIFN_DMACNFG_POLLFREQ
) |
998 ((HIFN_POLL_SCALAR
<< 8) & HIFN_DMACNFG_POLLINVAL
));
1002 * The maximum number of sessions supported by the card
1003 * is dependent on the amount of context ram, which
1004 * encryption algorithms are enabled, and how compression
1005 * is configured. This should be configured before this
1006 * routine is called.
1009 hifn_sessions(struct hifn_softc
*sc
)
1014 pucnfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
);
1016 if (pucnfg
& HIFN_PUCNFG_COMPSING
) {
1017 if (pucnfg
& HIFN_PUCNFG_ENCCNFG
)
1022 * 7955/7956 has internal context memory of 32K
1024 if (sc
->sc_flags
& HIFN_IS_7956
)
1025 sc
->sc_maxses
= 32768 / ctxsize
;
1028 ((sc
->sc_ramsize
- 32768) / ctxsize
);
1031 sc
->sc_maxses
= sc
->sc_ramsize
/ 16384;
1033 if (sc
->sc_maxses
> 2048)
1034 sc
->sc_maxses
= 2048;
1038 * Determine ram type (sram or dram). Board should be just out of a reset
1039 * state when this is called.
1042 hifn_ramtype(struct hifn_softc
*sc
)
1044 u_int8_t data
[8], dataexpect
[8];
1047 for (i
= 0; i
< sizeof(data
); i
++)
1048 data
[i
] = dataexpect
[i
] = 0x55;
1049 if (hifn_writeramaddr(sc
, 0, data
))
1051 if (hifn_readramaddr(sc
, 0, data
))
1053 if (memcmp(data
, dataexpect
, sizeof(data
)) != 0) {
1054 sc
->sc_drammodel
= 1;
1058 for (i
= 0; i
< sizeof(data
); i
++)
1059 data
[i
] = dataexpect
[i
] = 0xaa;
1060 if (hifn_writeramaddr(sc
, 0, data
))
1062 if (hifn_readramaddr(sc
, 0, data
))
1064 if (memcmp(data
, dataexpect
, sizeof(data
)) != 0) {
1065 sc
->sc_drammodel
= 1;
1072 #define HIFN_SRAM_MAX (32 << 20)
1073 #define HIFN_SRAM_STEP_SIZE 16384
1074 #define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
1077 hifn_sramsize(struct hifn_softc
*sc
)
1081 u_int8_t dataexpect
[sizeof(data
)];
1084 for (i
= 0; i
< sizeof(data
); i
++)
1085 data
[i
] = dataexpect
[i
] = i
^ 0x5a;
1087 for (i
= HIFN_SRAM_GRANULARITY
- 1; i
>= 0; i
--) {
1088 a
= i
* HIFN_SRAM_STEP_SIZE
;
1089 memcpy(data
, &i
, sizeof(i
));
1090 hifn_writeramaddr(sc
, a
, data
);
1093 for (i
= 0; i
< HIFN_SRAM_GRANULARITY
; i
++) {
1094 a
= i
* HIFN_SRAM_STEP_SIZE
;
1095 memcpy(dataexpect
, &i
, sizeof(i
));
1096 if (hifn_readramaddr(sc
, a
, data
) < 0)
1098 if (memcmp(data
, dataexpect
, sizeof(data
)) != 0)
1100 sc
->sc_ramsize
= a
+ HIFN_SRAM_STEP_SIZE
;
1107 * XXX For dram boards, one should really try all of the
1108 * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
1109 * is already set up correctly.
1112 hifn_dramsize(struct hifn_softc
*sc
)
1116 if (sc
->sc_flags
& HIFN_IS_7956
) {
1118 * 7955/7956 have a fixed internal ram of only 32K.
1120 sc
->sc_ramsize
= 32768;
1122 cnfg
= READ_REG_0(sc
, HIFN_0_PUCNFG
) &
1123 HIFN_PUCNFG_DRAMMASK
;
1124 sc
->sc_ramsize
= 1 << ((cnfg
>> 13) + 18);
1130 hifn_alloc_slot(struct hifn_softc
*sc
, int *cmdp
, int *srcp
, int *dstp
,
1133 struct hifn_dma
*dma
= sc
->sc_dma
;
1135 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
1137 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_VALID
|
1138 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1139 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
1140 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1142 *cmdp
= dma
->cmdi
++;
1143 dma
->cmdk
= dma
->cmdi
;
1145 if (dma
->srci
== HIFN_D_SRC_RSIZE
) {
1147 dma
->srcr
[HIFN_D_SRC_RSIZE
].l
= htole32(HIFN_D_VALID
|
1148 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1149 HIFN_SRCR_SYNC(sc
, HIFN_D_SRC_RSIZE
,
1150 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1152 *srcp
= dma
->srci
++;
1153 dma
->srck
= dma
->srci
;
1155 if (dma
->dsti
== HIFN_D_DST_RSIZE
) {
1157 dma
->dstr
[HIFN_D_DST_RSIZE
].l
= htole32(HIFN_D_VALID
|
1158 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1159 HIFN_DSTR_SYNC(sc
, HIFN_D_DST_RSIZE
,
1160 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1162 *dstp
= dma
->dsti
++;
1163 dma
->dstk
= dma
->dsti
;
1165 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
1167 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_VALID
|
1168 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1169 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
1170 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1172 *resp
= dma
->resi
++;
1173 dma
->resk
= dma
->resi
;
1177 hifn_writeramaddr(struct hifn_softc
*sc
, int addr
, u_int8_t
*data
)
1179 struct hifn_dma
*dma
= sc
->sc_dma
;
1180 struct hifn_base_command wc
;
1181 const u_int32_t masks
= HIFN_D_VALID
| HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
;
1182 int r
, cmdi
, resi
, srci
, dsti
;
1184 wc
.masks
= htole16(3 << 13);
1185 wc
.session_num
= htole16(addr
>> 14);
1186 wc
.total_source_count
= htole16(8);
1187 wc
.total_dest_count
= htole16(addr
& 0x3fff);
1189 hifn_alloc_slot(sc
, &cmdi
, &srci
, &dsti
, &resi
);
1191 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1192 HIFN_DMACSR_C_CTRL_ENA
| HIFN_DMACSR_S_CTRL_ENA
|
1193 HIFN_DMACSR_D_CTRL_ENA
| HIFN_DMACSR_R_CTRL_ENA
);
1195 /* build write command */
1196 memset(dma
->command_bufs
[cmdi
], 0, HIFN_MAX_COMMAND
);
1197 *(struct hifn_base_command
*)dma
->command_bufs
[cmdi
] = wc
;
1198 memcpy(&dma
->test_src
, data
, sizeof(dma
->test_src
));
1200 dma
->srcr
[srci
].p
= htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
1201 + offsetof(struct hifn_dma
, test_src
));
1202 dma
->dstr
[dsti
].p
= htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
1203 + offsetof(struct hifn_dma
, test_dst
));
1205 dma
->cmdr
[cmdi
].l
= htole32(16 | masks
);
1206 dma
->srcr
[srci
].l
= htole32(8 | masks
);
1207 dma
->dstr
[dsti
].l
= htole32(4 | masks
);
1208 dma
->resr
[resi
].l
= htole32(4 | masks
);
1210 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1211 0, sc
->sc_dmamap
->dm_mapsize
,
1212 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1214 for (r
= 10000; r
>= 0; r
--) {
1216 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1217 0, sc
->sc_dmamap
->dm_mapsize
,
1218 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
1219 if ((dma
->resr
[resi
].l
& htole32(HIFN_D_VALID
)) == 0)
1221 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1222 0, sc
->sc_dmamap
->dm_mapsize
,
1223 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1226 printf("%s: writeramaddr -- "
1227 "result[%d](addr %d) still valid\n",
1228 device_xname(&sc
->sc_dv
), resi
, addr
);
1234 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1235 HIFN_DMACSR_C_CTRL_DIS
| HIFN_DMACSR_S_CTRL_DIS
|
1236 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
);
1242 hifn_readramaddr(struct hifn_softc
*sc
, int addr
, u_int8_t
*data
)
1244 struct hifn_dma
*dma
= sc
->sc_dma
;
1245 struct hifn_base_command rc
;
1246 const u_int32_t masks
= HIFN_D_VALID
| HIFN_D_LAST
| HIFN_D_MASKDONEIRQ
;
1247 int r
, cmdi
, srci
, dsti
, resi
;
1249 rc
.masks
= htole16(2 << 13);
1250 rc
.session_num
= htole16(addr
>> 14);
1251 rc
.total_source_count
= htole16(addr
& 0x3fff);
1252 rc
.total_dest_count
= htole16(8);
1254 hifn_alloc_slot(sc
, &cmdi
, &srci
, &dsti
, &resi
);
1256 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1257 HIFN_DMACSR_C_CTRL_ENA
| HIFN_DMACSR_S_CTRL_ENA
|
1258 HIFN_DMACSR_D_CTRL_ENA
| HIFN_DMACSR_R_CTRL_ENA
);
1260 memset(dma
->command_bufs
[cmdi
], 0, HIFN_MAX_COMMAND
);
1261 *(struct hifn_base_command
*)dma
->command_bufs
[cmdi
] = rc
;
1263 dma
->srcr
[srci
].p
= htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1264 offsetof(struct hifn_dma
, test_src
));
1266 dma
->dstr
[dsti
].p
= htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1267 offsetof(struct hifn_dma
, test_dst
));
1269 dma
->cmdr
[cmdi
].l
= htole32(8 | masks
);
1270 dma
->srcr
[srci
].l
= htole32(8 | masks
);
1271 dma
->dstr
[dsti
].l
= htole32(8 | masks
);
1272 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
| masks
);
1274 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1275 0, sc
->sc_dmamap
->dm_mapsize
,
1276 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1278 for (r
= 10000; r
>= 0; r
--) {
1280 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1281 0, sc
->sc_dmamap
->dm_mapsize
,
1282 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
1283 if ((dma
->resr
[resi
].l
& htole32(HIFN_D_VALID
)) == 0)
1285 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
1286 0, sc
->sc_dmamap
->dm_mapsize
,
1287 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1290 printf("%s: readramaddr -- "
1291 "result[%d](addr %d) still valid\n",
1292 device_xname(&sc
->sc_dv
), resi
, addr
);
1296 memcpy(data
, &dma
->test_dst
, sizeof(dma
->test_dst
));
1299 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
,
1300 HIFN_DMACSR_C_CTRL_DIS
| HIFN_DMACSR_S_CTRL_DIS
|
1301 HIFN_DMACSR_D_CTRL_DIS
| HIFN_DMACSR_R_CTRL_DIS
);
1307 * Initialize the descriptor rings.
1310 hifn_init_dma(struct hifn_softc
*sc
)
1312 struct hifn_dma
*dma
= sc
->sc_dma
;
1317 /* initialize static pointer values */
1318 for (i
= 0; i
< HIFN_D_CMD_RSIZE
; i
++)
1319 dma
->cmdr
[i
].p
= htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1320 offsetof(struct hifn_dma
, command_bufs
[i
][0]));
1321 for (i
= 0; i
< HIFN_D_RES_RSIZE
; i
++)
1322 dma
->resr
[i
].p
= htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1323 offsetof(struct hifn_dma
, result_bufs
[i
][0]));
1325 dma
->cmdr
[HIFN_D_CMD_RSIZE
].p
=
1326 htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1327 offsetof(struct hifn_dma
, cmdr
[0]));
1328 dma
->srcr
[HIFN_D_SRC_RSIZE
].p
=
1329 htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1330 offsetof(struct hifn_dma
, srcr
[0]));
1331 dma
->dstr
[HIFN_D_DST_RSIZE
].p
=
1332 htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1333 offsetof(struct hifn_dma
, dstr
[0]));
1334 dma
->resr
[HIFN_D_RES_RSIZE
].p
=
1335 htole32(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1336 offsetof(struct hifn_dma
, resr
[0]));
1338 dma
->cmdu
= dma
->srcu
= dma
->dstu
= dma
->resu
= 0;
1339 dma
->cmdi
= dma
->srci
= dma
->dsti
= dma
->resi
= 0;
1340 dma
->cmdk
= dma
->srck
= dma
->dstk
= dma
->resk
= 0;
1344 * Writes out the raw command buffer space. Returns the
1345 * command buffer size.
1348 hifn_write_command(struct hifn_command
*cmd
, u_int8_t
*buf
)
1351 struct hifn_base_command
*base_cmd
;
1352 struct hifn_mac_command
*mac_cmd
;
1353 struct hifn_crypt_command
*cry_cmd
;
1354 struct hifn_comp_command
*comp_cmd
;
1355 int using_mac
, using_crypt
, using_comp
, len
, ivlen
;
1356 u_int32_t dlen
, slen
;
1359 using_mac
= cmd
->base_masks
& HIFN_BASE_CMD_MAC
;
1360 using_crypt
= cmd
->base_masks
& HIFN_BASE_CMD_CRYPT
;
1361 using_comp
= cmd
->base_masks
& HIFN_BASE_CMD_COMP
;
1363 base_cmd
= (struct hifn_base_command
*)buf_pos
;
1364 base_cmd
->masks
= htole16(cmd
->base_masks
);
1365 slen
= cmd
->src_map
->dm_mapsize
;
1367 dlen
= cmd
->dst_map
->dm_mapsize
- cmd
->sloplen
+
1370 dlen
= cmd
->dst_map
->dm_mapsize
;
1371 base_cmd
->total_source_count
= htole16(slen
& HIFN_BASE_CMD_LENMASK_LO
);
1372 base_cmd
->total_dest_count
= htole16(dlen
& HIFN_BASE_CMD_LENMASK_LO
);
1375 base_cmd
->session_num
= htole16(cmd
->session_num
|
1376 ((slen
<< HIFN_BASE_CMD_SRCLEN_S
) & HIFN_BASE_CMD_SRCLEN_M
) |
1377 ((dlen
<< HIFN_BASE_CMD_DSTLEN_S
) & HIFN_BASE_CMD_DSTLEN_M
));
1378 buf_pos
+= sizeof(struct hifn_base_command
);
1381 comp_cmd
= (struct hifn_comp_command
*)buf_pos
;
1382 dlen
= cmd
->compcrd
->crd_len
;
1383 comp_cmd
->source_count
= htole16(dlen
& 0xffff);
1385 comp_cmd
->masks
= htole16(cmd
->comp_masks
|
1386 ((dlen
<< HIFN_COMP_CMD_SRCLEN_S
) & HIFN_COMP_CMD_SRCLEN_M
));
1387 comp_cmd
->header_skip
= htole16(cmd
->compcrd
->crd_skip
);
1388 comp_cmd
->reserved
= 0;
1389 buf_pos
+= sizeof(struct hifn_comp_command
);
1393 mac_cmd
= (struct hifn_mac_command
*)buf_pos
;
1394 dlen
= cmd
->maccrd
->crd_len
;
1395 mac_cmd
->source_count
= htole16(dlen
& 0xffff);
1397 mac_cmd
->masks
= htole16(cmd
->mac_masks
|
1398 ((dlen
<< HIFN_MAC_CMD_SRCLEN_S
) & HIFN_MAC_CMD_SRCLEN_M
));
1399 mac_cmd
->header_skip
= htole16(cmd
->maccrd
->crd_skip
);
1400 mac_cmd
->reserved
= 0;
1401 buf_pos
+= sizeof(struct hifn_mac_command
);
1405 cry_cmd
= (struct hifn_crypt_command
*)buf_pos
;
1406 dlen
= cmd
->enccrd
->crd_len
;
1407 cry_cmd
->source_count
= htole16(dlen
& 0xffff);
1409 cry_cmd
->masks
= htole16(cmd
->cry_masks
|
1410 ((dlen
<< HIFN_CRYPT_CMD_SRCLEN_S
) & HIFN_CRYPT_CMD_SRCLEN_M
));
1411 cry_cmd
->header_skip
= htole16(cmd
->enccrd
->crd_skip
);
1412 cry_cmd
->reserved
= 0;
1413 buf_pos
+= sizeof(struct hifn_crypt_command
);
1416 if (using_mac
&& cmd
->mac_masks
& HIFN_MAC_CMD_NEW_KEY
) {
1417 memcpy(buf_pos
, cmd
->mac
, HIFN_MAC_KEY_LENGTH
);
1418 buf_pos
+= HIFN_MAC_KEY_LENGTH
;
1421 if (using_crypt
&& cmd
->cry_masks
& HIFN_CRYPT_CMD_NEW_KEY
) {
1422 switch (cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) {
1423 case HIFN_CRYPT_CMD_ALG_3DES
:
1424 memcpy(buf_pos
, cmd
->ck
, HIFN_3DES_KEY_LENGTH
);
1425 buf_pos
+= HIFN_3DES_KEY_LENGTH
;
1427 case HIFN_CRYPT_CMD_ALG_DES
:
1428 memcpy(buf_pos
, cmd
->ck
, HIFN_DES_KEY_LENGTH
);
1429 buf_pos
+= HIFN_DES_KEY_LENGTH
;
1431 case HIFN_CRYPT_CMD_ALG_RC4
:
1436 clen
= MIN(cmd
->cklen
, len
);
1437 memcpy(buf_pos
, cmd
->ck
, clen
);
1441 memset(buf_pos
, 0, 4);
1444 case HIFN_CRYPT_CMD_ALG_AES
:
1446 * AES keys are variable 128, 192 and
1447 * 256 bits (16, 24 and 32 bytes).
1449 memcpy(buf_pos
, cmd
->ck
, cmd
->cklen
);
1450 buf_pos
+= cmd
->cklen
;
1455 if (using_crypt
&& cmd
->cry_masks
& HIFN_CRYPT_CMD_NEW_IV
) {
1456 switch (cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) {
1457 case HIFN_CRYPT_CMD_ALG_AES
:
1458 ivlen
= HIFN_AES_IV_LENGTH
;
1461 ivlen
= HIFN_IV_LENGTH
;
1464 memcpy(buf_pos
, cmd
->iv
, ivlen
);
1468 if ((cmd
->base_masks
& (HIFN_BASE_CMD_MAC
| HIFN_BASE_CMD_CRYPT
|
1469 HIFN_BASE_CMD_COMP
)) == 0) {
1470 memset(buf_pos
, 0, 8);
1474 return (buf_pos
- buf
);
1478 hifn_dmamap_aligned(bus_dmamap_t map
)
1482 for (i
= 0; i
< map
->dm_nsegs
; i
++) {
1483 if (map
->dm_segs
[i
].ds_addr
& 3)
1485 if ((i
!= (map
->dm_nsegs
- 1)) &&
1486 (map
->dm_segs
[i
].ds_len
& 3))
1493 hifn_dmamap_load_dst(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
1495 struct hifn_dma
*dma
= sc
->sc_dma
;
1496 bus_dmamap_t map
= cmd
->dst_map
;
1498 int idx
, used
= 0, i
;
1501 for (i
= 0; i
< map
->dm_nsegs
- 1; i
++) {
1502 dma
->dstr
[idx
].p
= htole32(map
->dm_segs
[i
].ds_addr
);
1503 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
|
1504 HIFN_D_MASKDONEIRQ
| map
->dm_segs
[i
].ds_len
);
1505 HIFN_DSTR_SYNC(sc
, idx
,
1506 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1509 if (++idx
== HIFN_D_DST_RSIZE
) {
1510 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
|
1511 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1512 HIFN_DSTR_SYNC(sc
, idx
,
1513 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1518 if (cmd
->sloplen
== 0) {
1519 p
= map
->dm_segs
[i
].ds_addr
;
1520 l
= HIFN_D_VALID
| HIFN_D_MASKDONEIRQ
| HIFN_D_LAST
|
1521 map
->dm_segs
[i
].ds_len
;
1523 p
= sc
->sc_dmamap
->dm_segs
[0].ds_addr
+
1524 offsetof(struct hifn_dma
, slop
[cmd
->slopidx
]);
1525 l
= HIFN_D_VALID
| HIFN_D_MASKDONEIRQ
| HIFN_D_LAST
|
1528 if ((map
->dm_segs
[i
].ds_len
- cmd
->sloplen
) != 0) {
1529 dma
->dstr
[idx
].p
= htole32(map
->dm_segs
[i
].ds_addr
);
1530 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
|
1531 HIFN_D_MASKDONEIRQ
|
1532 (map
->dm_segs
[i
].ds_len
- cmd
->sloplen
));
1533 HIFN_DSTR_SYNC(sc
, idx
,
1534 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1537 if (++idx
== HIFN_D_DST_RSIZE
) {
1538 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
|
1539 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1540 HIFN_DSTR_SYNC(sc
, idx
,
1541 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1546 dma
->dstr
[idx
].p
= htole32(p
);
1547 dma
->dstr
[idx
].l
= htole32(l
);
1548 HIFN_DSTR_SYNC(sc
, idx
, BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1551 if (++idx
== HIFN_D_DST_RSIZE
) {
1552 dma
->dstr
[idx
].l
= htole32(HIFN_D_VALID
| HIFN_D_JUMP
|
1553 HIFN_D_MASKDONEIRQ
);
1554 HIFN_DSTR_SYNC(sc
, idx
,
1555 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1565 hifn_dmamap_load_src(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
1567 struct hifn_dma
*dma
= sc
->sc_dma
;
1568 bus_dmamap_t map
= cmd
->src_map
;
1573 for (i
= 0; i
< map
->dm_nsegs
; i
++) {
1574 if (i
== map
->dm_nsegs
- 1)
1577 dma
->srcr
[idx
].p
= htole32(map
->dm_segs
[i
].ds_addr
);
1578 dma
->srcr
[idx
].l
= htole32(map
->dm_segs
[i
].ds_len
|
1579 HIFN_D_VALID
| HIFN_D_MASKDONEIRQ
| last
);
1580 HIFN_SRCR_SYNC(sc
, idx
,
1581 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1583 if (++idx
== HIFN_D_SRC_RSIZE
) {
1584 dma
->srcr
[idx
].l
= htole32(HIFN_D_VALID
|
1585 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1586 HIFN_SRCR_SYNC(sc
, HIFN_D_SRC_RSIZE
,
1587 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1592 dma
->srcu
+= map
->dm_nsegs
;
1597 hifn_crypto(struct hifn_softc
*sc
, struct hifn_command
*cmd
,
1598 struct cryptop
*crp
, int hint
)
1600 struct hifn_dma
*dma
= sc
->sc_dma
;
1602 int cmdi
, resi
, s
, err
= 0;
1604 if (bus_dmamap_create(sc
->sc_dmat
, HIFN_MAX_DMALEN
, MAX_SCATTER
,
1605 HIFN_MAX_SEGLEN
, 0, BUS_DMA_NOWAIT
, &cmd
->src_map
))
1608 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
1609 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, cmd
->src_map
,
1610 cmd
->srcu
.src_m
, BUS_DMA_NOWAIT
)) {
1614 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1615 if (bus_dmamap_load_uio(sc
->sc_dmat
, cmd
->src_map
,
1616 cmd
->srcu
.src_io
, BUS_DMA_NOWAIT
)) {
1625 if (hifn_dmamap_aligned(cmd
->src_map
)) {
1626 cmd
->sloplen
= cmd
->src_map
->dm_mapsize
& 3;
1627 if (crp
->crp_flags
& CRYPTO_F_IOV
)
1628 cmd
->dstu
.dst_io
= cmd
->srcu
.src_io
;
1629 else if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
1630 cmd
->dstu
.dst_m
= cmd
->srcu
.src_m
;
1631 cmd
->dst_map
= cmd
->src_map
;
1633 if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1636 } else if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
1638 struct mbuf
*m
, *m0
, *mlast
;
1640 totlen
= cmd
->src_map
->dm_mapsize
;
1641 if (cmd
->srcu
.src_m
->m_flags
& M_PKTHDR
) {
1643 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
1646 MGET(m0
, M_DONTWAIT
, MT_DATA
);
1653 M_DUP_PKTHDR(m0
, cmd
->srcu
.src_m
);
1654 if (totlen
>= MINCLSIZE
) {
1655 MCLGET(m0
, M_DONTWAIT
);
1656 if (m0
->m_flags
& M_EXT
)
1660 m0
->m_pkthdr
.len
= m0
->m_len
= len
;
1663 while (totlen
> 0) {
1664 MGET(m
, M_DONTWAIT
, MT_DATA
);
1671 if (totlen
>= MINCLSIZE
) {
1672 MCLGET(m
, M_DONTWAIT
);
1673 if (m
->m_flags
& M_EXT
)
1678 if (m0
->m_flags
& M_PKTHDR
)
1679 m0
->m_pkthdr
.len
+= len
;
1685 cmd
->dstu
.dst_m
= m0
;
1689 if (cmd
->dst_map
== NULL
) {
1690 if (bus_dmamap_create(sc
->sc_dmat
,
1691 HIFN_MAX_SEGLEN
* MAX_SCATTER
, MAX_SCATTER
,
1692 HIFN_MAX_SEGLEN
, 0, BUS_DMA_NOWAIT
, &cmd
->dst_map
)) {
1696 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
1697 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, cmd
->dst_map
,
1698 cmd
->dstu
.dst_m
, BUS_DMA_NOWAIT
)) {
1702 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1703 if (bus_dmamap_load_uio(sc
->sc_dmat
, cmd
->dst_map
,
1704 cmd
->dstu
.dst_io
, BUS_DMA_NOWAIT
)) {
1713 printf("%s: Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
1714 device_xname(&sc
->sc_dv
),
1715 READ_REG_1(sc
, HIFN_1_DMA_CSR
),
1716 READ_REG_1(sc
, HIFN_1_DMA_IER
),
1717 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
,
1718 cmd
->src_map
->dm_nsegs
, cmd
->dst_map
->dm_nsegs
);
1721 if (cmd
->src_map
== cmd
->dst_map
)
1722 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
1723 0, cmd
->src_map
->dm_mapsize
,
1724 BUS_DMASYNC_PREWRITE
|BUS_DMASYNC_PREREAD
);
1726 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
1727 0, cmd
->src_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
1728 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
1729 0, cmd
->dst_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
1735 * need 1 cmd, and 1 res
1736 * need N src, and N dst
1738 if ((dma
->cmdu
+ 1) > HIFN_D_CMD_RSIZE
||
1739 (dma
->resu
+ 1) > HIFN_D_RES_RSIZE
) {
1744 if ((dma
->srcu
+ cmd
->src_map
->dm_nsegs
) > HIFN_D_SRC_RSIZE
||
1745 (dma
->dstu
+ cmd
->dst_map
->dm_nsegs
+ 1) > HIFN_D_DST_RSIZE
) {
1751 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
1753 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_VALID
|
1754 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1755 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
1756 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1759 cmdlen
= hifn_write_command(cmd
, dma
->command_bufs
[cmdi
]);
1760 HIFN_CMD_SYNC(sc
, cmdi
, BUS_DMASYNC_PREWRITE
);
1762 /* .p for command/result already set */
1763 dma
->cmdr
[cmdi
].l
= htole32(cmdlen
| HIFN_D_VALID
| HIFN_D_LAST
|
1764 HIFN_D_MASKDONEIRQ
);
1765 HIFN_CMDR_SYNC(sc
, cmdi
,
1766 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1768 if (sc
->sc_c_busy
== 0) {
1769 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_C_CTRL_ENA
);
1771 SET_LED(sc
, HIFN_MIPSRST_LED0
);
1775 * We don't worry about missing an interrupt (which a "command wait"
1776 * interrupt salvages us from), unless there is more than one command
1779 * XXX We do seem to miss some interrupts. So we always enable
1780 * XXX command wait. From OpenBSD revision 1.149.
1784 if (dma
->cmdu
> 1) {
1786 sc
->sc_dmaier
|= HIFN_DMAIER_C_WAIT
;
1787 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
1792 hifnstats
.hst_ipackets
++;
1793 hifnstats
.hst_ibytes
+= cmd
->src_map
->dm_mapsize
;
1795 hifn_dmamap_load_src(sc
, cmd
);
1796 if (sc
->sc_s_busy
== 0) {
1797 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_S_CTRL_ENA
);
1799 SET_LED(sc
, HIFN_MIPSRST_LED1
);
1803 * Unlike other descriptors, we don't mask done interrupt from
1804 * result descriptor.
1808 printf("load res\n");
1810 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
1812 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_VALID
|
1813 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
1814 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
1815 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1818 dma
->hifn_commands
[resi
] = cmd
;
1819 HIFN_RES_SYNC(sc
, resi
, BUS_DMASYNC_PREREAD
);
1820 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
|
1821 HIFN_D_VALID
| HIFN_D_LAST
);
1822 HIFN_RESR_SYNC(sc
, resi
,
1823 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1825 if (sc
->sc_r_busy
== 0) {
1826 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_R_CTRL_ENA
);
1828 SET_LED(sc
, HIFN_MIPSRST_LED2
);
1832 cmd
->slopidx
= resi
;
1834 hifn_dmamap_load_dst(sc
, cmd
);
1836 if (sc
->sc_d_busy
== 0) {
1837 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_D_CTRL_ENA
);
1843 printf("%s: command: stat %8x ier %8x\n",
1844 device_xname(&sc
->sc_dv
),
1845 READ_REG_1(sc
, HIFN_1_DMA_CSR
), READ_REG_1(sc
, HIFN_1_DMA_IER
));
1850 return (err
); /* success */
1853 if (cmd
->src_map
!= cmd
->dst_map
)
1854 bus_dmamap_unload(sc
->sc_dmat
, cmd
->dst_map
);
1856 if (cmd
->src_map
!= cmd
->dst_map
)
1857 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->dst_map
);
1859 if (crp
->crp_flags
& CRYPTO_F_IMBUF
&&
1860 cmd
->srcu
.src_m
!= cmd
->dstu
.dst_m
)
1861 m_freem(cmd
->dstu
.dst_m
);
1862 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
1864 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->src_map
);
1869 hifn_tick(void *vsc
)
1871 struct hifn_softc
*sc
= vsc
;
1875 if (sc
->sc_active
== 0) {
1876 struct hifn_dma
*dma
= sc
->sc_dma
;
1879 if (dma
->cmdu
== 0 && sc
->sc_c_busy
) {
1881 r
|= HIFN_DMACSR_C_CTRL_DIS
;
1882 CLR_LED(sc
, HIFN_MIPSRST_LED0
);
1884 if (dma
->srcu
== 0 && sc
->sc_s_busy
) {
1886 r
|= HIFN_DMACSR_S_CTRL_DIS
;
1887 CLR_LED(sc
, HIFN_MIPSRST_LED1
);
1889 if (dma
->dstu
== 0 && sc
->sc_d_busy
) {
1891 r
|= HIFN_DMACSR_D_CTRL_DIS
;
1893 if (dma
->resu
== 0 && sc
->sc_r_busy
) {
1895 r
|= HIFN_DMACSR_R_CTRL_DIS
;
1896 CLR_LED(sc
, HIFN_MIPSRST_LED2
);
1899 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, r
);
1905 timeout_add(&sc
->sc_tickto
, hz
);
1907 callout_reset(&sc
->sc_tickto
, hz
, hifn_tick
, sc
);
1912 hifn_intr(void *arg
)
1914 struct hifn_softc
*sc
= arg
;
1915 struct hifn_dma
*dma
= sc
->sc_dma
;
1916 u_int32_t dmacsr
, restart
;
1919 dmacsr
= READ_REG_1(sc
, HIFN_1_DMA_CSR
);
1923 printf("%s: irq: stat %08x ien %08x u %d/%d/%d/%d\n",
1924 device_xname(&sc
->sc_dv
),
1925 dmacsr
, READ_REG_1(sc
, HIFN_1_DMA_IER
),
1926 dma
->cmdu
, dma
->srcu
, dma
->dstu
, dma
->resu
);
1929 /* Nothing in the DMA unit interrupted */
1930 if ((dmacsr
& sc
->sc_dmaier
) == 0)
1933 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, dmacsr
& sc
->sc_dmaier
);
1935 if (dmacsr
& HIFN_DMACSR_ENGINE
)
1936 WRITE_REG_0(sc
, HIFN_0_PUISR
, READ_REG_0(sc
, HIFN_0_PUISR
));
1938 if ((sc
->sc_flags
& HIFN_HAS_PUBLIC
) &&
1939 (dmacsr
& HIFN_DMACSR_PUBDONE
))
1940 WRITE_REG_1(sc
, HIFN_1_PUB_STATUS
,
1941 READ_REG_1(sc
, HIFN_1_PUB_STATUS
) | HIFN_PUBSTS_DONE
);
1943 restart
= dmacsr
& (HIFN_DMACSR_R_OVER
| HIFN_DMACSR_D_OVER
);
1945 printf("%s: overrun %x\n", device_xname(&sc
->sc_dv
), dmacsr
);
1947 if (sc
->sc_flags
& HIFN_IS_7811
) {
1948 if (dmacsr
& HIFN_DMACSR_ILLR
)
1949 printf("%s: illegal read\n", device_xname(&sc
->sc_dv
));
1950 if (dmacsr
& HIFN_DMACSR_ILLW
)
1951 printf("%s: illegal write\n", device_xname(&sc
->sc_dv
));
1954 restart
= dmacsr
& (HIFN_DMACSR_C_ABORT
| HIFN_DMACSR_S_ABORT
|
1955 HIFN_DMACSR_D_ABORT
| HIFN_DMACSR_R_ABORT
);
1957 printf("%s: abort, resetting.\n", device_xname(&sc
->sc_dv
));
1958 hifnstats
.hst_abort
++;
1963 if ((dmacsr
& HIFN_DMACSR_C_WAIT
) && (dma
->resu
== 0)) {
1965 * If no slots to process and we receive a "waiting on
1966 * command" interrupt, we disable the "waiting on command"
1969 sc
->sc_dmaier
&= ~HIFN_DMAIER_C_WAIT
;
1970 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
1973 /* clear the rings */
1975 while (dma
->resu
!= 0) {
1976 HIFN_RESR_SYNC(sc
, i
,
1977 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
1978 if (dma
->resr
[i
].l
& htole32(HIFN_D_VALID
)) {
1979 HIFN_RESR_SYNC(sc
, i
,
1980 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1984 if (i
!= HIFN_D_RES_RSIZE
) {
1985 struct hifn_command
*cmd
;
1987 HIFN_RES_SYNC(sc
, i
, BUS_DMASYNC_POSTREAD
);
1988 cmd
= dma
->hifn_commands
[i
];
1990 /*("hifn_intr: null command slot %u", i)*/);
1991 dma
->hifn_commands
[i
] = NULL
;
1993 hifn_callback(sc
, cmd
, dma
->result_bufs
[i
]);
1994 hifnstats
.hst_opackets
++;
1997 if (++i
== (HIFN_D_RES_RSIZE
+ 1))
2004 i
= dma
->srck
; u
= dma
->srcu
;
2006 HIFN_SRCR_SYNC(sc
, i
,
2007 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2008 if (dma
->srcr
[i
].l
& htole32(HIFN_D_VALID
)) {
2009 HIFN_SRCR_SYNC(sc
, i
,
2010 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2013 if (++i
== (HIFN_D_SRC_RSIZE
+ 1))
2018 dma
->srck
= i
; dma
->srcu
= u
;
2020 i
= dma
->cmdk
; u
= dma
->cmdu
;
2022 HIFN_CMDR_SYNC(sc
, i
,
2023 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2024 if (dma
->cmdr
[i
].l
& htole32(HIFN_D_VALID
)) {
2025 HIFN_CMDR_SYNC(sc
, i
,
2026 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2029 if (i
!= HIFN_D_CMD_RSIZE
) {
2031 HIFN_CMD_SYNC(sc
, i
, BUS_DMASYNC_POSTWRITE
);
2033 if (++i
== (HIFN_D_CMD_RSIZE
+ 1))
2036 dma
->cmdk
= i
; dma
->cmdu
= u
;
2042 * Allocate a new 'session' and return an encoded session id. 'sidp'
2043 * contains our registration id, and should contain an encoded session
2044 * id on successful allocation.
2047 hifn_newsession(void *arg
, u_int32_t
*sidp
, struct cryptoini
*cri
)
2049 struct cryptoini
*c
;
2050 struct hifn_softc
*sc
= arg
;
2051 int i
, mac
= 0, cry
= 0, comp
= 0;
2053 KASSERT(sc
!= NULL
/*, ("hifn_newsession: null softc")*/);
2054 if (sidp
== NULL
|| cri
== NULL
|| sc
== NULL
)
2057 for (i
= 0; i
< sc
->sc_maxses
; i
++)
2058 if (sc
->sc_sessions
[i
].hs_state
== HS_STATE_FREE
)
2060 if (i
== sc
->sc_maxses
)
2063 for (c
= cri
; c
!= NULL
; c
= c
->cri_next
) {
2064 switch (c
->cri_alg
) {
2067 case CRYPTO_MD5_HMAC_96
:
2068 case CRYPTO_SHA1_HMAC_96
:
2073 case CRYPTO_DES_CBC
:
2074 case CRYPTO_3DES_CBC
:
2075 case CRYPTO_AES_CBC
:
2076 /* Note that this is an initialization
2077 vector, not a cipher key; any function
2078 giving sufficient Hamming distance
2079 between outputs is fine. Use of RC4
2080 to generate IVs has been FIPS140-2
2081 certified by several labs. */
2083 arc4randbytes(sc
->sc_sessions
[i
].hs_iv
,
2084 c
->cri_alg
== CRYPTO_AES_CBC
?
2085 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2086 #else /* FreeBSD and OpenBSD have get_random_bytes */
2087 /* XXX this may read fewer, does it matter? */
2088 get_random_bytes(sc
->sc_sessions
[i
].hs_iv
,
2089 c
->cri_alg
== CRYPTO_AES_CBC
?
2090 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2098 #ifdef HAVE_CRYPTO_LZS
2099 case CRYPTO_LZS_COMP
:
2109 if (mac
== 0 && cry
== 0 && comp
== 0)
2113 * XXX only want to support compression without chaining to
2114 * MAC/crypt engine right now
2116 if ((comp
&& mac
) || (comp
&& cry
))
2119 *sidp
= HIFN_SID(device_unit(&sc
->sc_dv
), i
);
2120 sc
->sc_sessions
[i
].hs_state
= HS_STATE_USED
;
2126 * Deallocate a session.
2127 * XXX this routine should run a zero'd mac/encrypt key into context ram.
2128 * XXX to blow away any keys already stored there.
2131 hifn_freesession(void *arg
, u_int64_t tid
)
2133 struct hifn_softc
*sc
= arg
;
2135 u_int32_t sid
= ((u_int32_t
) tid
) & 0xffffffff;
2137 KASSERT(sc
!= NULL
/*, ("hifn_freesession: null softc")*/);
2141 session
= HIFN_SESSION(sid
);
2142 if (session
>= sc
->sc_maxses
)
2145 memset(&sc
->sc_sessions
[session
], 0, sizeof(sc
->sc_sessions
[session
]));
2150 hifn_process(void *arg
, struct cryptop
*crp
, int hint
)
2152 struct hifn_softc
*sc
= arg
;
2153 struct hifn_command
*cmd
= NULL
;
2154 int session
, err
, ivlen
;
2155 struct cryptodesc
*crd1
, *crd2
, *maccrd
, *enccrd
;
2157 if (crp
== NULL
|| crp
->crp_callback
== NULL
) {
2158 hifnstats
.hst_invalid
++;
2161 session
= HIFN_SESSION(crp
->crp_sid
);
2163 if (sc
== NULL
|| session
>= sc
->sc_maxses
) {
2168 cmd
= (struct hifn_command
*)malloc(sizeof(struct hifn_command
),
2169 M_DEVBUF
, M_NOWAIT
|M_ZERO
);
2171 hifnstats
.hst_nomem
++;
2176 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
2177 cmd
->srcu
.src_m
= (struct mbuf
*)crp
->crp_buf
;
2178 cmd
->dstu
.dst_m
= (struct mbuf
*)crp
->crp_buf
;
2179 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
2180 cmd
->srcu
.src_io
= (struct uio
*)crp
->crp_buf
;
2181 cmd
->dstu
.dst_io
= (struct uio
*)crp
->crp_buf
;
2184 goto errout
; /* XXX we don't handle contiguous buffers! */
2187 crd1
= crp
->crp_desc
;
2192 crd2
= crd1
->crd_next
;
2195 if (crd1
->crd_alg
== CRYPTO_MD5_HMAC_96
||
2196 crd1
->crd_alg
== CRYPTO_SHA1_HMAC_96
||
2197 crd1
->crd_alg
== CRYPTO_SHA1
||
2198 crd1
->crd_alg
== CRYPTO_MD5
) {
2201 } else if (crd1
->crd_alg
== CRYPTO_DES_CBC
||
2202 crd1
->crd_alg
== CRYPTO_3DES_CBC
||
2203 crd1
->crd_alg
== CRYPTO_AES_CBC
||
2204 crd1
->crd_alg
== CRYPTO_ARC4
) {
2205 if ((crd1
->crd_flags
& CRD_F_ENCRYPT
) == 0)
2206 cmd
->base_masks
|= HIFN_BASE_CMD_DECODE
;
2209 #ifdef HAVE_CRYPTO_LZS
2210 } else if (crd1
->crd_alg
== CRYPTO_LZS_COMP
) {
2211 return (hifn_compression(sc
, crp
, cmd
));
2218 if ((crd1
->crd_alg
== CRYPTO_MD5_HMAC_96
||
2219 crd1
->crd_alg
== CRYPTO_SHA1_HMAC_96
||
2220 crd1
->crd_alg
== CRYPTO_MD5
||
2221 crd1
->crd_alg
== CRYPTO_SHA1
) &&
2222 (crd2
->crd_alg
== CRYPTO_DES_CBC
||
2223 crd2
->crd_alg
== CRYPTO_3DES_CBC
||
2224 crd2
->crd_alg
== CRYPTO_AES_CBC
||
2225 crd2
->crd_alg
== CRYPTO_ARC4
) &&
2226 ((crd2
->crd_flags
& CRD_F_ENCRYPT
) == 0)) {
2227 cmd
->base_masks
= HIFN_BASE_CMD_DECODE
;
2230 } else if ((crd1
->crd_alg
== CRYPTO_DES_CBC
||
2231 crd1
->crd_alg
== CRYPTO_ARC4
||
2232 crd1
->crd_alg
== CRYPTO_3DES_CBC
||
2233 crd1
->crd_alg
== CRYPTO_AES_CBC
) &&
2234 (crd2
->crd_alg
== CRYPTO_MD5_HMAC_96
||
2235 crd2
->crd_alg
== CRYPTO_SHA1_HMAC_96
||
2236 crd2
->crd_alg
== CRYPTO_MD5
||
2237 crd2
->crd_alg
== CRYPTO_SHA1
) &&
2238 (crd1
->crd_flags
& CRD_F_ENCRYPT
)) {
2243 * We cannot order the 7751 as requested
2251 cmd
->enccrd
= enccrd
;
2252 cmd
->base_masks
|= HIFN_BASE_CMD_CRYPT
;
2253 switch (enccrd
->crd_alg
) {
2255 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_RC4
;
2256 if ((enccrd
->crd_flags
& CRD_F_ENCRYPT
)
2257 != sc
->sc_sessions
[session
].hs_prev_op
)
2258 sc
->sc_sessions
[session
].hs_state
=
2261 case CRYPTO_DES_CBC
:
2262 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_DES
|
2263 HIFN_CRYPT_CMD_MODE_CBC
|
2264 HIFN_CRYPT_CMD_NEW_IV
;
2266 case CRYPTO_3DES_CBC
:
2267 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_3DES
|
2268 HIFN_CRYPT_CMD_MODE_CBC
|
2269 HIFN_CRYPT_CMD_NEW_IV
;
2271 case CRYPTO_AES_CBC
:
2272 cmd
->cry_masks
|= HIFN_CRYPT_CMD_ALG_AES
|
2273 HIFN_CRYPT_CMD_MODE_CBC
|
2274 HIFN_CRYPT_CMD_NEW_IV
;
2280 if (enccrd
->crd_alg
!= CRYPTO_ARC4
) {
2281 ivlen
= ((enccrd
->crd_alg
== CRYPTO_AES_CBC
) ?
2282 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2283 if (enccrd
->crd_flags
& CRD_F_ENCRYPT
) {
2284 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
2285 memcpy(cmd
->iv
, enccrd
->crd_iv
, ivlen
);
2287 bcopy(sc
->sc_sessions
[session
].hs_iv
,
2290 if ((enccrd
->crd_flags
& CRD_F_IV_PRESENT
)
2292 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
2293 m_copyback(cmd
->srcu
.src_m
,
2296 else if (crp
->crp_flags
& CRYPTO_F_IOV
)
2297 cuio_copyback(cmd
->srcu
.src_io
,
2302 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
2303 memcpy(cmd
->iv
, enccrd
->crd_iv
, ivlen
);
2304 else if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
2305 m_copydata(cmd
->srcu
.src_m
,
2306 enccrd
->crd_inject
, ivlen
, cmd
->iv
);
2307 else if (crp
->crp_flags
& CRYPTO_F_IOV
)
2308 cuio_copydata(cmd
->srcu
.src_io
,
2309 enccrd
->crd_inject
, ivlen
, cmd
->iv
);
2313 cmd
->ck
= enccrd
->crd_key
;
2314 cmd
->cklen
= enccrd
->crd_klen
>> 3;
2317 * Need to specify the size for the AES key in the masks.
2319 if ((cmd
->cry_masks
& HIFN_CRYPT_CMD_ALG_MASK
) ==
2320 HIFN_CRYPT_CMD_ALG_AES
) {
2321 switch (cmd
->cklen
) {
2323 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_128
;
2326 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_192
;
2329 cmd
->cry_masks
|= HIFN_CRYPT_CMD_KSZ_256
;
2337 if (sc
->sc_sessions
[session
].hs_state
== HS_STATE_USED
)
2338 cmd
->cry_masks
|= HIFN_CRYPT_CMD_NEW_KEY
;
2342 cmd
->maccrd
= maccrd
;
2343 cmd
->base_masks
|= HIFN_BASE_CMD_MAC
;
2345 switch (maccrd
->crd_alg
) {
2347 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_MD5
|
2348 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HASH
|
2349 HIFN_MAC_CMD_POS_IPSEC
;
2351 case CRYPTO_MD5_HMAC_96
:
2352 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_MD5
|
2353 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HMAC
|
2354 HIFN_MAC_CMD_POS_IPSEC
| HIFN_MAC_CMD_TRUNC
;
2357 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_SHA1
|
2358 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HASH
|
2359 HIFN_MAC_CMD_POS_IPSEC
;
2361 case CRYPTO_SHA1_HMAC_96
:
2362 cmd
->mac_masks
|= HIFN_MAC_CMD_ALG_SHA1
|
2363 HIFN_MAC_CMD_RESULT
| HIFN_MAC_CMD_MODE_HMAC
|
2364 HIFN_MAC_CMD_POS_IPSEC
| HIFN_MAC_CMD_TRUNC
;
2368 if ((maccrd
->crd_alg
== CRYPTO_SHA1_HMAC_96
||
2369 maccrd
->crd_alg
== CRYPTO_MD5_HMAC_96
) &&
2370 sc
->sc_sessions
[session
].hs_state
== HS_STATE_USED
) {
2371 cmd
->mac_masks
|= HIFN_MAC_CMD_NEW_KEY
;
2372 memcpy(cmd
->mac
, maccrd
->crd_key
, maccrd
->crd_klen
>> 3);
2373 memset(cmd
->mac
+ (maccrd
->crd_klen
>> 3), 0,
2374 HIFN_MAC_KEY_LENGTH
- (maccrd
->crd_klen
>> 3));
2379 cmd
->session_num
= session
;
2382 err
= hifn_crypto(sc
, cmd
, crp
, hint
);
2385 sc
->sc_sessions
[session
].hs_prev_op
=
2386 enccrd
->crd_flags
& CRD_F_ENCRYPT
;
2387 if (sc
->sc_sessions
[session
].hs_state
== HS_STATE_USED
)
2388 sc
->sc_sessions
[session
].hs_state
= HS_STATE_KEY
;
2390 } else if (err
== ERESTART
) {
2392 * There weren't enough resources to dispatch the request
2393 * to the part. Notify the caller so they'll requeue this
2394 * request and resubmit it again soon.
2398 printf(device_xname(&sc
->sc_dv
), "requeue request\n");
2400 free(cmd
, M_DEVBUF
);
2401 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
2407 free(cmd
, M_DEVBUF
);
2409 hifnstats
.hst_invalid
++;
2411 hifnstats
.hst_nomem
++;
2412 crp
->crp_etype
= err
;
2418 hifn_abort(struct hifn_softc
*sc
)
2420 struct hifn_dma
*dma
= sc
->sc_dma
;
2421 struct hifn_command
*cmd
;
2422 struct cryptop
*crp
;
2425 i
= dma
->resk
; u
= dma
->resu
;
2427 cmd
= dma
->hifn_commands
[i
];
2428 KASSERT(cmd
!= NULL
/*, ("hifn_abort: null cmd slot %u", i)*/);
2429 dma
->hifn_commands
[i
] = NULL
;
2432 if ((dma
->resr
[i
].l
& htole32(HIFN_D_VALID
)) == 0) {
2433 /* Salvage what we can. */
2434 hifnstats
.hst_opackets
++;
2435 hifn_callback(sc
, cmd
, dma
->result_bufs
[i
]);
2437 if (cmd
->src_map
== cmd
->dst_map
) {
2438 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2439 0, cmd
->src_map
->dm_mapsize
,
2440 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
2442 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2443 0, cmd
->src_map
->dm_mapsize
,
2444 BUS_DMASYNC_POSTWRITE
);
2445 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2446 0, cmd
->dst_map
->dm_mapsize
,
2447 BUS_DMASYNC_POSTREAD
);
2450 if (cmd
->srcu
.src_m
!= cmd
->dstu
.dst_m
) {
2451 m_freem(cmd
->srcu
.src_m
);
2452 crp
->crp_buf
= (void *)cmd
->dstu
.dst_m
;
2455 /* non-shared buffers cannot be restarted */
2456 if (cmd
->src_map
!= cmd
->dst_map
) {
2458 * XXX should be EAGAIN, delayed until
2461 crp
->crp_etype
= ENOMEM
;
2462 bus_dmamap_unload(sc
->sc_dmat
, cmd
->dst_map
);
2463 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->dst_map
);
2465 crp
->crp_etype
= ENOMEM
;
2467 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
2468 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->src_map
);
2470 free(cmd
, M_DEVBUF
);
2471 if (crp
->crp_etype
!= EAGAIN
)
2475 if (++i
== HIFN_D_RES_RSIZE
)
2479 dma
->resk
= i
; dma
->resu
= u
;
2481 /* Force upload of key next time */
2482 for (i
= 0; i
< sc
->sc_maxses
; i
++)
2483 if (sc
->sc_sessions
[i
].hs_state
== HS_STATE_KEY
)
2484 sc
->sc_sessions
[i
].hs_state
= HS_STATE_USED
;
2486 hifn_reset_board(sc
, 1);
2488 hifn_init_pci_registers(sc
);
2492 hifn_callback(struct hifn_softc
*sc
, struct hifn_command
*cmd
, u_int8_t
*resbuf
)
2494 struct hifn_dma
*dma
= sc
->sc_dma
;
2495 struct cryptop
*crp
= cmd
->crp
;
2496 struct cryptodesc
*crd
;
2498 int totlen
, i
, u
, ivlen
;
2500 if (cmd
->src_map
== cmd
->dst_map
)
2501 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2502 0, cmd
->src_map
->dm_mapsize
,
2503 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2505 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2506 0, cmd
->src_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
2507 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2508 0, cmd
->dst_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
2511 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
2512 if (cmd
->srcu
.src_m
!= cmd
->dstu
.dst_m
) {
2513 crp
->crp_buf
= (void *)cmd
->dstu
.dst_m
;
2514 totlen
= cmd
->src_map
->dm_mapsize
;
2515 for (m
= cmd
->dstu
.dst_m
; m
!= NULL
; m
= m
->m_next
) {
2516 if (totlen
< m
->m_len
) {
2522 cmd
->dstu
.dst_m
->m_pkthdr
.len
=
2523 cmd
->srcu
.src_m
->m_pkthdr
.len
;
2524 m_freem(cmd
->srcu
.src_m
);
2528 if (cmd
->sloplen
!= 0) {
2529 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
2530 m_copyback((struct mbuf
*)crp
->crp_buf
,
2531 cmd
->src_map
->dm_mapsize
- cmd
->sloplen
,
2532 cmd
->sloplen
, (void *)&dma
->slop
[cmd
->slopidx
]);
2533 else if (crp
->crp_flags
& CRYPTO_F_IOV
)
2534 cuio_copyback((struct uio
*)crp
->crp_buf
,
2535 cmd
->src_map
->dm_mapsize
- cmd
->sloplen
,
2536 cmd
->sloplen
, (void *)&dma
->slop
[cmd
->slopidx
]);
2539 i
= dma
->dstk
; u
= dma
->dstu
;
2541 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2542 offsetof(struct hifn_dma
, dstr
[i
]), sizeof(struct hifn_desc
),
2543 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2544 if (dma
->dstr
[i
].l
& htole32(HIFN_D_VALID
)) {
2545 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2546 offsetof(struct hifn_dma
, dstr
[i
]),
2547 sizeof(struct hifn_desc
),
2548 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2551 if (++i
== (HIFN_D_DST_RSIZE
+ 1))
2556 dma
->dstk
= i
; dma
->dstu
= u
;
2558 hifnstats
.hst_obytes
+= cmd
->dst_map
->dm_mapsize
;
2560 if ((cmd
->base_masks
& (HIFN_BASE_CMD_CRYPT
| HIFN_BASE_CMD_DECODE
)) ==
2561 HIFN_BASE_CMD_CRYPT
) {
2562 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
2563 if (crd
->crd_alg
!= CRYPTO_DES_CBC
&&
2564 crd
->crd_alg
!= CRYPTO_3DES_CBC
&&
2565 crd
->crd_alg
!= CRYPTO_AES_CBC
)
2567 ivlen
= ((crd
->crd_alg
== CRYPTO_AES_CBC
) ?
2568 HIFN_AES_IV_LENGTH
: HIFN_IV_LENGTH
);
2569 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
2570 m_copydata((struct mbuf
*)crp
->crp_buf
,
2571 crd
->crd_skip
+ crd
->crd_len
- ivlen
,
2573 cmd
->softc
->sc_sessions
[cmd
->session_num
].hs_iv
);
2574 else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
2575 cuio_copydata((struct uio
*)crp
->crp_buf
,
2576 crd
->crd_skip
+ crd
->crd_len
- ivlen
,
2578 cmd
->softc
->sc_sessions
[cmd
->session_num
].hs_iv
);
2580 /* XXX We do not handle contig data */
2585 if (cmd
->base_masks
& HIFN_BASE_CMD_MAC
) {
2588 macbuf
= resbuf
+ sizeof(struct hifn_base_result
);
2589 if (cmd
->base_masks
& HIFN_BASE_CMD_COMP
)
2590 macbuf
+= sizeof(struct hifn_comp_result
);
2591 macbuf
+= sizeof(struct hifn_mac_result
);
2593 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
2596 if (crd
->crd_alg
== CRYPTO_MD5
)
2598 else if (crd
->crd_alg
== CRYPTO_SHA1
)
2600 else if (crd
->crd_alg
== CRYPTO_MD5_HMAC_96
||
2601 crd
->crd_alg
== CRYPTO_SHA1_HMAC_96
)
2606 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
2607 m_copyback((struct mbuf
*)crp
->crp_buf
,
2608 crd
->crd_inject
, len
, macbuf
);
2609 else if ((crp
->crp_flags
& CRYPTO_F_IOV
) && crp
->crp_mac
)
2610 memcpy(crp
->crp_mac
, (void *)macbuf
, len
);
2615 if (cmd
->src_map
!= cmd
->dst_map
) {
2616 bus_dmamap_unload(sc
->sc_dmat
, cmd
->dst_map
);
2617 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->dst_map
);
2619 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
2620 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->src_map
);
2621 free(cmd
, M_DEVBUF
);
2625 #ifdef HAVE_CRYPTO_LZS
2628 hifn_compression(struct hifn_softc
*sc
, struct cryptop
*crp
,
2629 struct hifn_command
*cmd
)
2631 struct cryptodesc
*crd
= crp
->crp_desc
;
2635 cmd
->base_masks
|= HIFN_BASE_CMD_COMP
;
2637 if ((crp
->crp_flags
& CRYPTO_F_IMBUF
) == 0) {
2639 * XXX can only handle mbufs right now since we can
2640 * XXX dynamically resize them.
2646 if ((crd
->crd_flags
& CRD_F_COMP
) == 0)
2647 cmd
->base_masks
|= HIFN_BASE_CMD_DECODE
;
2648 if (crd
->crd_alg
== CRYPTO_LZS_COMP
)
2649 cmd
->comp_masks
|= HIFN_COMP_CMD_ALG_LZS
|
2650 HIFN_COMP_CMD_CLEARHIST
;
2652 if (bus_dmamap_create(sc
->sc_dmat
, HIFN_MAX_DMALEN
, MAX_SCATTER
,
2653 HIFN_MAX_SEGLEN
, 0, BUS_DMA_NOWAIT
, &cmd
->src_map
)) {
2658 if (bus_dmamap_create(sc
->sc_dmat
, HIFN_MAX_DMALEN
, MAX_SCATTER
,
2659 HIFN_MAX_SEGLEN
, 0, BUS_DMA_NOWAIT
, &cmd
->dst_map
)) {
2664 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
2667 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, cmd
->src_map
,
2668 cmd
->srcu
.src_m
, BUS_DMA_NOWAIT
)) {
2673 len
= cmd
->src_map
->dm_mapsize
/ MCLBYTES
;
2674 if ((cmd
->src_map
->dm_mapsize
% MCLBYTES
) != 0)
2678 if ((crd
->crd_flags
& CRD_F_COMP
) == 0)
2681 if (len
> HIFN_MAX_DMALEN
)
2682 len
= HIFN_MAX_DMALEN
;
2684 cmd
->dstu
.dst_m
= hifn_mkmbuf_chain(len
, cmd
->srcu
.src_m
);
2685 if (cmd
->dstu
.dst_m
== NULL
) {
2690 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, cmd
->dst_map
,
2691 cmd
->dstu
.dst_m
, BUS_DMA_NOWAIT
)) {
2695 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
2696 if (bus_dmamap_load_uio(sc
->sc_dmat
, cmd
->src_map
,
2697 cmd
->srcu
.src_io
, BUS_DMA_NOWAIT
)) {
2701 if (bus_dmamap_load_uio(sc
->sc_dmat
, cmd
->dst_map
,
2702 cmd
->dstu
.dst_io
, BUS_DMA_NOWAIT
)) {
2708 if (cmd
->src_map
== cmd
->dst_map
)
2709 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2710 0, cmd
->src_map
->dm_mapsize
,
2711 BUS_DMASYNC_PREWRITE
|BUS_DMASYNC_PREREAD
);
2713 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2714 0, cmd
->src_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2715 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2716 0, cmd
->dst_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
2721 * Always use session 0. The modes of compression we use are
2722 * stateless and there is always at least one compression
2725 cmd
->session_num
= 0;
2729 err
= hifn_compress_enter(sc
, cmd
);
2737 if (cmd
->dst_map
!= NULL
) {
2738 if (cmd
->dst_map
->dm_nsegs
> 0)
2739 bus_dmamap_unload(sc
->sc_dmat
, cmd
->dst_map
);
2740 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->dst_map
);
2742 if (cmd
->src_map
!= NULL
) {
2743 if (cmd
->src_map
->dm_nsegs
> 0)
2744 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
2745 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->src_map
);
2747 free(cmd
, M_DEVBUF
);
2749 hifnstats
.hst_invalid
++;
2751 hifnstats
.hst_nomem
++;
2752 crp
->crp_etype
= err
;
2758 * must be called at splnet()
2761 hifn_compress_enter(struct hifn_softc
*sc
, struct hifn_command
*cmd
)
2763 struct hifn_dma
*dma
= sc
->sc_dma
;
2767 if ((dma
->cmdu
+ 1) > HIFN_D_CMD_RSIZE
||
2768 (dma
->resu
+ 1) > HIFN_D_CMD_RSIZE
)
2771 if ((dma
->srcu
+ cmd
->src_map
->dm_nsegs
) > HIFN_D_SRC_RSIZE
||
2772 (dma
->dstu
+ cmd
->dst_map
->dm_nsegs
) > HIFN_D_DST_RSIZE
)
2775 if (dma
->cmdi
== HIFN_D_CMD_RSIZE
) {
2777 dma
->cmdr
[HIFN_D_CMD_RSIZE
].l
= htole32(HIFN_D_VALID
|
2778 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
2779 HIFN_CMDR_SYNC(sc
, HIFN_D_CMD_RSIZE
,
2780 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2783 cmdlen
= hifn_write_command(cmd
, dma
->command_bufs
[cmdi
]);
2784 HIFN_CMD_SYNC(sc
, cmdi
, BUS_DMASYNC_PREWRITE
);
2786 /* .p for command/result already set */
2787 dma
->cmdr
[cmdi
].l
= htole32(cmdlen
| HIFN_D_VALID
| HIFN_D_LAST
|
2788 HIFN_D_MASKDONEIRQ
);
2789 HIFN_CMDR_SYNC(sc
, cmdi
,
2790 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2792 if (sc
->sc_c_busy
== 0) {
2793 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_C_CTRL_ENA
);
2795 SET_LED(sc
, HIFN_MIPSRST_LED0
);
2799 * We don't worry about missing an interrupt (which a "command wait"
2800 * interrupt salvages us from), unless there is more than one command
2803 if (dma
->cmdu
> 1) {
2804 sc
->sc_dmaier
|= HIFN_DMAIER_C_WAIT
;
2805 WRITE_REG_1(sc
, HIFN_1_DMA_IER
, sc
->sc_dmaier
);
2808 hifnstats
.hst_ipackets
++;
2809 hifnstats
.hst_ibytes
+= cmd
->src_map
->dm_mapsize
;
2811 hifn_dmamap_load_src(sc
, cmd
);
2812 if (sc
->sc_s_busy
== 0) {
2813 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_S_CTRL_ENA
);
2815 SET_LED(sc
, HIFN_MIPSRST_LED1
);
2819 * Unlike other descriptors, we don't mask done interrupt from
2820 * result descriptor.
2822 if (dma
->resi
== HIFN_D_RES_RSIZE
) {
2824 dma
->resr
[HIFN_D_RES_RSIZE
].l
= htole32(HIFN_D_VALID
|
2825 HIFN_D_JUMP
| HIFN_D_MASKDONEIRQ
);
2826 HIFN_RESR_SYNC(sc
, HIFN_D_RES_RSIZE
,
2827 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2830 dma
->hifn_commands
[resi
] = cmd
;
2831 HIFN_RES_SYNC(sc
, resi
, BUS_DMASYNC_PREREAD
);
2832 dma
->resr
[resi
].l
= htole32(HIFN_MAX_RESULT
|
2833 HIFN_D_VALID
| HIFN_D_LAST
);
2834 HIFN_RESR_SYNC(sc
, resi
,
2835 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2837 if (sc
->sc_r_busy
== 0) {
2838 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_R_CTRL_ENA
);
2840 SET_LED(sc
, HIFN_MIPSRST_LED2
);
2844 cmd
->slopidx
= resi
;
2846 hifn_dmamap_load_dst(sc
, cmd
);
2848 if (sc
->sc_d_busy
== 0) {
2849 WRITE_REG_1(sc
, HIFN_1_DMA_CSR
, HIFN_DMACSR_D_CTRL_ENA
);
2853 cmd
->cmd_callback
= hifn_callback_comp
;
2858 hifn_callback_comp(struct hifn_softc
*sc
, struct hifn_command
*cmd
,
2861 struct hifn_base_result baseres
;
2862 struct cryptop
*crp
= cmd
->crp
;
2863 struct hifn_dma
*dma
= sc
->sc_dma
;
2869 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2870 0, cmd
->src_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
2871 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2872 0, cmd
->dst_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
2874 dstsize
= cmd
->dst_map
->dm_mapsize
;
2875 bus_dmamap_unload(sc
->sc_dmat
, cmd
->dst_map
);
2877 memcpy(&baseres
, resbuf
, sizeof(struct hifn_base_result
));
2879 i
= dma
->dstk
; u
= dma
->dstu
;
2881 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2882 offsetof(struct hifn_dma
, dstr
[i
]), sizeof(struct hifn_desc
),
2883 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
2884 if (dma
->dstr
[i
].l
& htole32(HIFN_D_VALID
)) {
2885 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap
,
2886 offsetof(struct hifn_dma
, dstr
[i
]),
2887 sizeof(struct hifn_desc
),
2888 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2891 if (++i
== (HIFN_D_DST_RSIZE
+ 1))
2896 dma
->dstk
= i
; dma
->dstu
= u
;
2898 if (baseres
.flags
& htole16(HIFN_BASE_RES_DSTOVERRUN
)) {
2903 m_freem(cmd
->dstu
.dst_m
);
2905 if (xlen
== HIFN_MAX_DMALEN
) {
2906 /* We've done all we can. */
2913 if (xlen
> HIFN_MAX_DMALEN
)
2914 xlen
= HIFN_MAX_DMALEN
;
2916 cmd
->dstu
.dst_m
= hifn_mkmbuf_chain(xlen
,
2918 if (cmd
->dstu
.dst_m
== NULL
) {
2922 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, cmd
->dst_map
,
2923 cmd
->dstu
.dst_m
, BUS_DMA_NOWAIT
)) {
2928 bus_dmamap_sync(sc
->sc_dmat
, cmd
->src_map
,
2929 0, cmd
->src_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2930 bus_dmamap_sync(sc
->sc_dmat
, cmd
->dst_map
,
2931 0, cmd
->dst_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
2933 /* already at splnet... */
2934 err
= hifn_compress_enter(sc
, cmd
);
2940 olen
= dstsize
- (letoh16(baseres
.dst_cnt
) |
2941 (((letoh16(baseres
.session
) & HIFN_BASE_RES_DSTLEN_M
) >>
2942 HIFN_BASE_RES_DSTLEN_S
) << 16));
2944 crp
->crp_olen
= olen
- cmd
->compcrd
->crd_skip
;
2946 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
2947 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->src_map
);
2948 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->dst_map
);
2950 m
= cmd
->dstu
.dst_m
;
2951 if (m
->m_flags
& M_PKTHDR
)
2952 m
->m_pkthdr
.len
= olen
;
2953 crp
->crp_buf
= (void *)m
;
2954 for (; m
!= NULL
; m
= m
->m_next
) {
2955 if (olen
>= m
->m_len
)
2963 m_freem(cmd
->srcu
.src_m
);
2964 free(cmd
, M_DEVBUF
);
2970 if (cmd
->dst_map
!= NULL
) {
2971 if (cmd
->src_map
->dm_nsegs
!= 0)
2972 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
2973 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->dst_map
);
2975 if (cmd
->src_map
!= NULL
) {
2976 if (cmd
->src_map
->dm_nsegs
!= 0)
2977 bus_dmamap_unload(sc
->sc_dmat
, cmd
->src_map
);
2978 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->src_map
);
2980 if (cmd
->dstu
.dst_m
!= NULL
)
2981 m_freem(cmd
->dstu
.dst_m
);
2982 free(cmd
, M_DEVBUF
);
2983 crp
->crp_etype
= err
;
2987 static struct mbuf
*
2988 hifn_mkmbuf_chain(int totlen
, struct mbuf
*mtemplate
)
2991 struct mbuf
*m
, *m0
, *mlast
;
2993 if (mtemplate
->m_flags
& M_PKTHDR
) {
2995 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
2998 MGET(m0
, M_DONTWAIT
, MT_DATA
);
3003 M_DUP_PKTHDR(m0
, mtemplate
);
3004 MCLGET(m0
, M_DONTWAIT
);
3005 if (!(m0
->m_flags
& M_EXT
))
3010 m0
->m_pkthdr
.len
= m0
->m_len
= len
;
3013 while (totlen
> 0) {
3014 MGET(m
, M_DONTWAIT
, MT_DATA
);
3019 MCLGET(m
, M_DONTWAIT
);
3020 if (!(m
->m_flags
& M_EXT
)) {
3026 if (m0
->m_flags
& M_PKTHDR
)
3027 m0
->m_pkthdr
.len
+= len
;
3036 #endif /* HAVE_CRYPTO_LZS */
3039 hifn_write_4(struct hifn_softc
*sc
, int reggrp
, bus_size_t reg
, u_int32_t val
)
3042 * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
3043 * and Group 1 registers; avoid conditions that could create
3044 * burst writes by doing a read in between the writes.
3046 if (sc
->sc_flags
& HIFN_NO_BURSTWRITE
) {
3047 if (sc
->sc_waw_lastgroup
== reggrp
&&
3048 sc
->sc_waw_lastreg
== reg
- 4) {
3049 bus_space_read_4(sc
->sc_st1
, sc
->sc_sh1
, HIFN_1_REVID
);
3051 sc
->sc_waw_lastgroup
= reggrp
;
3052 sc
->sc_waw_lastreg
= reg
;
3055 bus_space_write_4(sc
->sc_st0
, sc
->sc_sh0
, reg
, val
);
3057 bus_space_write_4(sc
->sc_st1
, sc
->sc_sh1
, reg
, val
);
3062 hifn_read_4(struct hifn_softc
*sc
, int reggrp
, bus_size_t reg
)
3064 if (sc
->sc_flags
& HIFN_NO_BURSTWRITE
) {
3065 sc
->sc_waw_lastgroup
= -1;
3066 sc
->sc_waw_lastreg
= 1;
3069 return (bus_space_read_4(sc
->sc_st0
, sc
->sc_sh0
, reg
));
3070 return (bus_space_read_4(sc
->sc_st1
, sc
->sc_sh1
, reg
));