diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/files.pci | 17 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751.c | 2771 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751reg.h | 523 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751var.h | 324 | ||||
-rw-r--r-- | sys/dev/pci/safe.c | 1829 | ||||
-rw-r--r-- | sys/dev/pci/safereg.h | 413 | ||||
-rw-r--r-- | sys/dev/pci/safevar.h | 205 | ||||
-rw-r--r-- | sys/dev/pci/ubsec.c | 1742 | ||||
-rw-r--r-- | sys/dev/pci/ubsecreg.h | 252 | ||||
-rw-r--r-- | sys/dev/pci/ubsecvar.h | 175 |
10 files changed, 1 insertions, 8250 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index 0bde7450cc8..a20459798b9 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.355 2021/09/02 10:11:21 mlarkin Exp $ +# $OpenBSD: files.pci,v 1.356 2021/10/21 18:36:42 bluhm Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -420,21 +420,6 @@ device nep: ether, ifnet, ifmedia, mii attach nep at pci file dev/pci/if_nep.c nep -# Hi/fn 7751/7811/7951 -device hifn: crypto -attach hifn at pci -file dev/pci/hifn7751.c hifn - -# Bluesteelnet (Broadcom) 5501/5601 -device ubsec: crypto -attach ubsec at pci -file dev/pci/ubsec.c ubsec - -# Safenet SafeXcel 1141 -device safe: crypto -attach safe at pci -file dev/pci/safe.c safe - # Winbond W89C840F ethernet device wb: ether, ifnet, mii, ifmedia, mii_phy attach wb at pci diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c deleted file mode 100644 index cae21a06000..00000000000 --- a/sys/dev/pci/hifn7751.c +++ /dev/null @@ -1,2771 +0,0 @@ -/* $OpenBSD: hifn7751.c,v 1.181 2021/10/13 13:08:58 bluhm Exp $ */ - -/* - * Invertex AEON / Hifn 7751 driver - * Copyright (c) 1999 Invertex Inc. All rights reserved. - * Copyright (c) 1999 Theo de Raadt - * Copyright (c) 2000-2001 Network Security Technologies, Inc. - * http://www.netsec.net - * Copyright (c) 2003 Hifn Inc. - - * This driver is based on a previous driver by Invertex, for which they - * requested: Please send any comments, feedback, bug-fixes, or feature - * requests to software@invertex.com. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -/* - * Driver for various Hifn encryption processors. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/timeout.h> -#include <sys/errno.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/mbuf.h> -#include <sys/device.h> - -#include <crypto/cryptodev.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -#include <dev/pci/hifn7751reg.h> -#include <dev/pci/hifn7751var.h> - -#undef HIFN_DEBUG - -/* - * Prototypes and count for the pci_device structure - */ -int hifn_probe(struct device *, void *, void *); -void hifn_attach(struct device *, struct device *, void *); - -struct cfattach hifn_ca = { - sizeof(struct hifn_softc), hifn_probe, hifn_attach, -}; - -struct cfdriver hifn_cd = { - 0, "hifn", DV_DULL -}; - -void hifn_reset_board(struct hifn_softc *, int); -void hifn_reset_puc(struct hifn_softc *); -void hifn_puc_wait(struct hifn_softc *); -int hifn_enable_crypto(struct hifn_softc *, pcireg_t); -void hifn_set_retry(struct hifn_softc *); -void hifn_init_dma(struct hifn_softc *); -void hifn_init_pci_registers(struct hifn_softc *); -int hifn_sramsize(struct hifn_softc *); -int hifn_dramsize(struct hifn_softc *); -int hifn_ramtype(struct hifn_softc *); -void hifn_sessions(struct hifn_softc *); -int hifn_intr(void *); -u_int hifn_write_command(struct hifn_command *, u_int8_t *); -u_int32_t hifn_next_signature(u_int32_t a, u_int cnt); -int hifn_newsession(u_int32_t *, struct cryptoini *); -int hifn_freesession(u_int64_t); -int hifn_process(struct cryptop *); -void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *); -int hifn_crypto(struct hifn_softc *, struct hifn_command *, - struct cryptop *); -int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *); -int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *); -int hifn_dmamap_aligned(bus_dmamap_t); -int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *); -int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *); -int hifn_init_pubrng(struct hifn_softc *); -void hifn_rng(void *); -void hifn_tick(void *); -void hifn_abort(struct hifn_softc *); -void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *); -void hifn_write_4(struct hifn_softc *, int, bus_size_t, u_int32_t); -u_int32_t hifn_read_4(struct hifn_softc *, int, bus_size_t); -int hifn_compression(struct hifn_softc *, struct cryptop *, - struct hifn_command *); -struct mbuf *hifn_mkmbuf_chain(int, struct mbuf *); -int hifn_compress_enter(struct hifn_softc *, struct hifn_command *); -void hifn_callback_comp(struct hifn_softc *, struct hifn_command *, - u_int8_t *); - -struct hifn_stats hifnstats; - -const struct pci_matchid hifn_devices[] = { - { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956 }, - { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751 }, -}; - -int -hifn_probe(struct device *parent, void *match, void *aux) -{ - return (pci_matchbyid((struct pci_attach_args *)aux, hifn_devices, - nitems(hifn_devices))); -} - -void -hifn_attach(struct device *parent, struct device *self, void *aux) -{ - struct hifn_softc *sc = (struct hifn_softc *)self; - struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; - const char *intrstr = NULL; - char rbase; - bus_size_t iosize0, iosize1; - u_int16_t ena; - int rseg; - caddr_t kva; - int algs[CRYPTO_ALGORITHM_MAX + 1]; - - sc->sc_pci_pc = pa->pa_pc; - sc->sc_pci_tag = pa->pa_tag; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7951)) - sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7955 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7956)) - sc->sc_flags = HIFN_IS_7956 | HIFN_HAS_AES | HIFN_HAS_RNG | - HIFN_HAS_PUBLIC; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7811) - sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG | HIFN_HAS_LEDS | - HIFN_NO_BURSTWRITE; - - if (pci_mapreg_map(pa, HIFN_BAR0, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_st0, &sc->sc_sh0, NULL, &iosize0, 0)) { - printf(": can't find mem space %d\n", 0); - return; - } - - if (pci_mapreg_map(pa, HIFN_BAR1, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_st1, &sc->sc_sh1, NULL, &iosize1, 0)) { - printf(": can't find mem space %d\n", 1); - goto fail_io0; - } - - hifn_set_retry(sc); - - if (sc->sc_flags & HIFN_NO_BURSTWRITE) { - sc->sc_waw_lastgroup = -1; - sc->sc_waw_lastreg = 1; - } - - sc->sc_dmat = pa->pa_dmat; - if (bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_dma), 1, - sizeof(*sc->sc_dma), 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) { - printf(": can't create dma map\n"); - goto fail_io1; - } - if (bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_dma), PAGE_SIZE, 0, - sc->sc_dmasegs, 1, &sc->sc_dmansegs, - BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { - printf(": can't alloc dma buffer\n"); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - goto fail_io1; - } - if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs, - sizeof(*sc->sc_dma), &kva, BUS_DMA_NOWAIT)) { - printf(": can't map dma buffers (%lu bytes)\n", - (u_long)sizeof(*sc->sc_dma)); - bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - goto fail_io1; - } - if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, kva, - sizeof(*sc->sc_dma), NULL, BUS_DMA_NOWAIT)) { - printf(": can't load dma map\n"); - bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(*sc->sc_dma)); - bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - goto fail_io1; - } - sc->sc_dma = (struct hifn_dma *)kva; - - hifn_reset_board(sc, 0); - - if (hifn_enable_crypto(sc, pa->pa_id) != 0) { - printf("%s: crypto enabling failed\n", sc->sc_dv.dv_xname); - goto fail_mem; - } - hifn_reset_puc(sc); - - hifn_init_dma(sc); - hifn_init_pci_registers(sc); - - if (sc->sc_flags & HIFN_IS_7956) - sc->sc_drammodel = 1; - else if (hifn_ramtype(sc)) - goto fail_mem; - - if (sc->sc_drammodel == 0) - hifn_sramsize(sc); - else - hifn_dramsize(sc); - - /* - * Workaround for NetSec 7751 rev A: half ram size because two - * of the address lines were left floating - */ - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETSEC && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETSEC_7751 && - PCI_REVISION(pa->pa_class) == 0x61) - sc->sc_ramsize >>= 1; - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - goto fail_mem; - } - intrstr = pci_intr_string(pc, ih); - sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, hifn_intr, sc, - self->dv_xname); - if (sc->sc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - goto fail_mem; - } - - hifn_sessions(sc); - - rseg = sc->sc_ramsize / 1024; - rbase = 'K'; - if (sc->sc_ramsize >= (1024 * 1024)) { - rbase = 'M'; - rseg /= 1024; - } - printf("%d%cB %cram, %s\n", rseg, rbase, - sc->sc_drammodel ? 'd' : 's', intrstr); - - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) - goto fail_intr; - - WRITE_REG_0(sc, HIFN_0_PUCNFG, - READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID); - ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA; - - bzero(algs, sizeof(algs)); - - algs[CRYPTO_LZS_COMP] = CRYPTO_ALG_FLAG_SUPPORTED; - switch (ena) { - case HIFN_PUSTAT_ENA_2: - algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - /*FALLTHROUGH*/ - case HIFN_PUSTAT_ENA_1: - algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (sc->sc_flags & HIFN_HAS_AES) - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - - crypto_register(sc->sc_cid, algs, hifn_newsession, - hifn_freesession, hifn_process); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, - sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG)) - hifn_init_pubrng(sc); - - timeout_set(&sc->sc_tickto, hifn_tick, sc); - timeout_add_sec(&sc->sc_tickto, 1); - - return; - -fail_intr: - pci_intr_disestablish(pc, sc->sc_ih); -fail_mem: - bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap); - bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(*sc->sc_dma)); - bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - - /* Turn off DMA polling */ - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - -fail_io1: - bus_space_unmap(sc->sc_st1, sc->sc_sh1, iosize1); -fail_io0: - bus_space_unmap(sc->sc_st0, sc->sc_sh0, iosize0); -} - -int -hifn_init_pubrng(struct hifn_softc *sc) -{ - u_int32_t r; - int i; - - if ((sc->sc_flags & HIFN_IS_7811) == 0) { - /* Reset 7951 public key/rng engine */ - WRITE_REG_1(sc, HIFN_1_PUB_RESET, - READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET); - - for (i = 0; i < 100; i++) { - DELAY(1000); - if ((READ_REG_1(sc, HIFN_1_PUB_RESET) & - HIFN_PUBRST_RESET) == 0) - break; - } - - if (i == 100) { - printf("%s: public key init failed\n", - sc->sc_dv.dv_xname); - return (1); - } - } - - /* Enable the rng, if available */ - if (sc->sc_flags & HIFN_HAS_RNG) { - if (sc->sc_flags & HIFN_IS_7811) { - r = READ_REG_1(sc, HIFN_1_7811_RNGENA); - if (r & HIFN_7811_RNGENA_ENA) { - r &= ~HIFN_7811_RNGENA_ENA; - WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r); - } - WRITE_REG_1(sc, HIFN_1_7811_RNGCFG, - HIFN_7811_RNGCFG_DEFL); - r |= HIFN_7811_RNGENA_ENA; - WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r); - } else - WRITE_REG_1(sc, HIFN_1_RNG_CONFIG, - READ_REG_1(sc, HIFN_1_RNG_CONFIG) | - HIFN_RNGCFG_ENA); - - sc->sc_rngfirst = 1; - sc->sc_rngms = 10; - timeout_set(&sc->sc_rngto, hifn_rng, sc); - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); - } - - /* Enable public key engine, if available */ - if (sc->sc_flags & HIFN_HAS_PUBLIC) { - WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE); - sc->sc_dmaier |= HIFN_DMAIER_PUBDONE; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - } - - return (0); -} - -void -hifn_rng(void *vsc) -{ - struct hifn_softc *sc = vsc; - u_int32_t num1, sts, num2; - int i; - - if (sc->sc_flags & HIFN_IS_7811) { - for (i = 0; i < 5; i++) { - sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS); - if (sts & HIFN_7811_RNGSTS_UFL) { - printf("%s: RNG underflow: disabling\n", - sc->sc_dv.dv_xname); - return; - } - if ((sts & HIFN_7811_RNGSTS_RDY) == 0) - break; - - /* - * There are at least two words in the RNG FIFO - * at this point. - */ - num1 = READ_REG_1(sc, HIFN_1_7811_RNGDAT); - num2 = READ_REG_1(sc, HIFN_1_7811_RNGDAT); - if (sc->sc_rngfirst) - sc->sc_rngfirst = 0; - else { - enqueue_randomness(num1); - enqueue_randomness(num2); - } - } - } else { - num1 = READ_REG_1(sc, HIFN_1_RNG_DATA); - - if (sc->sc_rngfirst) - sc->sc_rngfirst = 0; - else - enqueue_randomness(num1); - } - - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); -} - -void -hifn_puc_wait(struct hifn_softc *sc) -{ - int i; - - for (i = 5000; i > 0; i--) { - DELAY(1); - if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET)) - break; - } - if (!i) - printf("%s: proc unit did not reset\n", sc->sc_dv.dv_xname); -} - -/* - * Reset the processing unit. - */ -void -hifn_reset_puc(struct hifn_softc *sc) -{ - /* Reset processing unit */ - WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA); - hifn_puc_wait(sc); -} - -void -hifn_set_retry(struct hifn_softc *sc) -{ - u_int32_t r; - - r = pci_conf_read(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_TRDY_TIMEOUT); - r &= 0xffff0000; - pci_conf_write(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_TRDY_TIMEOUT, r); -} - -/* - * Resets the board. Values in the regesters are left as is - * from the reset (i.e. initial values are assigned elsewhere). - */ -void -hifn_reset_board(struct hifn_softc *sc, int full) -{ - u_int32_t reg; - - /* - * Set polling in the DMA configuration register to zero. 0x7 avoids - * resetting the board and zeros out the other fields. - */ - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - - /* - * Now that polling has been disabled, we have to wait 1 ms - * before resetting the board. - */ - DELAY(1000); - - /* Reset the DMA unit */ - if (full) { - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE); - DELAY(1000); - } else { - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, - HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET); - hifn_reset_puc(sc); - } - - bzero(sc->sc_dma, sizeof(*sc->sc_dma)); - - /* Bring dma unit out of reset */ - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - - hifn_puc_wait(sc); - - hifn_set_retry(sc); - - if (sc->sc_flags & HIFN_IS_7811) { - for (reg = 0; reg < 1000; reg++) { - if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) & - HIFN_MIPSRST_CRAMINIT) - break; - DELAY(1000); - } - if (reg == 1000) - printf(": cram init timeout\n"); - } -} - -u_int32_t -hifn_next_signature(u_int32_t a, u_int cnt) -{ - int i; - u_int32_t v; - - for (i = 0; i < cnt; i++) { - - /* get the parity */ - v = a & 0x80080125; - v ^= v >> 16; - v ^= v >> 8; - v ^= v >> 4; - v ^= v >> 2; - v ^= v >> 1; - - a = (v & 1) ^ (a << 1); - } - - return a; -} - -struct pci2id { - u_short pci_vendor; - u_short pci_prod; - char card_id[13]; -} pci2id[] = { - { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7951, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7955, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7956, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_NETSEC, - PCI_PRODUCT_NETSEC_7751, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_INVERTEX, - PCI_PRODUCT_INVERTEX_AEON, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7811, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - /* - * Other vendors share this PCI ID as well, such as - * powercrypt, and obviously they also - * use the same key. - */ - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7751, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, -}; - -/* - * Checks to see if crypto is already enabled. If crypto isn't enable, - * "hifn_enable_crypto" is called to enable it. The check is important, - * as enabling crypto twice will lock the board. - */ -int -hifn_enable_crypto(struct hifn_softc *sc, pcireg_t pciid) -{ - u_int32_t dmacfg, ramcfg, encl, addr, i; - char *offtbl = NULL; - - for (i = 0; i < nitems(pci2id); i++) { - if (pci2id[i].pci_vendor == PCI_VENDOR(pciid) && - pci2id[i].pci_prod == PCI_PRODUCT(pciid)) { - offtbl = pci2id[i].card_id; - break; - } - } - - if (offtbl == NULL) { -#ifdef HIFN_DEBUG - printf(": Unknown card!\n"); -#endif - return (1); - } - - ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG); - dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG); - - /* - * The RAM config register's encrypt level bit needs to be set before - * every read performed on the encryption level register. - */ - WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID); - - encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA; - - /* - * Make sure we don't re-unlock. Two unlocks kills chip until the - * next reboot. - */ - if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) { -#ifdef HIFN_DEBUG - printf(": Strong Crypto already enabled!\n"); -#endif - goto report; - } - - if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) { -#ifdef HIFN_DEBUG - printf(": Unknown encryption level\n"); -#endif - return 1; - } - - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK | - HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - DELAY(1000); - addr = READ_REG_1(sc, HIFN_1_UNLOCK_SECRET1); - DELAY(1000); - WRITE_REG_1(sc, HIFN_1_UNLOCK_SECRET2, 0); - DELAY(1000); - - for (i = 0; i <= 12; i++) { - addr = hifn_next_signature(addr, offtbl[i] + 0x101); - WRITE_REG_1(sc, HIFN_1_UNLOCK_SECRET2, addr); - - DELAY(1000); - } - - WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID); - encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA; - -#ifdef HIFN_DEBUG - if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2) - printf(": engine is permanently locked until next system reset"); - else - printf(": engine enabled successfully!"); -#endif - -report: - WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg); - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg); - - switch (encl) { - case HIFN_PUSTAT_ENA_0: - offtbl = "LZS"; - break; - case HIFN_PUSTAT_ENA_1: - offtbl = "LZS DES"; - break; - case HIFN_PUSTAT_ENA_2: - offtbl = "LZS 3DES ARC4 MD5 SHA1"; - break; - default: - offtbl = "disabled"; - break; - } - printf(": %s", offtbl); - if (sc->sc_flags & HIFN_HAS_RNG) - printf(" RNG"); - if (sc->sc_flags & HIFN_HAS_AES) - printf(" AES"); - if (sc->sc_flags & HIFN_HAS_PUBLIC) - printf(" PK"); - printf(", "); - - return (0); -} - -/* - * Give initial values to the registers listed in the "Register Space" - * section of the HIFN Software Development reference manual. - */ -void -hifn_init_pci_registers(struct hifn_softc *sc) -{ - /* write fixed values needed by the Initialization registers */ - WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA); - WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD); - WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER); - - /* write all 4 ring address registers */ - WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, cmdr[0])); - WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, srcr[0])); - WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, dstr[0])); - WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, resr[0])); - - DELAY(2000); - - /* write status register */ - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS | - HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS | - HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST | - HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER | - HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST | - HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER | - HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST | - HIFN_DMACSR_S_WAIT | - HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST | - HIFN_DMACSR_C_WAIT | - HIFN_DMACSR_ENGINE | - ((sc->sc_flags & HIFN_HAS_PUBLIC) ? - HIFN_DMACSR_PUBDONE : 0) | - ((sc->sc_flags & HIFN_IS_7811) ? - HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0)); - - sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0; - sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT | - HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER | - HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT | - HIFN_DMAIER_ENGINE | - ((sc->sc_flags & HIFN_IS_7811) ? - HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0); - sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - CLR_LED(sc, HIFN_MIPSRST_LED0 | HIFN_MIPSRST_LED1 | HIFN_MIPSRST_LED2); - - if (sc->sc_flags & HIFN_IS_7956) { - WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | - HIFN_PUCNFG_TCALLPHASES | - HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32); - WRITE_REG_1(sc, HIFN_1_PLL, HIFN_PLL_7956); - } else { - WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | - HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES | - HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 | - (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM)); - } - - WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER); - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST | - ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) | - ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL)); -} - -/* - * The maximum number of sessions supported by the card - * is dependent on the amount of context ram, which - * encryption algorithms are enabled, and how compression - * is configured. This should be configured before this - * routine is called. - */ -void -hifn_sessions(struct hifn_softc *sc) -{ - u_int32_t pucnfg; - int ctxsize; - - pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG); - - if (pucnfg & HIFN_PUCNFG_COMPSING) { - if (pucnfg & HIFN_PUCNFG_ENCCNFG) - ctxsize = 128; - else - ctxsize = 512; - /* - * 7955/7956 has internal context memory of 32K - */ - if (sc->sc_flags & HIFN_IS_7956) - sc->sc_maxses = 32768 / ctxsize; - else - sc->sc_maxses = 1 + - ((sc->sc_ramsize - 32768) / ctxsize); - } - else - sc->sc_maxses = sc->sc_ramsize / 16384; - - if (sc->sc_maxses > 2048) - sc->sc_maxses = 2048; -} - -/* - * Determine ram type (sram or dram). Board should be just out of a reset - * state when this is called. - */ -int -hifn_ramtype(struct hifn_softc *sc) -{ - u_int8_t data[8], dataexpect[8]; - int i; - - for (i = 0; i < sizeof(data); i++) - data[i] = dataexpect[i] = 0x55; - if (hifn_writeramaddr(sc, 0, data)) - return (-1); - if (hifn_readramaddr(sc, 0, data)) - return (-1); - if (bcmp(data, dataexpect, sizeof(data)) != 0) { - sc->sc_drammodel = 1; - return (0); - } - - for (i = 0; i < sizeof(data); i++) - data[i] = dataexpect[i] = 0xaa; - if (hifn_writeramaddr(sc, 0, data)) - return (-1); - if (hifn_readramaddr(sc, 0, data)) - return (-1); - if (bcmp(data, dataexpect, sizeof(data)) != 0) { - sc->sc_drammodel = 1; - return (0); - } - - return (0); -} - -#define HIFN_SRAM_MAX (32 << 20) -#define HIFN_SRAM_STEP_SIZE 16384 -#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE) - -int -hifn_sramsize(struct hifn_softc *sc) -{ - u_int32_t a; - u_int8_t data[8]; - u_int8_t dataexpect[sizeof(data)]; - int32_t i; - - for (i = 0; i < sizeof(data); i++) - data[i] = dataexpect[i] = i ^ 0x5a; - - for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) { - a = i * HIFN_SRAM_STEP_SIZE; - bcopy(&i, data, sizeof(i)); - hifn_writeramaddr(sc, a, data); - } - - for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) { - a = i * HIFN_SRAM_STEP_SIZE; - bcopy(&i, dataexpect, sizeof(i)); - if (hifn_readramaddr(sc, a, data) < 0) - return (0); - if (bcmp(data, dataexpect, sizeof(data)) != 0) - return (0); - sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE; - } - - return (0); -} - -/* - * XXX For dram boards, one should really try all of the - * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG - * is already set up correctly. - */ -int -hifn_dramsize(struct hifn_softc *sc) -{ - u_int32_t cnfg; - - if (sc->sc_flags & HIFN_IS_7956) { - /* - * 7956/7956 have a fixed internal ram of only 32K. - */ - sc->sc_ramsize = 32768; - } else { - cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) & - HIFN_PUCNFG_DRAMMASK; - sc->sc_ramsize = 1 << ((cnfg >> 13) + 18); - } - return (0); -} - -void -hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, - int *dstp, int *resp) -{ - struct hifn_dma *dma = sc->sc_dma; - - if (dma->cmdi == HIFN_D_CMD_RSIZE) { - dma->cmdi = 0; - dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *cmdp = dma->cmdi++; - dma->cmdk = dma->cmdi; - - if (dma->srci == HIFN_D_SRC_RSIZE) { - dma->srci = 0; - dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *srcp = dma->srci++; - dma->srck = dma->srci; - - if (dma->dsti == HIFN_D_DST_RSIZE) { - dma->dsti = 0; - dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *dstp = dma->dsti++; - dma->dstk = dma->dsti; - - if (dma->resi == HIFN_D_RES_RSIZE) { - dma->resi = 0; - dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *resp = dma->resi++; - dma->resk = dma->resi; -} - -int -hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data) -{ - struct hifn_dma *dma = sc->sc_dma; - struct hifn_base_command wc; - const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ; - int r, cmdi, resi, srci, dsti; - - wc.masks = htole16(3 << 13); - wc.session_num = htole16(addr >> 14); - wc.total_source_count = htole16(8); - wc.total_dest_count = htole16(addr & 0x3fff); - - hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi); - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA | - HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA); - - /* build write command */ - bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND); - *(struct hifn_base_command *)dma->command_bufs[cmdi] = wc; - bcopy(data, &dma->test_src, sizeof(dma->test_src)); - - dma->srcr[srci].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr - + offsetof(struct hifn_dma, test_src)); - dma->dstr[dsti].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr - + offsetof(struct hifn_dma, test_dst)); - - dma->cmdr[cmdi].l = htole32(16 | masks); - dma->srcr[srci].l = htole32(8 | masks); - dma->dstr[dsti].l = htole32(4 | masks); - dma->resr[resi].l = htole32(4 | masks); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - for (r = 10000; r >= 0; r--) { - DELAY(10); - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0) - break; - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - if (r == 0) { - printf("%s: writeramaddr -- " - "result[%d](addr %d) still valid\n", - sc->sc_dv.dv_xname, resi, addr); - - return (-1); - } else - r = 0; - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS | - HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS); - - return (r); -} - -int -hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data) -{ - struct hifn_dma *dma = sc->sc_dma; - struct hifn_base_command rc; - const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ; - int r, cmdi, srci, dsti, resi; - - rc.masks = htole16(2 << 13); - rc.session_num = htole16(addr >> 14); - rc.total_source_count = htole16(addr & 0x3fff); - rc.total_dest_count = htole16(8); - - hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi); - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA | - HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA); - - bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND); - *(struct hifn_base_command *)dma->command_bufs[cmdi] = rc; - - dma->srcr[srci].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, test_src)); - dma->test_src = 0; - dma->dstr[dsti].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, test_dst)); - dma->test_dst = 0; - dma->cmdr[cmdi].l = htole32(8 | masks); - dma->srcr[srci].l = htole32(8 | masks); - dma->dstr[dsti].l = htole32(8 | masks); - dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - for (r = 10000; r >= 0; r--) { - DELAY(10); - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0) - break; - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - if (r == 0) { - printf("%s: readramaddr -- " - "result[%d](addr %d) still valid\n", - sc->sc_dv.dv_xname, resi, addr); - r = -1; - } else { - r = 0; - bcopy(&dma->test_dst, data, sizeof(dma->test_dst)); - } - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS | - HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS); - - return (r); -} - -/* - * Initialize the descriptor rings. - */ -void -hifn_init_dma(struct hifn_softc *sc) -{ - struct hifn_dma *dma = sc->sc_dma; - int i; - - hifn_set_retry(sc); - - /* initialize static pointer values */ - for (i = 0; i < HIFN_D_CMD_RSIZE; i++) - dma->cmdr[i].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, command_bufs[i][0])); - for (i = 0; i < HIFN_D_RES_RSIZE; i++) - dma->resr[i].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, result_bufs[i][0])); - - dma->cmdr[HIFN_D_CMD_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, cmdr[0])); - dma->srcr[HIFN_D_SRC_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, srcr[0])); - dma->dstr[HIFN_D_DST_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, dstr[0])); - dma->resr[HIFN_D_RES_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, resr[0])); - - dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0; - dma->cmdi = dma->srci = dma->dsti = dma->resi = 0; - dma->cmdk = dma->srck = dma->dstk = dma->resk = 0; -} - -/* - * Writes out the raw command buffer space. Returns the - * command buffer size. - */ -u_int -hifn_write_command(struct hifn_command *cmd, u_int8_t *buf) -{ - u_int8_t *buf_pos; - struct hifn_base_command *base_cmd; - struct hifn_mac_command *mac_cmd; - struct hifn_crypt_command *cry_cmd; - struct hifn_comp_command *comp_cmd; - int using_mac, using_crypt, using_comp, len, ivlen; - u_int32_t dlen, slen; - - buf_pos = buf; - using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC; - using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT; - using_comp = cmd->base_masks & HIFN_BASE_CMD_COMP; - - base_cmd = (struct hifn_base_command *)buf_pos; - base_cmd->masks = htole16(cmd->base_masks); - slen = cmd->src_map->dm_mapsize; - if (cmd->sloplen) - dlen = cmd->dst_map->dm_mapsize - cmd->sloplen + - sizeof(u_int32_t); - else - dlen = cmd->dst_map->dm_mapsize; - base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO); - base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO); - dlen >>= 16; - slen >>= 16; - base_cmd->session_num = htole16( - ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) | - ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M)); - buf_pos += sizeof(struct hifn_base_command); - - if (using_comp) { - comp_cmd = (struct hifn_comp_command *)buf_pos; - dlen = cmd->compcrd->crd_len; - comp_cmd->source_count = htole16(dlen & 0xffff); - dlen >>= 16; - comp_cmd->masks = htole16(cmd->comp_masks | - ((dlen << HIFN_COMP_CMD_SRCLEN_S) & HIFN_COMP_CMD_SRCLEN_M)); - comp_cmd->header_skip = htole16(cmd->compcrd->crd_skip); - comp_cmd->reserved = 0; - buf_pos += sizeof(struct hifn_comp_command); - } - - if (using_mac) { - mac_cmd = (struct hifn_mac_command *)buf_pos; - dlen = cmd->maccrd->crd_len; - mac_cmd->source_count = htole16(dlen & 0xffff); - dlen >>= 16; - mac_cmd->masks = htole16(cmd->mac_masks | - ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M)); - mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip); - mac_cmd->reserved = 0; - buf_pos += sizeof(struct hifn_mac_command); - } - - if (using_crypt) { - cry_cmd = (struct hifn_crypt_command *)buf_pos; - dlen = cmd->enccrd->crd_len; - cry_cmd->source_count = htole16(dlen & 0xffff); - dlen >>= 16; - cry_cmd->masks = htole16(cmd->cry_masks | - ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M)); - cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip); - cry_cmd->reserved = 0; - buf_pos += sizeof(struct hifn_crypt_command); - } - - if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) { - bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH); - buf_pos += HIFN_MAC_KEY_LENGTH; - } - - if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) { - switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) { - case HIFN_CRYPT_CMD_ALG_3DES: - bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH); - buf_pos += HIFN_3DES_KEY_LENGTH; - break; - case HIFN_CRYPT_CMD_ALG_DES: - bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH); - buf_pos += HIFN_DES_KEY_LENGTH; - break; - case HIFN_CRYPT_CMD_ALG_RC4: - len = 256; - do { - int clen; - - clen = MIN(cmd->cklen, len); - bcopy(cmd->ck, buf_pos, clen); - len -= clen; - buf_pos += clen; - } while (len > 0); - bzero(buf_pos, 4); - buf_pos += 4; - break; - case HIFN_CRYPT_CMD_ALG_AES: - /* - * AES key are variable 128, 192 and - * 256 bits (16, 24 and 32 bytes). - */ - bcopy(cmd->ck, buf_pos, cmd->cklen); - buf_pos += cmd->cklen; - break; - } - } - - if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) { - if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == - HIFN_CRYPT_CMD_ALG_AES) - ivlen = HIFN_AES_IV_LENGTH; - else - ivlen = HIFN_IV_LENGTH; - bcopy(cmd->iv, buf_pos, ivlen); - buf_pos += ivlen; - } - - if ((cmd->base_masks & (HIFN_BASE_CMD_MAC | HIFN_BASE_CMD_CRYPT | - HIFN_BASE_CMD_COMP)) == 0) { - bzero(buf_pos, 8); - buf_pos += 8; - } - - return (buf_pos - buf); -} - -int -hifn_dmamap_aligned(bus_dmamap_t map) -{ - int i; - - for (i = 0; i < map->dm_nsegs; i++) { - if (map->dm_segs[i].ds_addr & 3) - return (0); - if ((i != (map->dm_nsegs - 1)) && - (map->dm_segs[i].ds_len & 3)) - return (0); - } - return (1); -} - -int -hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd) -{ - struct hifn_dma *dma = sc->sc_dma; - bus_dmamap_t map = cmd->dst_map; - u_int32_t p, l; - int idx, used = 0, i; - - idx = dma->dsti; - for (i = 0; i < map->dm_nsegs - 1; i++) { - dma->dstr[idx].p = htole32(map->dm_segs[i].ds_addr); - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | map->dm_segs[i].ds_len); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - used++; - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - idx = 0; - } - } - - if (cmd->sloplen == 0) { - p = map->dm_segs[i].ds_addr; - l = HIFN_D_VALID | HIFN_D_MASKDONEIRQ | HIFN_D_LAST | - map->dm_segs[i].ds_len; - } else { - p = sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, slop[cmd->slopidx]); - l = HIFN_D_VALID | HIFN_D_MASKDONEIRQ | HIFN_D_LAST | - sizeof(u_int32_t); - - if ((map->dm_segs[i].ds_len - cmd->sloplen) != 0) { - dma->dstr[idx].p = htole32(map->dm_segs[i].ds_addr); - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | - (map->dm_segs[i].ds_len - cmd->sloplen)); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - used++; - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - idx = 0; - } - } - } - dma->dstr[idx].p = htole32(p); - dma->dstr[idx].l = htole32(l); - HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - used++; - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP | - HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - idx = 0; - } - - dma->dsti = idx; - dma->dstu += used; - return (idx); -} - -int -hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd) -{ - struct hifn_dma *dma = sc->sc_dma; - bus_dmamap_t map = cmd->src_map; - int idx, i; - u_int32_t last = 0; - - idx = dma->srci; - for (i = 0; i < map->dm_nsegs; i++) { - if (i == map->dm_nsegs - 1) - last = HIFN_D_LAST; - - dma->srcr[idx].p = htole32(map->dm_segs[i].ds_addr); - dma->srcr[idx].l = htole32(map->dm_segs[i].ds_len | - HIFN_D_VALID | HIFN_D_MASKDONEIRQ | last); - HIFN_SRCR_SYNC(sc, idx, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - - if (++idx == HIFN_D_SRC_RSIZE) { - dma->srcr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - idx = 0; - } - } - dma->srci = idx; - dma->srcu += map->dm_nsegs; - return (idx); -} - -int -hifn_crypto(struct hifn_softc *sc, struct hifn_command *cmd, - struct cryptop *crp) -{ - struct hifn_dma *dma = sc->sc_dma; - u_int32_t cmdlen; - int cmdi, resi, s, err = 0; - - if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map)) - return (ENOMEM); - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_srcmap1; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_srcmap1; - } - } else { - err = EINVAL; - goto err_srcmap1; - } - - if (hifn_dmamap_aligned(cmd->src_map)) { - cmd->sloplen = cmd->src_map->dm_mapsize & 3; - if (crp->crp_flags & CRYPTO_F_IOV) - cmd->dstu.dst_io = cmd->srcu.src_io; - else if (crp->crp_flags & CRYPTO_F_IMBUF) - cmd->dstu.dst_m = cmd->srcu.src_m; - cmd->dst_map = cmd->src_map; - } else { - if (crp->crp_flags & CRYPTO_F_IOV) { - err = EINVAL; - goto err_srcmap; - } else if (crp->crp_flags & CRYPTO_F_IMBUF) { - int totlen, len; - struct mbuf *m, *m0, *mlast; - - totlen = cmd->src_map->dm_mapsize; - if (cmd->srcu.src_m->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m0, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m0, M_DONTWAIT, MT_DATA); - } - if (m0 == NULL) { - err = ENOMEM; - goto err_srcmap; - } - if (len == MHLEN) { - err = m_dup_pkthdr(m0, cmd->srcu.src_m, - M_DONTWAIT); - if (err) { - m_free(m0); - goto err_srcmap; - } - } - if (totlen >= MINCLSIZE) { - MCLGET(m0, M_DONTWAIT); - if (m0->m_flags & M_EXT) - len = MCLBYTES; - } - totlen -= len; - m0->m_pkthdr.len = m0->m_len = len; - mlast = m0; - - while (totlen > 0) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - err = ENOMEM; - m_freem(m0); - goto err_srcmap; - } - len = MLEN; - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) - len = MCLBYTES; - } - - m->m_len = len; - if (m0->m_flags & M_PKTHDR) - m0->m_pkthdr.len += len; - totlen -= len; - - mlast->m_next = m; - mlast = m; - } - cmd->dstu.dst_m = m0; - } - } - - if (cmd->dst_map == NULL) { - if (bus_dmamap_create(sc->sc_dmat, - HIFN_MAX_SEGLEN * MAX_SCATTER, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->dst_map)) { - err = ENOMEM; - goto err_srcmap; - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_dstmap1; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_dstmap1; - } - } - } - -#ifdef HIFN_DEBUG - printf("%s: Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n", - sc->sc_dv.dv_xname, - READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER), - dma->cmdu, dma->srcu, dma->dstu, dma->resu, - cmd->src_map->dm_nsegs, cmd->dst_map->dm_nsegs); -#endif - - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - } - - s = splnet(); - - /* - * need 1 cmd, and 1 res - * need N src, and N dst - */ - if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE || - (dma->resu + 1) > HIFN_D_RES_RSIZE) { - splx(s); - err = ENOMEM; - goto err_dstmap; - } - if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE || - (dma->dstu + cmd->dst_map->dm_nsegs + 1) > HIFN_D_DST_RSIZE) { - splx(s); - err = ENOMEM; - goto err_dstmap; - } - - if (dma->cmdi == HIFN_D_CMD_RSIZE) { - dma->cmdi = 0; - dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - cmdi = dma->cmdi++; - cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]); - HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE); - - /* .p for command/result already set */ - dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_VALID | HIFN_D_LAST | - HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, cmdi, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - dma->cmdu++; - if (sc->sc_c_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); - sc->sc_c_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED0); - } - - /* - * Always enable the command wait interrupt. We are obviously - * missing an interrupt or two somewhere. Enabling the command wait - * interrupt will guarantee we get called periodically until all - * of the queues are drained and thus work around this. - */ - sc->sc_dmaier |= HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - - hifnstats.hst_ipackets++; - hifnstats.hst_ibytes += cmd->src_map->dm_mapsize; - - hifn_dmamap_load_src(sc, cmd); - if (sc->sc_s_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); - sc->sc_s_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED1); - } - - /* - * Unlike other descriptors, we don't mask done interrupt from - * result descriptor. - */ -#ifdef HIFN_DEBUG - printf("load res\n"); -#endif - if (dma->resi == HIFN_D_RES_RSIZE) { - dma->resi = 0; - dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - resi = dma->resi++; - dma->hifn_commands[resi] = cmd; - HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD); - dma->resr[resi].l = htole32(HIFN_MAX_RESULT | - HIFN_D_VALID | HIFN_D_LAST); - HIFN_RESR_SYNC(sc, resi, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - dma->resu++; - if (sc->sc_r_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA); - sc->sc_r_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED2); - } - - if (cmd->sloplen) - cmd->slopidx = resi; - - hifn_dmamap_load_dst(sc, cmd); - - if (sc->sc_d_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); - sc->sc_d_busy = 1; - } - -#ifdef HIFN_DEBUG - printf("%s: command: stat %8x ier %8x\n", - sc->sc_dv.dv_xname, - READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER)); -#endif - - sc->sc_active = 5; - cmd->cmd_callback = hifn_callback; - splx(s); - return (err); /* success */ - -err_dstmap: - if (cmd->src_map != cmd->dst_map) - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); -err_dstmap1: - if (cmd->src_map != cmd->dst_map) - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); -err_srcmap: - if (crp->crp_flags & CRYPTO_F_IMBUF && - cmd->srcu.src_m != cmd->dstu.dst_m) - m_freem(cmd->dstu.dst_m); - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); -err_srcmap1: - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - return (err); -} - -void -hifn_tick(void *vsc) -{ - struct hifn_softc *sc = vsc; - int s; - - s = splnet(); - if (sc->sc_active == 0) { - struct hifn_dma *dma = sc->sc_dma; - u_int32_t r = 0; - - if (dma->cmdu == 0 && sc->sc_c_busy) { - sc->sc_c_busy = 0; - r |= HIFN_DMACSR_C_CTRL_DIS; - CLR_LED(sc, HIFN_MIPSRST_LED0); - } - if (dma->srcu == 0 && sc->sc_s_busy) { - sc->sc_s_busy = 0; - r |= HIFN_DMACSR_S_CTRL_DIS; - CLR_LED(sc, HIFN_MIPSRST_LED1); - } - if (dma->dstu == 0 && sc->sc_d_busy) { - sc->sc_d_busy = 0; - r |= HIFN_DMACSR_D_CTRL_DIS; - } - if (dma->resu == 0 && sc->sc_r_busy) { - sc->sc_r_busy = 0; - r |= HIFN_DMACSR_R_CTRL_DIS; - CLR_LED(sc, HIFN_MIPSRST_LED2); - } - if (r) - WRITE_REG_1(sc, HIFN_1_DMA_CSR, r); - } - else - sc->sc_active--; - splx(s); - timeout_add_sec(&sc->sc_tickto, 1); -} - -int -hifn_intr(void *arg) -{ - struct hifn_softc *sc = arg; - struct hifn_dma *dma = sc->sc_dma; - u_int32_t dmacsr, restart; - int i, u; - - dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR); - -#ifdef HIFN_DEBUG - printf("%s: irq: stat %08x ien %08x u %d/%d/%d/%d\n", - sc->sc_dv.dv_xname, - dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), - dma->cmdu, dma->srcu, dma->dstu, dma->resu); -#endif - - /* Nothing in the DMA unit interrupted */ - if ((dmacsr & sc->sc_dmaier) == 0) - return (0); - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier); - - if (dmacsr & HIFN_DMACSR_ENGINE) - WRITE_REG_0(sc, HIFN_0_PUISR, READ_REG_0(sc, HIFN_0_PUISR)); - - if ((sc->sc_flags & HIFN_HAS_PUBLIC) && - (dmacsr & HIFN_DMACSR_PUBDONE)) - WRITE_REG_1(sc, HIFN_1_PUB_STATUS, - READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE); - - restart = dmacsr & (HIFN_DMACSR_R_OVER | HIFN_DMACSR_D_OVER); - if (restart) - printf("%s: overrun %x\n", sc->sc_dv.dv_xname, dmacsr); - - if (sc->sc_flags & HIFN_IS_7811) { - if (dmacsr & HIFN_DMACSR_ILLR) - printf("%s: illegal read\n", sc->sc_dv.dv_xname); - if (dmacsr & HIFN_DMACSR_ILLW) - printf("%s: illegal write\n", sc->sc_dv.dv_xname); - } - - restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT | - HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT); - if (restart) { - printf("%s: abort, resetting.\n", sc->sc_dv.dv_xname); - hifnstats.hst_abort++; - hifn_abort(sc); - return (1); - } - - if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->resu == 0)) { - /* - * If no slots to process and we receive a "waiting on - * command" interrupt, we disable the "waiting on command" - * (by clearing it). - */ - sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - } - - /* clear the rings */ - i = dma->resk; - while (dma->resu != 0) { - HIFN_RESR_SYNC(sc, i, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->resr[i].l & htole32(HIFN_D_VALID)) { - HIFN_RESR_SYNC(sc, i, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - - if (i != HIFN_D_RES_RSIZE) { - struct hifn_command *cmd; - - HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD); - cmd = dma->hifn_commands[i]; - - (*cmd->cmd_callback)(sc, cmd, dma->result_bufs[i]); - hifnstats.hst_opackets++; - } - - if (++i == (HIFN_D_RES_RSIZE + 1)) - i = 0; - else - dma->resu--; - } - dma->resk = i; - - i = dma->srck; u = dma->srcu; - while (u != 0) { - HIFN_SRCR_SYNC(sc, i, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->srcr[i].l & htole32(HIFN_D_VALID)) { - HIFN_SRCR_SYNC(sc, i, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (++i == (HIFN_D_SRC_RSIZE + 1)) - i = 0; - else - u--; - } - dma->srck = i; dma->srcu = u; - - i = dma->cmdk; u = dma->cmdu; - while (u != 0) { - HIFN_CMDR_SYNC(sc, i, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) { - HIFN_CMDR_SYNC(sc, i, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (i != HIFN_D_CMD_RSIZE) { - u--; - HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE); - } - if (++i == (HIFN_D_CMD_RSIZE + 1)) - i = 0; - } - dma->cmdk = i; dma->cmdu = u; - - return (1); -} - -/* - * Allocate a new 'session' and return an encoded session id. 'sidp' - * contains our registration id, and should contain an encoded session - * id on successful allocation. - */ -int -hifn_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct cryptoini *c; - struct hifn_softc *sc = NULL; - int i, mac = 0, cry = 0, comp = 0, sesn; - struct hifn_session *ses = NULL; - - if (sidp == NULL || cri == NULL) - return (EINVAL); - - for (i = 0; i < hifn_cd.cd_ndevs; i++) { - sc = hifn_cd.cd_devs[i]; - if (sc == NULL) - break; - if (sc->sc_cid == (*sidp)) - break; - } - if (sc == NULL) - return (EINVAL); - - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct hifn_session *)malloc( - sizeof(*ses), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - sesn = 0; - sc->sc_nsessions = 1; - } else { - for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { - if (!sc->sc_sessions[sesn].hs_used) { - ses = &sc->sc_sessions[sesn]; - break; - } - } - - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = mallocarray((sesn + 1), sizeof(*ses), - M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses)); - explicit_bzero(sc->sc_sessions, sesn * sizeof(*ses)); - free(sc->sc_sessions, M_DEVBUF, 0); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - bzero(ses, sizeof(*ses)); - - for (c = cri; c != NULL; c = c->cri_next) { - switch (c->cri_alg) { - case CRYPTO_MD5_HMAC: - case CRYPTO_SHA1_HMAC: - if (mac) - return (EINVAL); - mac = 1; - break; - case CRYPTO_3DES_CBC: - case CRYPTO_AES_CBC: - if (cry) - return (EINVAL); - cry = 1; - break; - case CRYPTO_LZS_COMP: - if (comp) - return (EINVAL); - comp = 1; - break; - default: - return (EINVAL); - } - } - if (mac == 0 && cry == 0 && comp == 0) - return (EINVAL); - - /* - * XXX only want to support compression without chaining to - * MAC/crypt engine right now - */ - if ((comp && mac) || (comp && cry)) - return (EINVAL); - - *sidp = HIFN_SID(sc->sc_dv.dv_unit, sesn); - ses->hs_used = 1; - - return (0); -} - -/* - * Deallocate a session. - * XXX this routine should run a zero'd mac/encrypt key into context ram. - * XXX to blow away any keys already stored there. - */ -int -hifn_freesession(u_int64_t tid) -{ - struct hifn_softc *sc; - int card, session; - u_int32_t sid = ((u_int32_t)tid) & 0xffffffff; - - card = HIFN_CARD(sid); - if (card >= hifn_cd.cd_ndevs || hifn_cd.cd_devs[card] == NULL) - return (EINVAL); - - sc = hifn_cd.cd_devs[card]; - session = HIFN_SESSION(sid); - if (session >= sc->sc_nsessions) - return (EINVAL); - - bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session])); - return (0); -} - -int -hifn_process(struct cryptop *crp) -{ - struct hifn_command *cmd = NULL; - int card, session, err = 0, ivlen; - struct hifn_softc *sc; - struct cryptodesc *crd1, *crd2 = NULL, *maccrd, *enccrd; - - if (crp->crp_ilen == 0) { - err = EINVAL; - goto errout; - } - - card = HIFN_CARD(crp->crp_sid); - if (card >= hifn_cd.cd_ndevs || hifn_cd.cd_devs[card] == NULL) { - err = EINVAL; - goto errout; - } - - sc = hifn_cd.cd_devs[card]; - session = HIFN_SESSION(crp->crp_sid); - if (session >= sc->sc_nsessions) { - err = EINVAL; - goto errout; - } - - cmd = malloc(sizeof(*cmd), M_DEVBUF, M_NOWAIT | M_ZERO); - if (cmd == NULL) { - err = ENOMEM; - goto errout; - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - cmd->srcu.src_m = (struct mbuf *)crp->crp_buf; - cmd->dstu.dst_m = (struct mbuf *)crp->crp_buf; - } else if (crp->crp_flags & CRYPTO_F_IOV) { - cmd->srcu.src_io = (struct uio *)crp->crp_buf; - cmd->dstu.dst_io = (struct uio *)crp->crp_buf; - } else { - err = EINVAL; - goto errout; /* XXX we don't handle contiguous buffers! */ - } - - if (crp->crp_ndesc < 1) { - err = EINVAL; - goto errout; - } - crd1 = &crp->crp_desc[0]; - if (crp->crp_ndesc >= 2) - crd2 = &crp->crp_desc[1]; - - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) { - maccrd = crd1; - enccrd = NULL; - } else if (crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) { - if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0) - cmd->base_masks |= HIFN_BASE_CMD_DECODE; - maccrd = NULL; - enccrd = crd1; - } else if (crd1->crd_alg == CRYPTO_LZS_COMP) { - return (hifn_compression(sc, crp, cmd)); - } else { - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) && - (crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC) && - ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { - cmd->base_masks = HIFN_BASE_CMD_DECODE; - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - /* - * We cannot order the 7751 as requested - */ - err = EINVAL; - goto errout; - } - } - - if (enccrd) { - cmd->enccrd = enccrd; - cmd->base_masks |= HIFN_BASE_CMD_CRYPT; - switch (enccrd->crd_alg) { - case CRYPTO_3DES_CBC: - cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES | - HIFN_CRYPT_CMD_MODE_CBC | - HIFN_CRYPT_CMD_NEW_IV; - break; - case CRYPTO_AES_CBC: - cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES | - HIFN_CRYPT_CMD_MODE_CBC | - HIFN_CRYPT_CMD_NEW_IV; - break; - default: - err = EINVAL; - goto errout; - } - ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ? - HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); - if (enccrd->crd_flags & CRD_F_ENCRYPT) { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, cmd->iv, ivlen); - else - arc4random_buf(cmd->iv, ivlen); - - if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - err = m_copyback(cmd->srcu.src_m, - enccrd->crd_inject, - ivlen, cmd->iv, M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback(cmd->srcu.src_io, - enccrd->crd_inject, - ivlen, cmd->iv); - if (err) - goto errout; - } - } else { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, cmd->iv, ivlen); - else if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata(cmd->srcu.src_m, - enccrd->crd_inject, ivlen, cmd->iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata(cmd->srcu.src_io, - enccrd->crd_inject, ivlen, cmd->iv); - } - - cmd->ck = enccrd->crd_key; - cmd->cklen = enccrd->crd_klen >> 3; - cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY; - - /* - * Need to specify the size for the AES key in the masks. - */ - if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == - HIFN_CRYPT_CMD_ALG_AES) { - switch (cmd->cklen) { - case 16: - cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128; - break; - case 24: - cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192; - break; - case 32: - cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256; - break; - default: - err = EINVAL; - goto errout; - } - } - } - - if (maccrd) { - cmd->maccrd = maccrd; - cmd->base_masks |= HIFN_BASE_CMD_MAC; - - switch (maccrd->crd_alg) { - case CRYPTO_MD5_HMAC: - cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 | - HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC | - HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC; - break; - case CRYPTO_SHA1_HMAC: - cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 | - HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC | - HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC; - break; - } - - if (maccrd->crd_alg == CRYPTO_SHA1_HMAC || - maccrd->crd_alg == CRYPTO_MD5_HMAC) { - cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY; - bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3); - bzero(cmd->mac + (maccrd->crd_klen >> 3), - HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3)); - } - } - - cmd->crp = crp; - cmd->session_num = session; - cmd->softc = sc; - - err = hifn_crypto(sc, cmd, crp); - if (!err) - return 0; - -errout: - if (cmd != NULL) { - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - } - if (err == EINVAL) - hifnstats.hst_invalid++; - else - hifnstats.hst_nomem++; - crp->crp_etype = err; - crypto_done(crp); - return (0); -} - -void -hifn_abort(struct hifn_softc *sc) -{ - struct hifn_dma *dma = sc->sc_dma; - struct hifn_command *cmd; - struct cryptop *crp; - int i, u; - - i = dma->resk; u = dma->resu; - while (u != 0) { - cmd = dma->hifn_commands[i]; - crp = cmd->crp; - - if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) { - /* Salvage what we can. */ - hifnstats.hst_opackets++; - (*cmd->cmd_callback)(sc, cmd, dma->result_bufs[i]); - } else { - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, - BUS_DMASYNC_POSTREAD); - } - - if (cmd->srcu.src_m != cmd->dstu.dst_m) { - m_freem(cmd->srcu.src_m); - crp->crp_buf = (caddr_t)cmd->dstu.dst_m; - } - - /* non-shared buffers cannot be restarted */ - if (cmd->src_map != cmd->dst_map) { - /* - * XXX should be EAGAIN, delayed until - * after the reset. - */ - crp->crp_etype = ENOMEM; - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } else - crp->crp_etype = ENOMEM; - - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - if (crp->crp_etype != EAGAIN) - crypto_done(crp); - } - - if (++i == HIFN_D_RES_RSIZE) - i = 0; - u--; - } - dma->resk = i; dma->resu = u; - - hifn_reset_board(sc, 1); - hifn_init_dma(sc); - hifn_init_pci_registers(sc); -} - -void -hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, - u_int8_t *resbuf) -{ - struct hifn_dma *dma = sc->sc_dma; - struct cryptop *crp = cmd->crp; - struct cryptodesc *crd; - struct mbuf *m; - int totlen, i, u; - - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (cmd->srcu.src_m != cmd->dstu.dst_m) { - crp->crp_buf = (caddr_t)cmd->dstu.dst_m; - totlen = cmd->src_map->dm_mapsize; - for (m = cmd->dstu.dst_m; m != NULL; m = m->m_next) { - if (totlen < m->m_len) { - m->m_len = totlen; - totlen = 0; - } else - totlen -= m->m_len; - } - cmd->dstu.dst_m->m_pkthdr.len = - cmd->srcu.src_m->m_pkthdr.len; - m_freem(cmd->srcu.src_m); - } - } - - if (cmd->sloplen != 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - crp->crp_etype = - m_copyback((struct mbuf *)crp->crp_buf, - cmd->src_map->dm_mapsize - cmd->sloplen, - cmd->sloplen, &dma->slop[cmd->slopidx], - M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback((struct uio *)crp->crp_buf, - cmd->src_map->dm_mapsize - cmd->sloplen, - cmd->sloplen, &dma->slop[cmd->slopidx]); - if (crp->crp_etype) - goto out; - } - - i = dma->dstk; u = dma->dstu; - while (u != 0) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), sizeof(struct hifn_desc), - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->dstr[i].l & htole32(HIFN_D_VALID)) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), - sizeof(struct hifn_desc), - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (++i == (HIFN_D_DST_RSIZE + 1)) - i = 0; - else - u--; - } - dma->dstk = i; dma->dstu = u; - - hifnstats.hst_obytes += cmd->dst_map->dm_mapsize; - - if (cmd->base_masks & HIFN_BASE_CMD_MAC) { - u_int8_t *macbuf; - - macbuf = resbuf + sizeof(struct hifn_base_result); - if (cmd->base_masks & HIFN_BASE_CMD_COMP) - macbuf += sizeof(struct hifn_comp_result); - macbuf += sizeof(struct hifn_mac_result); - - for (i = 0; i < crp->crp_ndesc; i++) { - int len; - - crd = &crp->crp_desc[i]; - - if (crd->crd_alg == CRYPTO_MD5_HMAC || - crd->crd_alg == CRYPTO_SHA1_HMAC) - len = 12; - else - continue; - - if (crp->crp_flags & CRYPTO_F_IMBUF) - crp->crp_etype = - m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, len, macbuf, M_NOWAIT); - else if ((crp->crp_flags & CRYPTO_F_IOV) && crp->crp_mac) - bcopy((caddr_t)macbuf, crp->crp_mac, len); - break; - } - } - -out: - if (cmd->src_map != cmd->dst_map) { - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - crypto_done(crp); -} - -int -hifn_compression(struct hifn_softc *sc, struct cryptop *crp, - struct hifn_command *cmd) -{ - struct cryptodesc *crd = &crp->crp_desc[0]; - int s, err = 0; - - cmd->compcrd = crd; - cmd->base_masks |= HIFN_BASE_CMD_COMP; - - if ((crp->crp_flags & CRYPTO_F_IMBUF) == 0) { - /* - * XXX can only handle mbufs right now since we can - * XXX dynamically resize them. - */ - err = EINVAL; - return (ENOMEM); - } - - if ((crd->crd_flags & CRD_F_COMP) == 0) - cmd->base_masks |= HIFN_BASE_CMD_DECODE; - if (crd->crd_alg == CRYPTO_LZS_COMP) - cmd->comp_masks |= HIFN_COMP_CMD_ALG_LZS | - HIFN_COMP_CMD_CLEARHIST; - - if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map)) { - err = ENOMEM; - goto fail; - } - - if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->dst_map)) { - err = ENOMEM; - goto fail; - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - int len; - - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - - len = cmd->src_map->dm_mapsize / MCLBYTES; - if ((cmd->src_map->dm_mapsize % MCLBYTES) != 0) - len++; - len *= MCLBYTES; - - if ((crd->crd_flags & CRD_F_COMP) == 0) - len *= 4; - - if (len > HIFN_MAX_DMALEN) - len = HIFN_MAX_DMALEN; - - cmd->dstu.dst_m = hifn_mkmbuf_chain(len, cmd->srcu.src_m); - if (cmd->dstu.dst_m == NULL) { - err = ENOMEM; - goto fail; - } - - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - } - - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - } - - cmd->crp = crp; - /* - * Always use session 0. The modes of compression we use are - * stateless and there is always at least one compression - * context, zero. - */ - cmd->session_num = 0; - cmd->softc = sc; - - s = splnet(); - err = hifn_compress_enter(sc, cmd); - splx(s); - - if (err != 0) - goto fail; - return (0); - -fail: - if (cmd->dst_map != NULL) { - if (cmd->dst_map->dm_nsegs > 0) - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } - if (cmd->src_map != NULL) { - if (cmd->src_map->dm_nsegs > 0) - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - } - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - if (err == EINVAL) - hifnstats.hst_invalid++; - else - hifnstats.hst_nomem++; - crp->crp_etype = err; - crypto_done(crp); - return (0); -} - -/* - * must be called at splnet() - */ -int -hifn_compress_enter(struct hifn_softc *sc, struct hifn_command *cmd) -{ - struct hifn_dma *dma = sc->sc_dma; - int cmdi, resi; - u_int32_t cmdlen; - - if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE || - (dma->resu + 1) > HIFN_D_CMD_RSIZE) - return (ENOMEM); - - if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE || - (dma->dstu + cmd->dst_map->dm_nsegs) > HIFN_D_DST_RSIZE) - return (ENOMEM); - - if (dma->cmdi == HIFN_D_CMD_RSIZE) { - dma->cmdi = 0; - dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - cmdi = dma->cmdi++; - cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]); - HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE); - - /* .p for command/result already set */ - dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_VALID | HIFN_D_LAST | - HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, cmdi, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - dma->cmdu++; - if (sc->sc_c_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); - sc->sc_c_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED0); - } - - /* - * Always enable the command wait interrupt. We are obviously - * missing an interrupt or two somewhere. Enabling the command wait - * interrupt will guarantee we get called periodically until all - * of the queues are drained and thus work around this. - */ - sc->sc_dmaier |= HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - - hifnstats.hst_ipackets++; - hifnstats.hst_ibytes += cmd->src_map->dm_mapsize; - - hifn_dmamap_load_src(sc, cmd); - if (sc->sc_s_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); - sc->sc_s_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED1); - } - - /* - * Unlike other descriptors, we don't mask done interrupt from - * result descriptor. - */ - if (dma->resi == HIFN_D_RES_RSIZE) { - dma->resi = 0; - dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - resi = dma->resi++; - dma->hifn_commands[resi] = cmd; - HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD); - dma->resr[resi].l = htole32(HIFN_MAX_RESULT | - HIFN_D_VALID | HIFN_D_LAST); - HIFN_RESR_SYNC(sc, resi, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - dma->resu++; - if (sc->sc_r_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA); - sc->sc_r_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED2); - } - - if (cmd->sloplen) - cmd->slopidx = resi; - - hifn_dmamap_load_dst(sc, cmd); - - if (sc->sc_d_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); - sc->sc_d_busy = 1; - } - sc->sc_active = 5; - cmd->cmd_callback = hifn_callback_comp; - return (0); -} - -void -hifn_callback_comp(struct hifn_softc *sc, struct hifn_command *cmd, - u_int8_t *resbuf) -{ - struct hifn_base_result baseres; - struct cryptop *crp = cmd->crp; - struct hifn_dma *dma = sc->sc_dma; - struct mbuf *m; - int err = 0, i, u; - u_int32_t olen; - bus_size_t dstsize; - - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - - dstsize = cmd->dst_map->dm_mapsize; - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - - bcopy(resbuf, &baseres, sizeof(struct hifn_base_result)); - - i = dma->dstk; u = dma->dstu; - while (u != 0) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), sizeof(struct hifn_desc), - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->dstr[i].l & htole32(HIFN_D_VALID)) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), - sizeof(struct hifn_desc), - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (++i == (HIFN_D_DST_RSIZE + 1)) - i = 0; - else - u--; - } - dma->dstk = i; dma->dstu = u; - - if (baseres.flags & htole16(HIFN_BASE_RES_DSTOVERRUN)) { - bus_size_t xlen; - - xlen = dstsize; - - m_freem(cmd->dstu.dst_m); - - if (xlen == HIFN_MAX_DMALEN) { - /* We've done all we can. */ - err = E2BIG; - goto out; - } - - xlen += MCLBYTES; - - if (xlen > HIFN_MAX_DMALEN) - xlen = HIFN_MAX_DMALEN; - - cmd->dstu.dst_m = hifn_mkmbuf_chain(xlen, - cmd->srcu.src_m); - if (cmd->dstu.dst_m == NULL) { - err = ENOMEM; - goto out; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto out; - } - - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - - /* already at splnet... */ - err = hifn_compress_enter(sc, cmd); - if (err != 0) - goto out; - return; - } - - olen = dstsize - (letoh16(baseres.dst_cnt) | - (((letoh16(baseres.session) & HIFN_BASE_RES_DSTLEN_M) >> - HIFN_BASE_RES_DSTLEN_S) << 16)); - - crp->crp_olen = olen - cmd->compcrd->crd_skip; - - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - - m = cmd->dstu.dst_m; - if (m->m_flags & M_PKTHDR) - m->m_pkthdr.len = olen; - crp->crp_buf = (caddr_t)m; - for (; m != NULL; m = m->m_next) { - if (olen >= m->m_len) - olen -= m->m_len; - else { - m->m_len = olen; - olen = 0; - } - } - - m_freem(cmd->srcu.src_m); - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - crp->crp_etype = 0; - crypto_done(crp); - return; - -out: - if (cmd->dst_map != NULL) { - if (cmd->src_map->dm_nsegs != 0) - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } - if (cmd->src_map != NULL) { - if (cmd->src_map->dm_nsegs != 0) - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - } - m_freem(cmd->dstu.dst_m); - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - crp->crp_etype = err; - crypto_done(crp); -} - -struct mbuf * -hifn_mkmbuf_chain(int totlen, struct mbuf *mtemplate) -{ - int len; - struct mbuf *m, *m0, *mlast; - - if (mtemplate->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m0, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m0, M_DONTWAIT, MT_DATA); - } - if (m0 == NULL) - return (NULL); - if (len == MHLEN) { - if (m_dup_pkthdr(m0, mtemplate, M_DONTWAIT)) { - m_free(m0); - return (NULL); - } - } - MCLGET(m0, M_DONTWAIT); - if (!(m0->m_flags & M_EXT)) { - m_freem(m0); - return (NULL); - } - len = MCLBYTES; - - totlen -= len; - m0->m_pkthdr.len = m0->m_len = len; - mlast = m0; - - while (totlen > 0) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(m0); - return (NULL); - } - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_free(m); - m_freem(m0); - return (NULL); - } - len = MCLBYTES; - m->m_len = len; - if (m0->m_flags & M_PKTHDR) - m0->m_pkthdr.len += len; - totlen -= len; - - mlast->m_next = m; - mlast = m; - } - - return (m0); -} - -void -hifn_write_4(struct hifn_softc *sc, int reggrp, bus_size_t reg, - u_int32_t val) -{ - /* - * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0 - * and Group 1 registers; avoid conditions that could create - * burst writes by doing a read in between the writes. - */ - if (sc->sc_flags & HIFN_NO_BURSTWRITE) { - if (sc->sc_waw_lastgroup == reggrp && - sc->sc_waw_lastreg == reg - 4) { - bus_space_read_4(sc->sc_st1, sc->sc_sh1, HIFN_1_REVID); - } - sc->sc_waw_lastgroup = reggrp; - sc->sc_waw_lastreg = reg; - } - if (reggrp == 0) - bus_space_write_4(sc->sc_st0, sc->sc_sh0, reg, val); - else - bus_space_write_4(sc->sc_st1, sc->sc_sh1, reg, val); - -} - -u_int32_t -hifn_read_4(struct hifn_softc *sc, int reggrp, bus_size_t reg) -{ - if (sc->sc_flags & HIFN_NO_BURSTWRITE) { - sc->sc_waw_lastgroup = -1; - sc->sc_waw_lastreg = 1; - } - if (reggrp == 0) - return (bus_space_read_4(sc->sc_st0, sc->sc_sh0, reg)); - return (bus_space_read_4(sc->sc_st1, sc->sc_sh1, reg)); -} diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h deleted file mode 100644 index a1bc208181e..00000000000 --- a/sys/dev/pci/hifn7751reg.h +++ /dev/null @@ -1,523 +0,0 @@ -/* $OpenBSD: hifn7751reg.h,v 1.46 2014/12/19 22:44:58 guenther Exp $ */ - -/* - * Invertex AEON / Hifn 7751 driver - * Copyright (c) 1999 Invertex Inc. All rights reserved. - * Copyright (c) 1999 Theo de Raadt - * Copyright (c) 2000-2001 Network Security Technologies, Inc. - * http://www.netsec.net - * - * Please send any comments, feedback, bug-fixes, or feature requests to - * software@invertex.com. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ -#ifndef __HIFN_H__ -#define __HIFN_H__ - -#include <sys/endian.h> - -/* - * Some PCI configuration space offset defines. The names were made - * identical to the names used by the Linux kernel. - */ -#define HIFN_BAR0 (PCI_MAPREG_START + 0) /* PUC register map */ -#define HIFN_BAR1 (PCI_MAPREG_START + 4) /* DMA register map */ -#define HIFN_RETRY_TIMEOUT 0x41 -#define HIFN_TRDY_TIMEOUT 0x40 - -/* - * The values below should multiple of 4 -- and be large enough to handle - * any command the driver implements. - * - * MAX_COMMAND = base command + mac command + encrypt command + - * mac-key + rc4-key - * MAX_RESULT = base result + comp result + mac result + mac + encrypt result - * - * - */ -#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260) -#define HIFN_MAX_RESULT (8 + 4 + 4 + 20 + 4) - -/* - * hifn_desc_t - * - * Holds an individual descriptor for any of the rings. - */ -struct hifn_desc { - volatile u_int32_t l; /* length and status bits */ - volatile u_int32_t p; -}; - -/* - * Masks for the "length" field of struct hifn_desc. - */ -#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */ -#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */ -#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */ -#define HIFN_D_OVER 0x08000000 /* overflow */ -#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */ -#define HIFN_D_JUMP 0x40000000 /* jump descriptor */ -#define HIFN_D_VALID 0x80000000 /* valid bit */ - -/* - * Processing Unit Registers (offset from BASEREG0) - */ -#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */ -#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */ -#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */ -#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */ -#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */ -#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */ -#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */ -#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */ -#define HIFN_0_SPACESIZE 0x20 /* Register space size */ - -/* Processing Unit Control Register (HIFN_0_PUCTRL) */ -#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */ -#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */ -#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */ -#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */ -#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */ - -/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */ -#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */ -#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */ -#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */ -#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */ -#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */ -#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */ -#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */ -#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */ -#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */ -#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */ - -/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */ -#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */ -#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */ -#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */ -#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */ -#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */ -#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */ -#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */ -#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */ -#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */ -#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */ -#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */ -#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */ -#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */ -#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */ -#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */ -#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */ -#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */ -#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */ -#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */ -#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */ -#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */ -#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */ -#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */ - -/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */ -#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */ -#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */ -#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */ -#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */ -#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */ -#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */ -#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */ -#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */ -#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */ -#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */ - -/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */ -#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */ -#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */ -#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */ -#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */ -#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */ -#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */ -#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */ -#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */ -#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */ -#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */ -#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */ -#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */ -#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */ -#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */ -#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */ -#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */ -#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */ - -/* FIFO Status Register (HIFN_0_FIFOSTAT) */ -#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */ -#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */ - -/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */ -#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as 1 */ - -/* - * DMA Interface Registers (offset from BASEREG1) - */ -#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */ -#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */ -#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */ -#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */ -#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */ -#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */ -#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */ -#define HIFN_1_PLL 0x4c /* 795x: PLL config */ -#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */ -#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */ -#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */ -#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */ -#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */ -#define HIFN_1_REVID 0x98 /* Revision ID */ -#define HIFN_1_UNLOCK_SECRET1 0xf4 -#define HIFN_1_UNLOCK_SECRET2 0xfc -#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */ -#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */ -#define HIFN_1_PUB_OPLEN 0x304 /* Public Operand Length */ -#define HIFN_1_PUB_OP 0x308 /* Public Operand */ -#define HIFN_1_PUB_STATUS 0x30c /* Public Status */ -#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */ -#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */ -#define HIFN_1_RNG_DATA 0x318 /* RNG data */ -#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */ -#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */ - -/* DMA Status and Control Register (HIFN_1_DMA_CSR) */ -#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */ -#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */ -#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */ -#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */ -#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */ -#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */ -#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */ -#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */ -#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */ -#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */ -#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */ -#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */ -#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */ -#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */ -#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */ -#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */ -#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */ -#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */ -#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */ -#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */ -#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */ -#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */ -#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */ -#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */ -#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */ -#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */ -#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */ -#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */ -#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */ -#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */ -#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */ -#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */ -#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */ -#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */ -#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */ -#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */ -#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */ -#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */ - -/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */ -#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */ -#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */ -#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */ -#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */ -#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */ -#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */ -#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */ -#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */ -#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */ -#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */ -#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */ -#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */ -#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */ -#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */ -#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */ -#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */ -#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */ -#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */ -#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */ -#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */ -#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */ -#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */ - -/* DMA Configuration Register (HIFN_1_DMA_CNFG) */ -#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */ -#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */ -#define HIFN_DMACNFG_UNLOCK 0x00000800 -#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */ -#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */ -#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */ -#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */ -#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */ - -/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */ -#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */ - -/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */ -#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */ -#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */ -#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */ - -/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */ -#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */ -#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */ - -/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */ -#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */ -#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */ -#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */ -#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */ -#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */ -#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */ -#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */ -#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */ -#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */ - -/* PLL config register (HIFN_1_PLL) */ -#define HIFN_PLL_7956 0x00001d18 /* 7956 PLL config value */ - -/* Revision ID */ -#define HIFN_REVID_7811_PB3_2 0x00000002 /* 7811PB3/2 */ - -/* Public key reset register (HIFN_1_PUB_RESET) */ -#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */ - -/* Public base address register (HIFN_1_PUB_BASE) */ -#define HIFN_PUBBASE_ADDR 0x00003fff /* base address */ - -/* Public operand length register (HIFN_1_PUB_OPLEN) */ -#define HIFN_PUBOPLEN_MOD_M 0x0000007f /* modulus length mask */ -#define HIFN_PUBOPLEN_MOD_S 0 /* modulus length shift */ -#define HIFN_PUBOPLEN_EXP_M 0x0003ff80 /* exponent length mask */ -#define HIFN_PUBOPLEN_EXP_S 7 /* exponent length shift */ -#define HIFN_PUBOPLEN_RED_M 0x003c0000 /* reducend length mask */ -#define HIFN_PUBOPLEN_RED_S 18 /* reducend length shift */ - -/* Public operation register (HIFN_1_PUB_OP) */ -#define HIFN_PUBOP_AOFFSET_M 0x0000007f /* A offset mask */ -#define HIFN_PUBOP_AOFFSET_S 0 /* A offset shift */ -#define HIFN_PUBOP_BOFFSET_M 0x00000f80 /* B offset mask */ -#define HIFN_PUBOP_BOFFSET_S 7 /* B offset shift */ -#define HIFN_PUBOP_MOFFSET_M 0x0003f000 /* M offset mask */ -#define HIFN_PUBOP_MOFFSET_S 12 /* M offset shift */ -#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */ -#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */ -#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */ -#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */ -#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */ -#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */ -#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */ -#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */ -#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */ -#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */ -#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */ -#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */ -#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular RED */ -#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular EXP */ - -/* Public status register (HIFN_1_PUB_STATUS) */ -#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */ -#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */ - -/* Public interrupt enable register (HIFN_1_PUB_IEN) */ -#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */ - -/* Random number generator config register (HIFN_1_RNG_CONFIG) */ -#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */ - -/********************************************************************* - * Structs for board commands - * - *********************************************************************/ - -/* - * Structure to help build up the command data structure. - */ -struct hifn_base_command { - volatile u_int16_t masks; - volatile u_int16_t session_num; - volatile u_int16_t total_source_count; - volatile u_int16_t total_dest_count; -}; - -#define HIFN_BASE_CMD_COMP 0x0100 /* enable compression engine */ -#define HIFN_BASE_CMD_PAD 0x0200 /* enable padding engine */ -#define HIFN_BASE_CMD_MAC 0x0400 /* enable MAC engine */ -#define HIFN_BASE_CMD_CRYPT 0x0800 /* enable crypt engine */ -#define HIFN_BASE_CMD_DECODE 0x2000 -#define HIFN_BASE_CMD_SRCLEN_M 0xc000 -#define HIFN_BASE_CMD_SRCLEN_S 14 -#define HIFN_BASE_CMD_DSTLEN_M 0x3000 -#define HIFN_BASE_CMD_DSTLEN_S 12 -#define HIFN_BASE_CMD_LENMASK_HI 0x30000 -#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff - -/* - * Structure to help build up the command data structure. - */ -struct hifn_crypt_command { - volatile u_int16_t masks; - volatile u_int16_t header_skip; - volatile u_int16_t source_count; - volatile u_int16_t reserved; -}; - -#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */ -#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */ -#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */ -#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */ -#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */ -#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */ -#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */ -#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */ -#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */ -#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */ -#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */ -#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */ -#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */ -#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */ -#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */ -#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */ -#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */ -#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000 -#define HIFN_CRYPT_CMD_SRCLEN_S 14 - -/* - * Structure to help build up the command data structure. - */ -struct hifn_mac_command { - volatile u_int16_t masks; - volatile u_int16_t header_skip; - volatile u_int16_t source_count; - volatile u_int16_t reserved; -}; - -#define HIFN_MAC_CMD_ALG_MASK 0x0001 -#define HIFN_MAC_CMD_ALG_SHA1 0x0000 -#define HIFN_MAC_CMD_ALG_MD5 0x0001 -#define HIFN_MAC_CMD_MODE_MASK 0x000c -#define HIFN_MAC_CMD_MODE_HMAC 0x0000 -#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004 -#define HIFN_MAC_CMD_MODE_HASH 0x0008 -#define HIFN_MAC_CMD_MODE_FULL 0x0004 -#define HIFN_MAC_CMD_TRUNC 0x0010 -#define HIFN_MAC_CMD_RESULT 0x0020 -#define HIFN_MAC_CMD_APPEND 0x0040 -#define HIFN_MAC_CMD_SRCLEN_M 0xc000 -#define HIFN_MAC_CMD_SRCLEN_S 14 - -/* - * MAC POS IPsec initiates authentication after encryption on encodes - * and before decryption on decodes. - */ -#define HIFN_MAC_CMD_POS_IPSEC 0x0200 -#define HIFN_MAC_CMD_NEW_KEY 0x0800 - -struct hifn_comp_command { - volatile u_int16_t masks; - volatile u_int16_t header_skip; - volatile u_int16_t source_count; - volatile u_int16_t reserved; -}; - -#define HIFN_COMP_CMD_SRCLEN_M 0xc000 -#define HIFN_COMP_CMD_SRCLEN_S 14 -#define HIFN_COMP_CMD_ONE 0x0100 /* must be one */ -#define HIFN_COMP_CMD_CLEARHIST 0x0010 /* clear history */ -#define HIFN_COMP_CMD_UPDATEHIST 0x0008 /* update history */ -#define HIFN_COMP_CMD_LZS_STRIP0 0x0004 /* LZS: strip zero */ -#define HIFN_COMP_CMD_MPPC_RESTART 0x0004 /* MPPC: restart */ -#define HIFN_COMP_CMD_ALG_MASK 0x0001 /* compression mode: */ -#define HIFN_COMP_CMD_ALG_MPPC 0x0001 /* MPPC */ -#define HIFN_COMP_CMD_ALG_LZS 0x0000 /* LZS */ - -struct hifn_base_result { - volatile u_int16_t flags; - volatile u_int16_t session; - volatile u_int16_t src_cnt; /* 15:0 of source count */ - volatile u_int16_t dst_cnt; /* 15:0 of dest count */ -}; - -#define HIFN_BASE_RES_DSTOVERRUN 0x0200 /* destination overrun */ -#define HIFN_BASE_RES_SRCLEN_M 0xc000 /* 17:16 of source count */ -#define HIFN_BASE_RES_SRCLEN_S 14 -#define HIFN_BASE_RES_DSTLEN_M 0x3000 /* 17:16 of dest count */ -#define HIFN_BASE_RES_DSTLEN_S 12 - -struct hifn_comp_result { - volatile u_int16_t flags; - volatile u_int16_t crc; -}; - -#define HIFN_COMP_RES_LCB_M 0xff00 /* longitudinal check byte */ -#define HIFN_COMP_RES_LCB_S 8 -#define HIFN_COMP_RES_RESTART 0x0004 /* MPPC: restart */ -#define HIFN_COMP_RES_ENDMARKER 0x0002 /* LZS: end marker seen */ -#define HIFN_COMP_RES_SRC_NOTZERO 0x0001 /* source expired */ - -struct hifn_mac_result { - volatile u_int16_t flags; - volatile u_int16_t reserved; - /* followed by 0, 6, 8, or 10 u_int16_t's of the MAC, then crypt */ -}; - -#define HIFN_MAC_RES_MISCOMPARE 0x0002 /* compare failed */ -#define HIFN_MAC_RES_SRC_NOTZERO 0x0001 /* source expired */ - -struct hifn_crypt_result { - volatile u_int16_t flags; - volatile u_int16_t reserved; -}; - -#define HIFN_CRYPT_RES_SRC_NOTZERO 0x0001 /* source expired */ - -/* - * The poll frequency and poll scalar defines are unshifted values used - * to set fields in the DMA Configuration Register. - */ -#ifndef HIFN_POLL_FREQUENCY -#define HIFN_POLL_FREQUENCY 0x1 -#endif - -#ifndef HIFN_POLL_SCALAR -#define HIFN_POLL_SCALAR 0x0 -#endif - -#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */ -#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */ -#endif /* __HIFN_H__ */ diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h deleted file mode 100644 index fb70f44fe47..00000000000 --- a/sys/dev/pci/hifn7751var.h +++ /dev/null @@ -1,324 +0,0 @@ -/* $OpenBSD: hifn7751var.h,v 1.54 2020/01/11 21:34:04 cheloha Exp $ */ - -/* - * Invertex AEON / Hifn 7751 driver - * Copyright (c) 1999 Invertex Inc. All rights reserved. - * Copyright (c) 1999 Theo de Raadt - * Copyright (c) 2000-2001 Network Security Technologies, Inc. - * http://www.netsec.net - * - * Please send any comments, feedback, bug-fixes, or feature requests to - * software@invertex.com. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -#ifndef __HIFN7751VAR_H__ -#define __HIFN7751VAR_H__ - -#ifdef _KERNEL - -/* - * Some configurable values for the driver - */ -#define HIFN_D_CMD_RSIZE 24 /* command descriptors */ -#define HIFN_D_SRC_RSIZE 80 /* source descriptors */ -#define HIFN_D_DST_RSIZE 80 /* destination descriptors */ -#define HIFN_D_RES_RSIZE 24 /* result descriptors */ - -/* - * Length values for cryptography - */ -#define HIFN_DES_KEY_LENGTH 8 -#define HIFN_3DES_KEY_LENGTH 24 -#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH -#define HIFN_IV_LENGTH 8 -#define HIFN_AES_IV_LENGTH 16 -#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH - -/* - * Length values for authentication - */ -#define HIFN_MAC_KEY_LENGTH 64 -#define HIFN_MD5_LENGTH 16 -#define HIFN_SHA1_LENGTH 20 -#define HIFN_MAC_TRUNC_LENGTH 12 - -#define MAX_SCATTER 64 - -/* - * Data structure to hold all 4 rings and any other ring related data. - */ -struct hifn_dma { - /* - * Descriptor rings. We add +1 to the size to accommodate the - * jump descriptor. - */ - struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1]; - struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1]; - struct hifn_desc dstr[HIFN_D_DST_RSIZE+1]; - struct hifn_desc resr[HIFN_D_RES_RSIZE+1]; - - struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE]; - - u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND]; - u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT]; - u_int32_t slop[HIFN_D_CMD_RSIZE]; - - u_int64_t test_src, test_dst; - - /* - * Our current positions for insertion and removal from the descriptor - * rings. - */ - int cmdi, srci, dsti, resi; - volatile int cmdu, srcu, dstu, resu; - int cmdk, srck, dstk, resk; -}; - -struct hifn_session { - int hs_used; -}; - -#define HIFN_RING_SYNC(sc, r, i, f) \ - bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ - offsetof(struct hifn_dma, r[i]), sizeof(struct hifn_desc), (f)) - -#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f)) -#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f)) -#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f)) -#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f)) - -#define HIFN_CMD_SYNC(sc, i, f) \ - bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ - offsetof(struct hifn_dma, command_bufs[(i)][0]), \ - HIFN_MAX_COMMAND, (f)) - -#define HIFN_RES_SYNC(sc, i, f) \ - bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ - offsetof(struct hifn_dma, result_bufs[(i)][0]), \ - HIFN_MAX_RESULT, (f)) - -/* - * Holds data specific to a single HIFN board. - */ -struct hifn_softc { - struct device sc_dv; /* generic device */ - void * sc_ih; /* interrupt handler cookie */ - u_int32_t sc_dmaier; - u_int32_t sc_drammodel; /* 1=dram, 0=sram */ - - bus_space_handle_t sc_sh0, sc_sh1; - bus_space_tag_t sc_st0, sc_st1; - bus_dma_tag_t sc_dmat; - - struct hifn_dma *sc_dma; - bus_dmamap_t sc_dmamap; - bus_dma_segment_t sc_dmasegs[1]; - int sc_dmansegs; - int32_t sc_cid; - int sc_maxses; - int sc_nsessions; - int sc_ramsize; - int sc_flags; -#define HIFN_HAS_RNG 0x01 /* includes random number generator */ -#define HIFN_HAS_PUBLIC 0x02 /* includes public key support */ -#define HIFN_IS_7811 0x04 /* Hifn 7811 part */ -#define HIFN_NO_BURSTWRITE 0x08 /* can't handle PCI burst writes */ -#define HIFN_HAS_LEDS 0x10 /* Has LEDs to blink */ -#define HIFN_HAS_AES 0x20 /* includes AES support */ -#define HIFN_IS_7956 0x40 /* Hifn 7955/7956 part */ - struct timeout sc_rngto, sc_tickto; - int sc_rngfirst; - int sc_rngms; /* timeout interval (milliseconds) */ - int sc_c_busy, sc_s_busy, sc_d_busy, sc_r_busy, sc_active; - struct hifn_session *sc_sessions; - pci_chipset_tag_t sc_pci_pc; - pcitag_t sc_pci_tag; - bus_size_t sc_waw_lastreg; - int sc_waw_lastgroup; -}; - -#define WRITE_REG_0(sc,reg,val) hifn_write_4((sc), 0, (reg), (val)) -#define WRITE_REG_1(sc,reg,val) hifn_write_4((sc), 1, (reg), (val)) -#define READ_REG_0(sc,reg) hifn_read_4((sc), 0, (reg)) -#define READ_REG_1(sc,reg) hifn_read_4((sc), 1, (reg)) - -#define SET_LED(sc,v) \ - if (sc->sc_flags & HIFN_HAS_LEDS) \ - WRITE_REG_1(sc, HIFN_1_7811_MIPSRST, \ - READ_REG_1(sc, HIFN_1_7811_MIPSRST) | (v)) -#define CLR_LED(sc,v) \ - if (sc->sc_flags & HIFN_HAS_LEDS) \ - WRITE_REG_1(sc, HIFN_1_7811_MIPSRST, \ - READ_REG_1(sc, HIFN_1_7811_MIPSRST) & ~(v)) - -/* - * struct hifn_command - * - * This is the control structure used to pass commands to hifn_encrypt(). - * - * flags - * ----- - * Flags is the bitwise "or" values for command configuration. A single - * encrypt direction needs to be set: - * - * HIFN_ENCODE or HIFN_DECODE - * - * To use cryptography, a single crypto algorithm must be included: - * - * HIFN_CRYPT_3DES or HIFN_CRYPT_DES - * - * To use authentication, a single MAC algorithm must be included: - * - * HIFN_MAC_MD5 or HIFN_MAC_SHA1 - * - * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash. - * If the value below is set, hash values are truncated or assumed - * truncated to 12 bytes: - * - * HIFN_MAC_TRUNC - * - * Keys for encryption and authentication can be sent as part of a command, - * or the last key value used with a particular session can be retrieved - * and used again if either of these flags are not specified. - * - * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY - * - * session_num - * ----------- - * A number between 0 and 2048 (for DRAM models) or a number between - * 0 and 768 (for SRAM models). Those who don't want to use session - * numbers should leave value at zero and send a new crypt key and/or - * new MAC key on every command. If you use session numbers and - * don't send a key with a command, the last key sent for that same - * session number will be used. - * - * Warning: Using session numbers and multiboard at the same time - * is currently broken. - * - * mbuf - * ---- - * Either fill in the mbuf pointer and npa=0 or - * fill packp[] and packl[] and set npa to > 0 - * - * mac_header_skip - * --------------- - * The number of bytes of the source_buf that are skipped over before - * authentication begins. This must be a number between 0 and 2^16-1 - * and can be used by IPsec implementers to skip over IP headers. - * *** Value ignored if authentication not used *** - * - * crypt_header_skip - * ----------------- - * The number of bytes of the source_buf that are skipped over before - * the cryptographic operation begins. This must be a number between 0 - * and 2^16-1. For IPsec, this number will always be 8 bytes larger - * than the auth_header_skip (to skip over the ESP header). - * *** Value ignored if cryptography not used *** - * - */ -struct hifn_command { - u_int16_t session_num; - u_int16_t base_masks, cry_masks, mac_masks, comp_masks; - u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH]; - int cklen; - int sloplen, slopidx; - - union { - struct mbuf *src_m; - struct uio *src_io; - } srcu; - bus_dmamap_t src_map; - - union { - struct mbuf *dst_m; - struct uio *dst_io; - } dstu; - bus_dmamap_t dst_map; - - struct hifn_softc *softc; - struct cryptop *crp; - struct cryptodesc *enccrd, *maccrd, *compcrd; - void (*cmd_callback)(struct hifn_softc *, struct hifn_command *, - u_int8_t *); -}; - -/* - * Return values for hifn_crypto() - */ -#define HIFN_CRYPTO_SUCCESS 0 -#define HIFN_CRYPTO_BAD_INPUT (-1) -#define HIFN_CRYPTO_RINGS_FULL (-2) - -/************************************************************************** - * - * Function: hifn_crypto - * - * Purpose: Called by external drivers to begin an encryption on the - * HIFN board. - * - * Blocking/Non-blocking Issues - * ============================ - * The driver cannot block in hifn_crypto (no calls to tsleep) currently. - * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough - * room in any of the rings for the request to proceed. - * - * Return Values - * ============= - * 0 for success, negative values on error - * - * Defines for negative error codes are: - * - * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings. - * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking - * behaviour was requested. - * - *************************************************************************/ - -/* - * Convert back and forth from 'sid' to 'card' and 'session' - */ -#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28) -#define HIFN_SESSION(sid) ((sid) & 0x000007ff) -#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff)) - -#endif /* _KERNEL */ - -struct hifn_stats { - u_int64_t hst_ibytes; - u_int64_t hst_obytes; - u_int32_t hst_ipackets; - u_int32_t hst_opackets; - u_int32_t hst_invalid; - u_int32_t hst_nomem; - u_int32_t hst_abort; -}; - -#endif /* __HIFN7751VAR_H__ */ diff --git a/sys/dev/pci/safe.c b/sys/dev/pci/safe.c deleted file mode 100644 index d95b0b3c8b6..00000000000 --- a/sys/dev/pci/safe.c +++ /dev/null @@ -1,1829 +0,0 @@ -/* $OpenBSD: safe.c,v 1.46 2021/10/13 13:08:58 bluhm Exp $ */ - -/*- - * Copyright (c) 2003 Sam Leffler, Errno Consulting - * Copyright (c) 2003 Global Technology Associates, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safe.c,v 1.1 2003/07/21 21:46:07 sam Exp $ - */ - -/* - * SafeNet SafeXcel-1141 hardware crypto accelerator - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/errno.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/device.h> -#include <sys/timeout.h> - -#include <machine/bus.h> - -#include <crypto/md5.h> -#include <crypto/sha1.h> -#include <crypto/cryptodev.h> -#include <crypto/cryptosoft.h> - -#include <dev/pci/pcivar.h> -#include <dev/pci/pcireg.h> -#include <dev/pci/pcidevs.h> - -#include <dev/pci/safereg.h> -#include <dev/pci/safevar.h> - -#ifndef bswap32 -#define bswap32(x) (x) = ntohl((u_int32_t)(x)) -#endif - -#define KASSERT_X(x,y) - -/* - * Prototypes and count for the pci_device structure - */ -int safe_probe(struct device *, void *, void *); -void safe_attach(struct device *, struct device *, void *); - -struct cfattach safe_ca = { - sizeof(struct safe_softc), safe_probe, safe_attach -}; - -struct cfdriver safe_cd = { - 0, "safe", DV_DULL -}; - -int safe_intr(void *); -int safe_newsession(u_int32_t *, struct cryptoini *); -int safe_freesession(u_int64_t); -int safe_process(struct cryptop *); -void safe_callback(struct safe_softc *, struct safe_ringentry *); -void safe_feed(struct safe_softc *, struct safe_ringentry *); -void safe_mcopy(struct mbuf *, struct mbuf *, u_int); -void safe_rng_init(struct safe_softc *); -void safe_rng(void *); -int safe_dma_malloc(struct safe_softc *, bus_size_t, - struct safe_dma_alloc *, int); -#define safe_dma_sync(_sc, _dma, _flags) \ - bus_dmamap_sync((_sc)->sc_dmat, (_dma)->dma_map, 0, \ - (_dma)->dma_map->dm_mapsize, (_flags)) -void safe_dma_free(struct safe_softc *, struct safe_dma_alloc *); -int safe_dmamap_aligned(const struct safe_operand *); -int safe_dmamap_uniform(const struct safe_operand *); - -void safe_reset_board(struct safe_softc *); -void safe_init_board(struct safe_softc *); -void safe_init_pciregs(struct safe_softc *); -void safe_cleanchip(struct safe_softc *); -static __inline u_int32_t safe_rng_read(struct safe_softc *); - -int safe_free_entry(struct safe_softc *, struct safe_ringentry *); - -#ifdef SAFE_DEBUG -int safe_debug; -#define DPRINTF(_x) if (safe_debug) printf _x - -void safe_dump_dmastatus(struct safe_softc *, const char *); -void safe_dump_intrstate(struct safe_softc *, const char *); -void safe_dump_ringstate(struct safe_softc *, const char *); -void safe_dump_request(struct safe_softc *, const char *, - struct safe_ringentry *); -void safe_dump_ring(struct safe_softc *sc, const char *tag); -#else -#define DPRINTF(_x) -#endif - -#define READ_REG(sc,r) \ - bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r)) - -#define WRITE_REG(sc,reg,val) \ - bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val) - -struct safe_stats safestats; - -int safe_rnginterval = 1; /* poll once a second */ -int safe_rngbufsize = 16; /* 64 bytes each poll */ -int safe_rngmaxalarm = 8; /* max alarms before reset */ - -int -safe_probe(struct device *parent, void *match, void *aux) -{ - struct pci_attach_args *pa = aux; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SAFENET && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SAFENET_SAFEXCEL) - return (1); - return (0); -} - -void -safe_attach(struct device *parent, struct device *self, void *aux) -{ - struct safe_softc *sc = (struct safe_softc *)self; - struct pci_attach_args *pa = aux; - pci_intr_handle_t ih; - const char *intrstr = NULL; - bus_size_t iosize; - bus_addr_t raddr; - u_int32_t devinfo; - int algs[CRYPTO_ALGORITHM_MAX + 1], i; - - /* XXX handle power management */ - - sc->sc_dmat = pa->pa_dmat; - - /* - * Setup memory-mapping of PCI registers. - */ - if (pci_mapreg_map(pa, SAFE_BAR, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) { - printf(": can't map register space\n"); - goto bad; - } - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - goto bad1; - } - intrstr = pci_intr_string(pa->pa_pc, ih); - sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, safe_intr, sc, - self->dv_xname); - if (sc->sc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - goto bad2; - } - - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) { - printf(": could not get crypto driver id\n"); - goto bad3; - } - - sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) & - (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN); - - /* - * Allocate packet engine descriptors. - */ - if (safe_dma_malloc(sc, - SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry), - &sc->sc_ringalloc, 0)) { - printf(": cannot allocate PE descriptor ring\n"); - goto bad4; - } - /* - * Hookup the static portion of all our data structures. - */ - sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr; - sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE; - sc->sc_front = sc->sc_ring; - sc->sc_back = sc->sc_ring; - raddr = sc->sc_ringalloc.dma_paddr; - bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry)); - for (i = 0; i < SAFE_MAX_NQUEUE; i++) { - struct safe_ringentry *re = &sc->sc_ring[i]; - - re->re_desc.d_sa = raddr + - offsetof(struct safe_ringentry, re_sa); - re->re_sa.sa_staterec = raddr + - offsetof(struct safe_ringentry, re_sastate); - - raddr += sizeof (struct safe_ringentry); - } - - /* - * Allocate scatter and gather particle descriptors. - */ - if (safe_dma_malloc(sc, SAFE_TOTAL_SPART * sizeof (struct safe_pdesc), - &sc->sc_spalloc, 0)) { - printf(": cannot allocate source particle descriptor ring\n"); - safe_dma_free(sc, &sc->sc_ringalloc); - goto bad4; - } - sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr; - sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART; - sc->sc_spfree = sc->sc_spring; - bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc)); - - if (safe_dma_malloc(sc, SAFE_TOTAL_DPART * sizeof (struct safe_pdesc), - &sc->sc_dpalloc, 0)) { - printf(": cannot allocate destination particle " - "descriptor ring\n"); - safe_dma_free(sc, &sc->sc_spalloc); - safe_dma_free(sc, &sc->sc_ringalloc); - goto bad4; - } - sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr; - sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART; - sc->sc_dpfree = sc->sc_dpring; - bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc)); - - printf(":"); - - devinfo = READ_REG(sc, SAFE_DEVINFO); - if (devinfo & SAFE_DEVINFO_RNG) - printf(" RNG"); - - bzero(algs, sizeof(algs)); - if (devinfo & SAFE_DEVINFO_DES) { - printf(" 3DES"); - algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (devinfo & SAFE_DEVINFO_AES) { - printf(" AES"); - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (devinfo & SAFE_DEVINFO_MD5) { - printf(" MD5"); - algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (devinfo & SAFE_DEVINFO_SHA1) { - printf(" SHA1"); - algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - crypto_register(sc->sc_cid, algs, safe_newsession, - safe_freesession, safe_process); - /* XXX other supported algorithms? */ - - printf(", %s\n", intrstr); - - safe_reset_board(sc); /* reset h/w */ - safe_init_pciregs(sc); /* init pci settings */ - safe_init_board(sc); /* init h/w */ - - if (devinfo & SAFE_DEVINFO_RNG) { - safe_rng_init(sc); - - timeout_set(&sc->sc_rngto, safe_rng, sc); - timeout_add_sec(&sc->sc_rngto, safe_rnginterval); - } - return; - -bad4: - /* XXX crypto_unregister_all(sc->sc_cid); */ -bad3: - pci_intr_disestablish(pa->pa_pc, sc->sc_ih); -bad2: - /* pci_intr_unmap? */; -bad1: - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); -bad: - return; -} - -int -safe_process(struct cryptop *crp) -{ - int err = 0, i, nicealign, uniform, s; - struct safe_softc *sc; - struct cryptodesc *crd1, *crd2 = NULL, *maccrd, *enccrd; - int bypass, oplen, ivsize, card; - int16_t coffset; - struct safe_session *ses; - struct safe_ringentry *re; - struct safe_sarec *sa; - struct safe_pdesc *pd; - u_int32_t cmd0, cmd1, staterec, iv[4]; - - s = splnet(); - - card = SAFE_CARD(crp->crp_sid); - if (card >= safe_cd.cd_ndevs || safe_cd.cd_devs[card] == NULL) { - safestats.st_invalid++; - splx(s); - return (EINVAL); - } - sc = safe_cd.cd_devs[card]; - - if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) { - safestats.st_badsession++; - splx(s); - return (EINVAL); - } - - if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) { - safestats.st_ringfull++; - splx(s); - return (ERESTART); - } - re = sc->sc_front; - - staterec = re->re_sa.sa_staterec; /* save */ - /* NB: zero everything but the PE descriptor */ - bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc)); - re->re_sa.sa_staterec = staterec; /* restore */ - - re->re_crp = crp; - re->re_sesn = SAFE_SESSION(crp->crp_sid); - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - re->re_src_m = (struct mbuf *)crp->crp_buf; - re->re_dst_m = (struct mbuf *)crp->crp_buf; - } else if (crp->crp_flags & CRYPTO_F_IOV) { - re->re_src_io = (struct uio *)crp->crp_buf; - re->re_dst_io = (struct uio *)crp->crp_buf; - } else { - safestats.st_badflags++; - err = EINVAL; - goto errout; /* XXX we don't handle contiguous blocks! */ - } - - sa = &re->re_sa; - ses = &sc->sc_sessions[re->re_sesn]; - - if (crp->crp_ndesc < 1) { - safestats.st_nodesc++; - err = EINVAL; - goto errout; - } - crd1 = &crp->crp_desc[0]; - if (crp->crp_ndesc >= 2) - crd2 = &crp->crp_desc[1]; - - cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */ - cmd1 = 0; - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) { - maccrd = crd1; - enccrd = NULL; - cmd0 |= SAFE_SA_CMD0_OP_HASH; - } else if (crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) { - maccrd = NULL; - enccrd = crd1; - cmd0 |= SAFE_SA_CMD0_OP_CRYPT; - } else { - safestats.st_badalg++; - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) && - (crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC) && - ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - safestats.st_badalg++; - err = EINVAL; - goto errout; - } - cmd0 |= SAFE_SA_CMD0_OP_BOTH; - } - - if (enccrd) { - if (enccrd->crd_alg == CRYPTO_3DES_CBC) { - cmd0 |= SAFE_SA_CMD0_3DES; - cmd1 |= SAFE_SA_CMD1_CBC; - ivsize = 2*sizeof(u_int32_t); - } else if (enccrd->crd_alg == CRYPTO_AES_CBC) { - cmd0 |= SAFE_SA_CMD0_AES; - cmd1 |= SAFE_SA_CMD1_CBC; - if (ses->ses_klen == 128) - cmd1 |= SAFE_SA_CMD1_AES128; - else if (ses->ses_klen == 192) - cmd1 |= SAFE_SA_CMD1_AES192; - else - cmd1 |= SAFE_SA_CMD1_AES256; - ivsize = 4*sizeof(u_int32_t); - } else { - cmd0 |= SAFE_SA_CMD0_CRYPT_NULL; - ivsize = 0; - } - - /* - * Setup encrypt/decrypt state. When using basic ops - * we can't use an inline IV because hash/crypt offset - * must be from the end of the IV to the start of the - * crypt data and this leaves out the preceding header - * from the hash calculation. Instead we place the IV - * in the state record and set the hash/crypt offset to - * copy both the header+IV. - */ - if (enccrd->crd_flags & CRD_F_ENCRYPT) { - cmd0 |= SAFE_SA_CMD0_OUTBOUND; - - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, iv, ivsize); - else - arc4random_buf(iv, ivsize); - - if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - err = m_copyback(re->re_src_m, - enccrd->crd_inject, ivsize, iv, - M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback(re->re_src_io, - enccrd->crd_inject, ivsize, iv); - if (err) - goto errout; - } - for (i = 0; i < ivsize / sizeof(iv[0]); i++) - re->re_sastate.sa_saved_iv[i] = htole32(iv[i]); - cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV; - } else { - cmd0 |= SAFE_SA_CMD0_INBOUND; - - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, iv, ivsize); - else if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata(re->re_src_m, enccrd->crd_inject, - ivsize, iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata(re->re_src_io, enccrd->crd_inject, - ivsize, (caddr_t)iv); - for (i = 0; i < ivsize / sizeof(iv[0]); i++) - re->re_sastate.sa_saved_iv[i] = htole32(iv[i]); - cmd0 |= SAFE_SA_CMD0_IVLD_STATE; - } - /* - * For basic encryption use the zero pad algorithm. - * This pads results to an 8-byte boundary and - * suppresses padding verification for inbound (i.e. - * decrypt) operations. - * - * NB: Not sure if the 8-byte pad boundary is a problem. - */ - cmd0 |= SAFE_SA_CMD0_PAD_ZERO; - - /* XXX assert key bufs have the same size */ - for (i = 0; i < nitems(sa->sa_key); i++) - sa->sa_key[i] = ses->ses_key[i]; - } - - if (maccrd) { - if (maccrd->crd_alg == CRYPTO_MD5_HMAC) { - cmd0 |= SAFE_SA_CMD0_MD5; - cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */ - } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) { - cmd0 |= SAFE_SA_CMD0_SHA1; - cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */ - } else { - cmd0 |= SAFE_SA_CMD0_HASH_NULL; - } - /* - * Digest data is loaded from the SA and the hash - * result is saved to the state block where we - * retrieve it for return to the caller. - */ - /* XXX assert digest bufs have the same size */ - for (i = 0; - i < nitems(sa->sa_outdigest); - i++) { - sa->sa_indigest[i] = ses->ses_hminner[i]; - sa->sa_outdigest[i] = ses->ses_hmouter[i]; - } - - cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH; - re->re_flags |= SAFE_QFLAGS_COPYOUTICV; - } - - if (enccrd && maccrd) { - /* - * The offset from hash data to the start of - * crypt data is the difference in the skips. - */ - bypass = maccrd->crd_skip; - coffset = enccrd->crd_skip - maccrd->crd_skip; - if (coffset < 0) { - DPRINTF(("%s: hash does not precede crypt; " - "mac skip %u enc skip %u\n", - __func__, maccrd->crd_skip, enccrd->crd_skip)); - safestats.st_skipmismatch++; - err = EINVAL; - goto errout; - } - oplen = enccrd->crd_skip + enccrd->crd_len; - if (maccrd->crd_skip + maccrd->crd_len != oplen) { - DPRINTF(("%s: hash amount %u != crypt amount %u\n", - __func__, maccrd->crd_skip + maccrd->crd_len, - oplen)); - safestats.st_lenmismatch++; - err = EINVAL; - goto errout; - } -#ifdef SAFE_DEBUG - if (safe_debug) { - printf("mac: skip %d, len %d, inject %d\n", - maccrd->crd_skip, maccrd->crd_len, - maccrd->crd_inject); - printf("enc: skip %d, len %d, inject %d\n", - enccrd->crd_skip, enccrd->crd_len, - enccrd->crd_inject); - printf("bypass %d coffset %d oplen %d\n", - bypass, coffset, oplen); - } -#endif - if (coffset & 3) { /* offset must be 32-bit aligned */ - DPRINTF(("%s: coffset %u misaligned\n", - __func__, coffset)); - safestats.st_coffmisaligned++; - err = EINVAL; - goto errout; - } - coffset >>= 2; - if (coffset > 255) { /* offset must be <256 dwords */ - DPRINTF(("%s: coffset %u too big\n", - __func__, coffset)); - safestats.st_cofftoobig++; - err = EINVAL; - goto errout; - } - /* - * Tell the hardware to copy the header to the output. - * The header is defined as the data from the end of - * the bypass to the start of data to be encrypted. - * Typically this is the inline IV. Note that you need - * to do this even if src+dst are the same; it appears - * that w/o this bit the crypted data is written - * immediately after the bypass data. - */ - cmd1 |= SAFE_SA_CMD1_HDRCOPY; - /* - * Disable IP header mutable bit handling. This is - * needed to get correct HMAC calculations. - */ - cmd1 |= SAFE_SA_CMD1_MUTABLE; - } else { - if (enccrd) { - bypass = enccrd->crd_skip; - oplen = bypass + enccrd->crd_len; - } else { - bypass = maccrd->crd_skip; - oplen = bypass + maccrd->crd_len; - } - coffset = 0; - } - /* XXX verify multiple of 4 when using s/g */ - if (bypass > 96) { /* bypass offset must be <= 96 bytes */ - DPRINTF(("%s: bypass %u too big\n", __func__, bypass)); - safestats.st_bypasstoobig++; - err = EINVAL; - goto errout; - } - - if (bus_dmamap_create(sc->sc_dmat, SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_src_map)) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, re->re_src_map, - re->re_src_m, BUS_DMA_NOWAIT)) { - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - re->re_src_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, re->re_src_map, - re->re_src_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - re->re_src_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - } - nicealign = safe_dmamap_aligned(&re->re_src); - uniform = safe_dmamap_uniform(&re->re_src); - - DPRINTF(("src nicealign %u uniform %u nsegs %u\n", - nicealign, uniform, re->re_src_nsegs)); - if (re->re_src_nsegs > 1) { - re->re_desc.d_src = sc->sc_spalloc.dma_paddr + - ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring); - for (i = 0; i < re->re_src_nsegs; i++) { - /* NB: no need to check if there's space */ - pd = sc->sc_spfree; - if (++(sc->sc_spfree) == sc->sc_springtop) - sc->sc_spfree = sc->sc_spring; - - KASSERT_X((pd->pd_flags&3) == 0 || - (pd->pd_flags&3) == SAFE_PD_DONE, - ("bogus source particle descriptor; flags %x", - pd->pd_flags)); - pd->pd_addr = re->re_src_segs[i].ds_addr; - pd->pd_ctrl = SAFE_PD_READY | - ((re->re_src_segs[i].ds_len << SAFE_PD_LEN_S) - & SAFE_PD_LEN_M); - } - cmd0 |= SAFE_SA_CMD0_IGATHER; - } else { - /* - * No need for gather, reference the operand directly. - */ - re->re_desc.d_src = re->re_src_segs[0].ds_addr; - } - - if (enccrd == NULL && maccrd != NULL) { - /* - * Hash op; no destination needed. - */ - } else { - if (crp->crp_flags & CRYPTO_F_IOV) { - if (!nicealign) { - safestats.st_iovmisaligned++; - err = EINVAL; - goto errout; - } - if (uniform != 1) { - /* - * Source is not suitable for direct use as - * the destination. Create a new scatter/gather - * list based on the destination requirements - * and check if that's ok. - */ - if (bus_dmamap_create(sc->sc_dmat, - SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, - BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_dst_map)) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_uio(sc->sc_dmat, - re->re_dst_map, re->re_dst_io, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - re->re_dst_map); - re->re_dst_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - uniform = safe_dmamap_uniform(&re->re_dst); - if (!uniform) { - /* - * There's no way to handle the DMA - * requirements with this uio. We - * could create a separate DMA area for - * the result and then copy it back, - * but for now we just bail and return - * an error. Note that uio requests - * > SAFE_MAX_DSIZE are handled because - * the DMA map and segment list for the - * destination will result in a - * destination particle list that does - * the necessary scatter DMA. - */ - safestats.st_iovnotuniform++; - err = EINVAL; - goto errout; - } - } else - re->re_dst = re->re_src; - } else if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (nicealign && uniform == 1) { - /* - * Source layout is suitable for direct - * sharing of the DMA map and segment list. - */ - re->re_dst = re->re_src; - } else if (nicealign && uniform == 2) { - /* - * The source is properly aligned but requires a - * different particle list to handle DMA of the - * result. Create a new map and do the load to - * create the segment list. The particle - * descriptor setup code below will handle the - * rest. - */ - if (bus_dmamap_create(sc->sc_dmat, - SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, - BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_dst_map)) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, - re->re_dst_map, re->re_dst_m, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - re->re_dst_map); - re->re_dst_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - } else { /* !(aligned and/or uniform) */ - int totlen, len; - struct mbuf *m, *top, **mp; - - /* - * DMA constraints require that we allocate a - * new mbuf chain for the destination. We - * allocate an entire new set of mbufs of - * optimal/required size and then tell the - * hardware to copy any bits that are not - * created as a byproduct of the operation. - */ - if (!nicealign) - safestats.st_unaligned++; - if (!uniform) - safestats.st_notuniform++; - totlen = re->re_src_mapsize; - if (re->re_src_m->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m, M_DONTWAIT, MT_DATA); - } - if (m == NULL) { - safestats.st_nombuf++; - err = sc->sc_nqchip ? ERESTART : ENOMEM; - goto errout; - } - if (len == MHLEN) { - err = m_dup_pkthdr(m, re->re_src_m, - M_DONTWAIT); - if (err) { - m_free(m); - goto errout; - } - } - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - safestats.st_nomcl++; - err = sc->sc_nqchip ? - ERESTART : ENOMEM; - goto errout; - } - len = MCLBYTES; - } - m->m_len = len; - top = NULL; - mp = ⊤ - - while (totlen > 0) { - if (top) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(top); - safestats.st_nombuf++; - err = sc->sc_nqchip ? - ERESTART : ENOMEM; - goto errout; - } - len = MLEN; - } - if (top && totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - *mp = m; - m_freem(top); - safestats.st_nomcl++; - err = sc->sc_nqchip ? - ERESTART : ENOMEM; - goto errout; - } - len = MCLBYTES; - } - m->m_len = len = min(totlen, len); - totlen -= len; - *mp = m; - mp = &m->m_next; - } - re->re_dst_m = top; - if (bus_dmamap_create(sc->sc_dmat, - SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, - BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_dst_map) != 0) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, - re->re_dst_map, re->re_dst_m, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - re->re_dst_map); - re->re_dst_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - if (re->re_src_mapsize > oplen) { - /* - * There's data following what the - * hardware will copy for us. If this - * isn't just the ICV (that's going to - * be written on completion), copy it - * to the new mbufs - */ - if (!(maccrd && - (re->re_src_mapsize-oplen) == 12 && - maccrd->crd_inject == oplen)) - safe_mcopy(re->re_src_m, - re->re_dst_m, - oplen); - else - safestats.st_noicvcopy++; - } - } - } else { - safestats.st_badflags++; - err = EINVAL; - goto errout; - } - - if (re->re_dst_nsegs > 1) { - re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr + - ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring); - for (i = 0; i < re->re_dst_nsegs; i++) { - pd = sc->sc_dpfree; - KASSERT_X((pd->pd_flags&3) == 0 || - (pd->pd_flags&3) == SAFE_PD_DONE, - ("bogus dest particle descriptor; flags %x", - pd->pd_flags)); - if (++(sc->sc_dpfree) == sc->sc_dpringtop) - sc->sc_dpfree = sc->sc_dpring; - pd->pd_addr = re->re_dst_segs[i].ds_addr; - pd->pd_ctrl = SAFE_PD_READY; - } - cmd0 |= SAFE_SA_CMD0_OSCATTER; - } else { - /* - * No need for scatter, reference the operand directly. - */ - re->re_desc.d_dst = re->re_dst_segs[0].ds_addr; - } - } - - /* - * All done with setup; fillin the SA command words - * and the packet engine descriptor. The operation - * is now ready for submission to the hardware. - */ - sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI; - sa->sa_cmd1 = cmd1 - | (coffset << SAFE_SA_CMD1_OFFSET_S) - | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */ - | SAFE_SA_CMD1_SRPCI; - - /* - * NB: the order of writes is important here. In case the - * chip is scanning the ring because of an outstanding request - * it might nab this one too. In that case we need to make - * sure the setup is complete before we write the length - * field of the descriptor as it signals the descriptor is - * ready for processing. - */ - re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI; - if (maccrd) - re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL; - re->re_desc.d_len = oplen - | SAFE_PE_LEN_READY - | (bypass << SAFE_PE_LEN_BYPASS_S) - ; - - safestats.st_ipackets++; - safestats.st_ibytes += oplen; - - if (++(sc->sc_front) == sc->sc_ringtop) - sc->sc_front = sc->sc_ring; - - /* XXX honor batching */ - safe_feed(sc, re); - splx(s); - return (0); - -errout: - if ((re->re_dst_m != NULL) && (re->re_src_m != re->re_dst_m)) - m_freem(re->re_dst_m); - - if (re->re_dst_map != NULL && re->re_dst_map != re->re_src_map) { - bus_dmamap_unload(sc->sc_dmat, re->re_dst_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_dst_map); - } - if (re->re_src_map != NULL) { - bus_dmamap_unload(sc->sc_dmat, re->re_src_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - } - crp->crp_etype = err; - crypto_done(crp); - splx(s); - return (err); -} - -/* - * Resets the board. Values in the regesters are left as is - * from the reset (i.e. initial values are assigned elsewhere). - */ -void -safe_reset_board(struct safe_softc *sc) -{ - u_int32_t v; - - /* - * Reset the device. The manual says no delay - * is needed between marking and clearing reset. - */ - v = READ_REG(sc, SAFE_PE_DMACFG) & - ~(SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET | - SAFE_PE_DMACFG_SGRESET); - WRITE_REG(sc, SAFE_PE_DMACFG, v - | SAFE_PE_DMACFG_PERESET - | SAFE_PE_DMACFG_PDRRESET - | SAFE_PE_DMACFG_SGRESET); - WRITE_REG(sc, SAFE_PE_DMACFG, v); -} - -/* - * Initialize registers we need to touch only once. - */ -void -safe_init_board(struct safe_softc *sc) -{ - u_int32_t v, dwords; - - v = READ_REG(sc, SAFE_PE_DMACFG); - v &= ~(SAFE_PE_DMACFG_PEMODE | SAFE_PE_DMACFG_ESPACKET); - v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */ - | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */ - | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */ - | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */ - | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */ - | SAFE_PE_DMACFG_ESSA /* endian-swap SA data */ - ; - WRITE_REG(sc, SAFE_PE_DMACFG, v); - - WRITE_REG(sc, SAFE_CRYPTO_CTRL, SAFE_CRYPTO_CTRL_PKEY | - SAFE_CRYPTO_CTRL_3DES | SAFE_CRYPTO_CTRL_RNG); - -#if BYTE_ORDER == LITTLE_ENDIAN - WRITE_REG(sc, SAFE_ENDIAN, SAFE_ENDIAN_TGT_PASS|SAFE_ENDIAN_DMA_PASS); -#elif BYTE_ORDER == BIG_ENDIAN - WRITE_REG(sc, SAFE_ENDIAN, SAFE_ENDIAN_TGT_PASS|SAFE_ENDIAN_DMA_SWAB); -#endif - - if (sc->sc_chiprev == SAFE_REV(1,0)) { - /* - * Avoid large PCI DMA transfers. Rev 1.0 has a bug where - * "target mode transfers" done while the chip is DMA'ing - * >1020 bytes cause the hardware to lockup. To avoid this - * we reduce the max PCI transfer size and use small source - * particle descriptors (<= 256 bytes). - */ - WRITE_REG(sc, SAFE_DMA_CFG, 256); - printf("%s: Reduce max DMA size to %u words for rev %u.%u WAR\n", - sc->sc_dev.dv_xname, - (READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff, - SAFE_REV_MAJ(sc->sc_chiprev), - SAFE_REV_MIN(sc->sc_chiprev)); - } - - /* NB: operands+results are overlaid */ - WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr); - WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr); - /* - * Configure ring entry size and number of items in the ring. - */ - KASSERT_X((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0, - ("PE ring entry not 32-bit aligned!")); - dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t); - WRITE_REG(sc, SAFE_PE_RINGCFG, - (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE); - WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */ - - WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr); - WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr); - WRITE_REG(sc, SAFE_PE_PARTSIZE, - (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART); - /* - * NB: destination particles are fixed size. We use - * an mbuf cluster and require all results go to - * clusters or smaller. - */ - WRITE_REG(sc, SAFE_PE_PARTCFG, SAFE_MAX_DSIZE); - - WRITE_REG(sc, SAFE_HI_CLR, SAFE_INT_PE_CDONE | SAFE_INT_PE_DDONE | - SAFE_INT_PE_ERROR | SAFE_INT_PE_ODONE); - - /* it's now safe to enable PE mode, do it */ - WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE); - - /* - * Configure hardware to use level-triggered interrupts and - * to interrupt after each descriptor is processed. - */ - DELAY(1000); - WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL); - DELAY(1000); - WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR); - DELAY(1000); - WRITE_REG(sc, SAFE_HI_DESC_CNT, 1); - DELAY(1000); -} - -/* - * Init PCI registers - */ -void -safe_init_pciregs(struct safe_softc *sc) -{ -} - -int -safe_dma_malloc(struct safe_softc *sc, bus_size_t size, - struct safe_dma_alloc *dma, int mapflags) -{ - int r; - - if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, - &dma->dma_seg, 1, &dma->dma_nseg, BUS_DMA_NOWAIT)) != 0) - goto fail_0; - - if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg, - size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0) - goto fail_1; - - if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_NOWAIT, &dma->dma_map)) != 0) - goto fail_2; - - if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr, - size, NULL, BUS_DMA_NOWAIT)) != 0) - goto fail_3; - - dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr; - dma->dma_size = size; - return (0); - -fail_3: - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -fail_2: - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size); -fail_1: - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); -fail_0: - dma->dma_map = NULL; - return (r); -} - -void -safe_dma_free(struct safe_softc *sc, struct safe_dma_alloc *dma) -{ - bus_dmamap_unload(sc->sc_dmat, dma->dma_map); - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size); - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -} - - -#define SAFE_RNG_MAXWAIT 1000 - -void -safe_rng_init(struct safe_softc *sc) -{ - u_int32_t w, v; - int i; - - WRITE_REG(sc, SAFE_RNG_CTRL, 0); - /* use default value according to the manual */ - WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */ - WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0); - - /* - * There is a bug in rev 1.0 of the 1140 that when the RNG - * is brought out of reset the ready status flag does not - * work until the RNG has finished its internal initialization. - * - * So in order to determine the device is through its - * initialization we must read the data register, using the - * status reg in the read in case it is initialized. Then read - * the data register until it changes from the first read. - * Once it changes read the data register until it changes - * again. At this time the RNG is considered initialized. - * This could take between 750ms - 1000ms in time. - */ - i = 0; - w = READ_REG(sc, SAFE_RNG_OUT); - do { - v = READ_REG(sc, SAFE_RNG_OUT); - if (v != w) { - w = v; - break; - } - DELAY(10); - } while (++i < SAFE_RNG_MAXWAIT); - - /* Wait Until data changes again */ - i = 0; - do { - v = READ_REG(sc, SAFE_RNG_OUT); - if (v != w) - break; - DELAY(10); - } while (++i < SAFE_RNG_MAXWAIT); -} - -static __inline u_int32_t -safe_rng_read(struct safe_softc *sc) -{ - int i; - - i = 0; - while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT) - ; - return (READ_REG(sc, SAFE_RNG_OUT)); -} - -void -safe_rng(void *arg) -{ - struct safe_softc *sc = arg; - u_int32_t buf[SAFE_RNG_MAXBUFSIZ]; /* NB: maybe move to softc */ - u_int maxwords; - int i; - - safestats.st_rng++; - /* - * Fetch the next block of data. - */ - maxwords = safe_rngbufsize; - if (maxwords > SAFE_RNG_MAXBUFSIZ) - maxwords = SAFE_RNG_MAXBUFSIZ; -retry: - for (i = 0; i < maxwords; i++) - buf[i] = safe_rng_read(sc); - /* - * Check the comparator alarm count and reset the h/w if - * it exceeds our threshold. This guards against the - * hardware oscillators resonating with external signals. - */ - if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) { - u_int32_t freq_inc, w; - - DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__, - READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm)); - safestats.st_rngalarm++; - WRITE_REG(sc, SAFE_RNG_CTRL, - READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN); - freq_inc = 18; - for (i = 0; i < 64; i++) { - w = READ_REG(sc, SAFE_RNG_CNFG); - freq_inc = ((w + freq_inc) & 0x3fL); - w = ((w & ~0x3fL) | freq_inc); - WRITE_REG(sc, SAFE_RNG_CNFG, w); - - WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0); - - (void) safe_rng_read(sc); - DELAY(25); - - if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) { - WRITE_REG(sc, SAFE_RNG_CTRL, - READ_REG(sc, SAFE_RNG_CTRL) & - ~SAFE_RNG_CTRL_SHORTEN); - goto retry; - } - freq_inc = 1; - } - WRITE_REG(sc, SAFE_RNG_CTRL, - READ_REG(sc, SAFE_RNG_CTRL) & ~SAFE_RNG_CTRL_SHORTEN); - } else - WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0); - - for (i = 0; i < maxwords; i++) - enqueue_randomness(buf[i]); - - timeout_add_sec(&sc->sc_rngto, safe_rnginterval); -} - -/* - * Allocate a new 'session' and return an encoded session id. 'sidp' - * contains our registration id, and should contain an encoded session - * id on successful allocation. - */ -int -safe_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct cryptoini *c, *encini = NULL, *macini = NULL; - struct safe_softc *sc = NULL; - struct safe_session *ses = NULL; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; - int i, sesn; - - if (sidp == NULL || cri == NULL) - return (EINVAL); - for (i = 0; i < safe_cd.cd_ndevs; i++) { - sc = safe_cd.cd_devs[i]; - if (sc == NULL || sc->sc_cid == (*sidp)) - break; - } - if (sc == NULL) - return (EINVAL); - - for (c = cri; c != NULL; c = c->cri_next) { - if (c->cri_alg == CRYPTO_MD5_HMAC || - c->cri_alg == CRYPTO_SHA1_HMAC) { - if (macini) - return (EINVAL); - macini = c; - } else if (c->cri_alg == CRYPTO_3DES_CBC || - c->cri_alg == CRYPTO_AES_CBC) { - if (encini) - return (EINVAL); - encini = c; - } else - return (EINVAL); - } - if (encini == NULL && macini == NULL) - return (EINVAL); - if (encini) { /* validate key length */ - switch (encini->cri_alg) { - case CRYPTO_3DES_CBC: - if (encini->cri_klen != 192) - return (EINVAL); - break; - case CRYPTO_AES_CBC: - if (encini->cri_klen != 128 && - encini->cri_klen != 192 && - encini->cri_klen != 256) - return (EINVAL); - break; - } - } - - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct safe_session *)malloc( - sizeof(struct safe_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - sesn = 0; - sc->sc_nsessions = 1; - } else { - for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { - if (sc->sc_sessions[sesn].ses_used == 0) { - ses = &sc->sc_sessions[sesn]; - break; - } - } - - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = mallocarray((sesn + 1), - sizeof(struct safe_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * - sizeof(struct safe_session)); - explicit_bzero(sc->sc_sessions, sesn * - sizeof(struct safe_session)); - free(sc->sc_sessions, M_DEVBUF, 0); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - - bzero(ses, sizeof(struct safe_session)); - ses->ses_used = 1; - - if (encini) { - ses->ses_klen = encini->cri_klen; - bcopy(encini->cri_key, ses->ses_key, ses->ses_klen / 8); - - for (i = 0; i < nitems(ses->ses_key); i++) - ses->ses_key[i] = htole32(ses->ses_key[i]); - } - - if (macini) { - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_IPAD_VAL; - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_ipad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hminner, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_ipad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hminner, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_opad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hmouter, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_opad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hmouter, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_OPAD_VAL; - - /* PE is little-endian, insure proper byte order */ - for (i = 0; - i < sizeof(ses->ses_hminner)/sizeof(ses->ses_hminner[0]); - i++) { - ses->ses_hminner[i] = htole32(ses->ses_hminner[i]); - ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]); - } - } - - *sidp = SAFE_SID(sc->sc_dev.dv_unit, sesn); - return (0); -} - -/* - * Deallocate a session. - */ -int -safe_freesession(u_int64_t tid) -{ - struct safe_softc *sc; - int session, ret, card; - u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; - - card = SAFE_CARD(sid); - if (card >= safe_cd.cd_ndevs || safe_cd.cd_devs[card] == NULL) - return (EINVAL); - sc = safe_cd.cd_devs[card]; - - if (sc == NULL) - return (EINVAL); - - session = SAFE_SESSION(sid); - if (session < sc->sc_nsessions) { - explicit_bzero(&sc->sc_sessions[session], - sizeof(sc->sc_sessions[session])); - ret = 0; - } else - ret = EINVAL; - return (ret); -} - -/* - * Is the operand suitable aligned for direct DMA. Each - * segment must be aligned on a 32-bit boundary and all - * but the last segment must be a multiple of 4 bytes. - */ -int -safe_dmamap_aligned(const struct safe_operand *op) -{ - int i; - - for (i = 0; i < op->map->dm_nsegs; i++) { - if (op->map->dm_segs[i].ds_addr & 3) - return (0); - if (i != (op->map->dm_nsegs - 1) && - (op->map->dm_segs[i].ds_len & 3)) - return (0); - } - return (1); -} - -/* - * Clean up after a chip crash. - * It is assumed that the caller in splnet() - */ -void -safe_cleanchip(struct safe_softc *sc) -{ - - if (sc->sc_nqchip != 0) { - struct safe_ringentry *re = sc->sc_back; - - while (re != sc->sc_front) { - if (re->re_desc.d_csr != 0) - safe_free_entry(sc, re); - if (++re == sc->sc_ringtop) - re = sc->sc_ring; - } - sc->sc_back = re; - sc->sc_nqchip = 0; - } -} - -/* - * free a safe_q - * It is assumed that the caller is within splnet(). - */ -int -safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re) -{ - struct cryptop *crp; - - /* - * Free header MCR - */ - if ((re->re_dst_m != NULL) && (re->re_src_m != re->re_dst_m)) - m_freem(re->re_dst_m); - - crp = (struct cryptop *)re->re_crp; - - re->re_desc.d_csr = 0; - - crp->crp_etype = EFAULT; - crypto_done(crp); - return (0); -} - -/* - * safe_feed() - post a request to chip - */ -void -safe_feed(struct safe_softc *sc, struct safe_ringentry *re) -{ - bus_dmamap_sync(sc->sc_dmat, re->re_src_map, - 0, re->re_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (re->re_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, re->re_dst_map, 0, - re->re_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - /* XXX have no smaller granularity */ - safe_dma_sync(sc, &sc->sc_ringalloc, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - safe_dma_sync(sc, &sc->sc_spalloc, BUS_DMASYNC_PREWRITE); - safe_dma_sync(sc, &sc->sc_dpalloc, BUS_DMASYNC_PREWRITE); - -#ifdef SAFE_DEBUG - if (safe_debug) { - safe_dump_ringstate(sc, __func__); - safe_dump_request(sc, __func__, re); - } -#endif - sc->sc_nqchip++; - if (sc->sc_nqchip > safestats.st_maxqchip) - safestats.st_maxqchip = sc->sc_nqchip; - /* poke h/w to check descriptor ring, any value can be written */ - WRITE_REG(sc, SAFE_HI_RD_DESCR, 0); -} - -/* - * Is the operand suitable for direct DMA as the destination - * of an operation. The hardware requires that each ``particle'' - * but the last in an operation result have the same size. We - * fix that size at SAFE_MAX_DSIZE bytes. This routine returns - * 0 if some segment is not a multiple of this size, 1 if all - * segments are exactly this size, or 2 if segments are at worst - * a multple of this size. - */ -int -safe_dmamap_uniform(const struct safe_operand *op) -{ - int result = 1, i; - - if (op->map->dm_nsegs <= 0) - return (result); - - for (i = 0; i < op->map->dm_nsegs-1; i++) { - if (op->map->dm_segs[i].ds_len % SAFE_MAX_DSIZE) - return (0); - if (op->map->dm_segs[i].ds_len != SAFE_MAX_DSIZE) - result = 2; - } - return (result); -} - -/* - * Copy all data past offset from srcm to dstm. - */ -void -safe_mcopy(struct mbuf *srcm, struct mbuf *dstm, u_int offset) -{ - u_int j, dlen, slen; - caddr_t dptr, sptr; - - /* - * Advance src and dst to offset. - */ - for (j = offset; srcm->m_len <= j;) { - j -= srcm->m_len; - srcm = srcm->m_next; - if (srcm == NULL) - return; - } - sptr = mtod(srcm, caddr_t) + j; - slen = srcm->m_len - j; - - for (j = offset; dstm->m_len <= j;) { - j -= dstm->m_len; - dstm = dstm->m_next; - if (dstm == NULL) - return; - } - dptr = mtod(dstm, caddr_t) + j; - dlen = dstm->m_len - j; - - /* - * Copy everything that remains. - */ - for (;;) { - j = min(slen, dlen); - bcopy(sptr, dptr, j); - if (slen == j) { - srcm = srcm->m_next; - if (srcm == NULL) - return; - sptr = srcm->m_data; - slen = srcm->m_len; - } else - sptr += j, slen -= j; - if (dlen == j) { - dstm = dstm->m_next; - if (dstm == NULL) - return; - dptr = dstm->m_data; - dlen = dstm->m_len; - } else - dptr += j, dlen -= j; - } -} - -void -safe_callback(struct safe_softc *sc, struct safe_ringentry *re) -{ - struct cryptop *crp = (struct cryptop *)re->re_crp; - struct cryptodesc *crd; - int i; - - safestats.st_opackets++; - safestats.st_obytes += (re->re_dst_map == NULL) ? - re->re_src_mapsize : re->re_dst_mapsize; - - safe_dma_sync(sc, &sc->sc_ringalloc, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) { - printf("%s: csr 0x%x cmd0 0x%x cmd1 0x%x\n", - sc->sc_dev.dv_xname, re->re_desc.d_csr, - re->re_sa.sa_cmd0, re->re_sa.sa_cmd1); - safestats.st_peoperr++; - crp->crp_etype = EIO; /* something more meaningful? */ - } - if (re->re_dst_map != NULL && re->re_dst_map != re->re_src_map) { - bus_dmamap_sync(sc->sc_dmat, re->re_dst_map, 0, - re->re_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, re->re_dst_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_dst_map); - } - bus_dmamap_sync(sc->sc_dmat, re->re_src_map, 0, - re->re_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, re->re_src_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - - /* - * If result was written to a different mbuf chain, swap - * it in as the return value and reclaim the original. - */ - if ((crp->crp_flags & CRYPTO_F_IMBUF) && re->re_src_m != re->re_dst_m) { - m_freem(re->re_src_m); - crp->crp_buf = (caddr_t)re->re_dst_m; - } - - if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) { - /* copy out ICV result */ - for (i = 0; i < crp->crp_ndesc; i++) { - crd = &crp->crp_desc[i]; - if (!(crd->crd_alg == CRYPTO_MD5_HMAC || - crd->crd_alg == CRYPTO_SHA1_HMAC)) - continue; - if (crd->crd_alg == CRYPTO_SHA1_HMAC) { - /* - * SHA-1 ICV's are byte-swapped; fix 'em up - * before copy them to their destination. - */ - bswap32(re->re_sastate.sa_saved_indigest[0]); - bswap32(re->re_sastate.sa_saved_indigest[1]); - bswap32(re->re_sastate.sa_saved_indigest[2]); - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - crp->crp_etype = - m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, 12, - (caddr_t)re->re_sastate.sa_saved_indigest, - M_NOWAIT); - } else if (crp->crp_flags & CRYPTO_F_IOV && crp->crp_mac) { - bcopy((caddr_t)re->re_sastate.sa_saved_indigest, - crp->crp_mac, 12); - } - break; - } - } - - crypto_done(crp); -} - -/* - * SafeXcel Interrupt routine - */ -int -safe_intr(void *arg) -{ - struct safe_softc *sc = arg; - volatile u_int32_t stat; - - stat = READ_REG(sc, SAFE_HM_STAT); - if (stat == 0) /* shared irq, not for us */ - return (0); - - WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */ - - if ((stat & SAFE_INT_PE_DDONE)) { - /* - * Descriptor(s) done; scan the ring and - * process completed operations. - */ - while (sc->sc_back != sc->sc_front) { - struct safe_ringentry *re = sc->sc_back; -#ifdef SAFE_DEBUG - if (safe_debug) { - safe_dump_ringstate(sc, __func__); - safe_dump_request(sc, __func__, re); - } -#endif - /* - * safe_process marks ring entries that were allocated - * but not used with a csr of zero. This insures the - * ring front pointer never needs to be set backwards - * in the event that an entry is allocated but not used - * because of a setup error. - */ - if (re->re_desc.d_csr != 0) { - if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) - break; - if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) - break; - sc->sc_nqchip--; - safe_callback(sc, re); - } - if (++(sc->sc_back) == sc->sc_ringtop) - sc->sc_back = sc->sc_ring; - } - } - - return (1); -} - -#ifdef SAFE_DEBUG - -void -safe_dump_dmastatus(struct safe_softc *sc, const char *tag) -{ - printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n", tag, - READ_REG(sc, SAFE_DMA_ENDIAN), READ_REG(sc, SAFE_DMA_SRCADDR), - READ_REG(sc, SAFE_DMA_DSTADDR), READ_REG(sc, SAFE_DMA_STAT)); -} - -void -safe_dump_intrstate(struct safe_softc *sc, const char *tag) -{ - printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n", - tag, READ_REG(sc, SAFE_HI_CFG), READ_REG(sc, SAFE_HI_MASK), - READ_REG(sc, SAFE_HI_DESC_CNT), READ_REG(sc, SAFE_HU_STAT), - READ_REG(sc, SAFE_HM_STAT)); -} - -void -safe_dump_ringstate(struct safe_softc *sc, const char *tag) -{ - u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT); - - /* NB: assume caller has lock on ring */ - printf("%s: ERNGSTAT %x (next %u) back %u front %u\n", - tag, estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S), - sc->sc_back - sc->sc_ring, sc->sc_front - sc->sc_ring); -} - -void -safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re) -{ - int ix, nsegs; - - ix = re - sc->sc_ring; - printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n", tag, - re, ix, re->re_desc.d_csr, re->re_desc.d_src, re->re_desc.d_dst, - re->re_desc.d_sa, re->re_desc.d_len); - if (re->re_src_nsegs > 1) { - ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) / - sizeof(struct safe_pdesc); - for (nsegs = re->re_src_nsegs; nsegs; nsegs--) { - printf(" spd[%u] %p: %p", ix, - &sc->sc_spring[ix], - (caddr_t)sc->sc_spring[ix].pd_addr); - printf("\n"); - if (++ix == SAFE_TOTAL_SPART) - ix = 0; - } - } - if (re->re_dst_nsegs > 1) { - ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) / - sizeof(struct safe_pdesc); - for (nsegs = re->re_dst_nsegs; nsegs; nsegs--) { - printf(" dpd[%u] %p: %p\n", ix, - &sc->sc_dpring[ix], - (caddr_t) sc->sc_dpring[ix].pd_addr); - if (++ix == SAFE_TOTAL_DPART) - ix = 0; - } - } - printf("sa: cmd0 %08x cmd1 %08x staterec %x\n", - re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec); - printf("sa: key %x %x %x %x %x %x %x %x\n", re->re_sa.sa_key[0], - re->re_sa.sa_key[1], re->re_sa.sa_key[2], re->re_sa.sa_key[3], - re->re_sa.sa_key[4], re->re_sa.sa_key[5], re->re_sa.sa_key[6], - re->re_sa.sa_key[7]); - printf("sa: indigest %x %x %x %x %x\n", re->re_sa.sa_indigest[0], - re->re_sa.sa_indigest[1], re->re_sa.sa_indigest[2], - re->re_sa.sa_indigest[3], re->re_sa.sa_indigest[4]); - printf("sa: outdigest %x %x %x %x %x\n", re->re_sa.sa_outdigest[0], - re->re_sa.sa_outdigest[1], re->re_sa.sa_outdigest[2], - re->re_sa.sa_outdigest[3], re->re_sa.sa_outdigest[4]); - printf("sr: iv %x %x %x %x\n", - re->re_sastate.sa_saved_iv[0], re->re_sastate.sa_saved_iv[1], - re->re_sastate.sa_saved_iv[2], re->re_sastate.sa_saved_iv[3]); - printf("sr: hashbc %u indigest %x %x %x %x %x\n", - re->re_sastate.sa_saved_hashbc, - re->re_sastate.sa_saved_indigest[0], - re->re_sastate.sa_saved_indigest[1], - re->re_sastate.sa_saved_indigest[2], - re->re_sastate.sa_saved_indigest[3], - re->re_sastate.sa_saved_indigest[4]); -} - -void -safe_dump_ring(struct safe_softc *sc, const char *tag) -{ - printf("\nSafeNet Ring State:\n"); - safe_dump_intrstate(sc, tag); - safe_dump_dmastatus(sc, tag); - safe_dump_ringstate(sc, tag); - if (sc->sc_nqchip) { - struct safe_ringentry *re = sc->sc_back; - do { - safe_dump_request(sc, tag, re); - if (++re == sc->sc_ringtop) - re = sc->sc_ring; - } while (re != sc->sc_front); - } -} - -#endif /* SAFE_DEBUG */ diff --git a/sys/dev/pci/safereg.h b/sys/dev/pci/safereg.h deleted file mode 100644 index 32e38e76f0e..00000000000 --- a/sys/dev/pci/safereg.h +++ /dev/null @@ -1,413 +0,0 @@ -/* $OpenBSD: safereg.h,v 1.5 2009/05/23 15:27:31 jsg Exp $ */ - -/*- - * Copyright (c) 2003 Sam Leffler, Errno Consulting - * Copyright (c) 2003 Global Technology Associates, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $ - */ -#ifndef _SAFE_SAFEREG_H_ -#define _SAFE_SAFEREG_H_ - -/* - * Register definitions for SafeNet SafeXcel-1141 crypto device. - * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual. - */ - -#define SAFE_BAR 0x10 /* DMA base address register */ - -#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */ -#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */ -#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */ -#define SAFE_PE_SA 0x000c /* Packet Engine SA */ -#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */ -#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */ -#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */ -#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */ -#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */ -#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */ -#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */ -#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */ -#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */ -#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */ -#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */ -#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */ -#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */ -#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */ -#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */ -#define SAFE_DEVID 0x0084 /* Device ID */ -#define SAFE_DEVINFO 0x0088 /* Device Info */ -#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */ -#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */ -#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */ -#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */ -#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */ -#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */ -#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */ -#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */ -#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */ -#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */ -#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */ -#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */ -#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */ -#define SAFE_RNG_OUT 0x0100 /* RNG Output */ -#define SAFE_RNG_STAT 0x0104 /* RNG Status */ -#define SAFE_RNG_CTRL 0x0108 /* RNG Control */ -#define SAFE_RNG_A 0x010c /* RNG A */ -#define SAFE_RNG_B 0x0110 /* RNG B */ -#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */ -#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */ -#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */ -#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */ -#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */ -#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */ -#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */ -#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */ -#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */ -#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */ -#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */ -#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */ -#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */ -#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */ -#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */ -#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */ -#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */ -#define SAFE_PK_FUNC 0x081c /* Public Key Function */ -#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */ -#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */ - -#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */ -#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */ -#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */ -#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */ -#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */ -#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */ -#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */ -#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */ -#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */ -#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */ -#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */ -#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */ -#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */ -#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */ -#define SAFE_PE_CSR_XECODE_S 20 -#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */ -#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */ -#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */ -#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */ -#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */ -#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */ -#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */ -#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */ -#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */ -#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */ -#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */ -#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */ -#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */ -#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */ -#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */ - -/* - * Check the CSR to see if the PE has returned ownership to - * the host. Note that before processing a descriptor this - * must be done followed by a check of the SAFE_PE_LEN register - * status bits to avoid premature processing of a descriptor - * on its way back to the host. - */ -#define SAFE_PE_CSR_IS_DONE(_csr) \ - (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE) - -#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */ -#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */ -#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */ -#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */ -#define SAFE_PE_LEN_BYPASS_S 24 - -#define SAFE_PE_LEN_IS_DONE(_len) \ - (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE) - -/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */ -#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */ -#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */ -#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */ -#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */ - -#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */ -#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */ -#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */ - -#define SAFE_ENDIAN_TGT_PASS 0x00e40000 /* target pass-thru */ -#define SAFE_ENDIAN_TGT_SWAB 0x001b0000 /* target swap32 */ -#define SAFE_ENDIAN_DMA_PASS 0x000000e4 /* DMA pass-thru */ -#define SAFE_ENDIAN_DMA_SWAB 0x0000001b /* DMA swap32 */ - -#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */ -#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */ -#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */ -#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */ -#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */ -#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */ -#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */ -#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */ -#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */ -#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */ -#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */ -#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */ -#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */ -#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */ -#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */ -#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */ -#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */ - -#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */ -#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */ -#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */ -#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */ -#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */ -#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */ -#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */ -#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */ -#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */ -#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */ -#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */ -#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */ -#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */ -#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */ - -#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */ -#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */ -#define SAFE_PE_RINGCFG_OFFSET_S 16 - -#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */ -#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */ -#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */ - -#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */ - -#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */ -#define SAFE_PE_ERNGSTAT_NEXT_S 16 - -#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */ -#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */ - -#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */ -#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */ -#define SAFE_PE_PARTCFG_GBURST_2 0x00000000 -#define SAFE_PE_PARTCFG_GBURST_4 0x00010000 -#define SAFE_PE_PARTCFG_GBURST_8 0x00020000 -#define SAFE_PE_PARTCFG_GBURST_16 0x00030000 -#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */ -#define SAFE_PE_PARTCFG_SBURST_2 0x00000000 -#define SAFE_PE_PARTCFG_SBURST_4 0x00040000 -#define SAFE_PE_PARTCFG_SBURST_8 0x00080000 -#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000 - -#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */ -#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */ - -#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */ -#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */ -#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */ - -#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */ -#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */ -#define SAFE_DEVINFO_REV_MAJ_S 4 -#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */ -#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */ -#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */ -#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */ -#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */ -#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */ -#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */ -#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */ -#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */ -#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */ -#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */ - -#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min)) -#define SAFE_REV_MAJ(_chiprev) \ - (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S) -#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN) - -#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */ -#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */ -#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */ -#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */ -#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */ -#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */ -#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */ -#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */ -#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */ -#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */ -#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */ -#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */ - -#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */ - -#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */ -#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */ -#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */ -#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */ -#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */ -#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */ -#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */ -#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */ -#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */ -#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */ - -/* - * Packet engine descriptor. Note that d_csr is a copy of the - * SAFE_PE_CSR register and all definitions apply, and d_len - * is a copy of the SAFE_PE_LEN register and all definitions apply. - * d_src and d_len may point directly to contiguous data or to a - * list of ``particle descriptors'' when using scatter/gather i/o. - */ -struct safe_desc { - volatile u_int32_t d_csr; /* per-packet control/status */ - volatile u_int32_t d_src; /* source address */ - volatile u_int32_t d_dst; /* destination address */ - volatile u_int32_t d_sa; /* SA address */ - volatile u_int32_t d_len; /* length, bypass, status */ -}; - -/* - * Scatter/Gather particle descriptor. - * - * NB: scatter descriptors do not specify a size; this is fixed - * by the setting of the SAFE_PE_PARTCFG register. - */ -struct safe_pdesc { - volatile u_int32_t pd_addr; /* particle address */ - volatile u_int32_t pd_ctrl; /* length/flags */ -}; - -#define SAFE_PD_LEN_M 0xffff0000 /* length mask */ -#define SAFE_PD_LEN_S 16 -#define SAFE_PD_READY 0x00000001 /* ready for processing */ -#define SAFE_PD_DONE 0x00000002 /* h/w completed processing */ - -/* - * Security Association (SA) Record (Rev 1). One of these is - * required for each operation processed by the packet engine. - */ -struct safe_sarec { - volatile u_int32_t sa_cmd0; - volatile u_int32_t sa_cmd1; - volatile u_int32_t sa_resv0; - volatile u_int32_t sa_resv1; - volatile u_int32_t sa_key[8]; /* DES/3DES/AES key */ - volatile u_int32_t sa_indigest[5]; /* inner digest */ - volatile u_int32_t sa_outdigest[5];/* outer digest */ - volatile u_int32_t sa_spi; /* SPI */ - volatile u_int32_t sa_seqnum; /* sequence number */ - volatile u_int32_t sa_seqmask[2]; /* sequence number mask */ - volatile u_int32_t sa_resv2; - volatile u_int32_t sa_staterec; /* address of state record */ - volatile u_int32_t sa_resv3[2]; - volatile u_int32_t sa_samgmt0; /* SA management field 0 */ - volatile u_int32_t sa_samgmt1; /* SA management field 0 */ -}; - -#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */ -#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */ -#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */ -#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */ -#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */ -#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */ -#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */ -#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */ -#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */ -#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */ -#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */ -#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */ -#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */ -#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */ -#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */ -#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */ -#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */ -#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */ -#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */ -#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */ -#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */ -#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */ -#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */ -#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */ -#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */ -#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */ -#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */ -#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */ -#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */ -#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */ -#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */ -#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */ -#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */ -#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */ -#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */ -#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */ -#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */ -#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */ -#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */ -#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */ -#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */ -#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */ -#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */ - -#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */ -#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */ -#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */ -#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */ -#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */ -#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */ -#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */ -#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */ -#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */ -#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */ -#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */ -#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */ -#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */ -#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */ -#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */ -#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */ -#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */ -#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */ -#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */ -#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS -#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */ -#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */ -#define SAFE_SA_CMD1_OFFSET_S 16 -#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */ -#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */ -#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */ -#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */ - -/* - * Security Associate State Record (Rev 1). - */ -struct safe_sastate { - volatile u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */ - volatile u_int32_t sa_saved_hashbc;/* saved hash byte count */ - volatile u_int32_t sa_saved_indigest[5]; /* saved inner digest */ -}; -#endif /* _SAFE_SAFEREG_H_ */ diff --git a/sys/dev/pci/safevar.h b/sys/dev/pci/safevar.h deleted file mode 100644 index 5066a000bdf..00000000000 --- a/sys/dev/pci/safevar.h +++ /dev/null @@ -1,205 +0,0 @@ -/* $OpenBSD: safevar.h,v 1.9 2014/08/15 15:43:27 mikeb Exp $ */ - -/*- - * Copyright (c) 2003 Sam Leffler, Errno Consulting - * Copyright (c) 2003 Global Technology Associates, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safevar.h,v 1.1 2003/07/21 21:46:07 sam Exp $ - */ -#ifndef _SAFE_SAFEVAR_H_ -#define _SAFE_SAFEVAR_H_ - -/* public key parameter locations */ -#define SAFE_CRK_PARAM_BASE 0 -#define SAFE_CRK_PARAM_EXP 1 -#define SAFE_CRK_PARAM_MOD 2 - -/* Maximum queue length */ -#ifndef SAFE_MAX_NQUEUE -#define SAFE_MAX_NQUEUE 60 -#endif - -#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */ -#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */ -#define SAFE_MAX_DSIZE MCLBYTES /* Fixed scatter particle size */ -#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */ -#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */ -/* total src+dst particle descriptors */ -#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART) -#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART) - -#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */ - -#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28) -#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff) -#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff)) - -#ifdef _KERNEL -/* - * State associated with the allocation of each chunk - * of memory setup for DMA. - */ -struct safe_dma_alloc { - u_int32_t dma_paddr; /* physical address */ - caddr_t dma_vaddr; /* virtual address */ - bus_dmamap_t dma_map; /* associated map */ - bus_dma_segment_t dma_seg; - bus_size_t dma_size; /* mapped memory size (bytes) */ - int dma_nseg; /* number of segments */ -}; - -/* - * Cryptographic operand state. One of these exists for each - * source and destination operand passed in from the crypto - * subsystem. When possible source and destination operands - * refer to the same memory. More often they are distinct. - * We track the virtual address of each operand as well as - * where each is mapped for DMA. - */ -struct safe_operand { - union { - struct mbuf *m; - struct uio *io; - } u; - bus_dmamap_t map; -}; - -/* - * Packet engine ring entry and cryptographic operation state. - * The packet engine requires a ring of descriptors that contain - * pointers to various cryptographic state. However the ring - * configuration register allows you to specify an arbitrary size - * for ring entries. We use this feature to collect most of the - * state for each cryptographic request into one spot. Other than - * ring entries only the ``particle descriptors'' (scatter/gather - * lists) and the actual operand data are kept separate. The - * particle descriptors must also be organized in rings. The - * operand data can be located aribtrarily (modulo alignment constraints). - * - * Note that the descriptor ring is mapped onto the PCI bus so - * the hardware can DMA data. This means the entire ring must be - * contiguous. - */ -struct safe_ringentry { - struct safe_desc re_desc; /* command descriptor */ - struct safe_sarec re_sa; /* SA record */ - struct safe_sastate re_sastate; /* SA state record */ - struct cryptop *re_crp; /* crypto operation */ - - struct safe_operand re_src; /* source operand */ - struct safe_operand re_dst; /* destination operand */ - - int re_sesn; /* crypto session ID */ - int re_flags; -#define SAFE_QFLAGS_COPYOUTICV 0x1 /* copy back on completion */ -}; - -#define re_src_m re_src.u.m -#define re_src_io re_src.u.io -#define re_src_map re_src.map -#define re_src_nsegs re_src.map->dm_nsegs -#define re_src_segs re_src.map->dm_segs -#define re_src_mapsize re_src.map->dm_mapsize - -#define re_dst_m re_dst.u.m -#define re_dst_io re_dst.u.io -#define re_dst_map re_dst.map -#define re_dst_nsegs re_dst.map->dm_nsegs -#define re_dst_segs re_dst.map->dm_segs -#define re_dst_mapsize re_dst.map->dm_mapsize - -struct rndstate_test; - -struct safe_session { - u_int32_t ses_used; - u_int32_t ses_klen; /* key length in bits */ - u_int32_t ses_key[8]; /* DES/3DES/AES key */ - u_int32_t ses_hminner[5]; /* hmac inner state */ - u_int32_t ses_hmouter[5]; /* hmac outer state */ -}; - -struct safe_softc { - struct device sc_dev; /* device backpointer */ - void *sc_ih; /* interrupt handler cookie */ - bus_space_handle_t sc_sh; /* memory handle */ - bus_space_tag_t sc_st; /* memory tag */ - struct resource *sc_sr; /* memory resource */ - bus_dma_tag_t sc_dmat; - u_int sc_chiprev; /* major/minor chip revision */ - int sc_needwakeup; /* notify crypto layer */ - int32_t sc_cid; /* crypto tag */ - struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */ - struct safe_ringentry *sc_ring; /* PE ring */ - struct safe_ringentry *sc_ringtop; /* PE ring top */ - struct safe_ringentry *sc_front; /* next free entry */ - struct safe_ringentry *sc_back; /* next pending entry */ - int sc_nqchip; /* # passed to chip */ - struct safe_pdesc *sc_spring; /* src particle ring */ - struct safe_pdesc *sc_springtop; /* src particle ring top */ - struct safe_pdesc *sc_spfree; /* next free src particle */ - struct safe_dma_alloc sc_spalloc; /* src particle ring state */ - struct safe_pdesc *sc_dpring; /* dest particle ring */ - struct safe_pdesc *sc_dpringtop; /* dest particle ring top */ - struct safe_pdesc *sc_dpfree; /* next free dest particle */ - struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */ - int sc_nsessions; /* # of sessions */ - struct safe_session *sc_sessions; /* sessions */ - - struct timeout sc_rngto; /* rng timeout */ -}; -#endif /* _KERNEL */ - -struct safe_stats { - u_int64_t st_ibytes; - u_int64_t st_obytes; - u_int32_t st_ipackets; - u_int32_t st_opackets; - u_int32_t st_invalid; /* invalid argument */ - u_int32_t st_badsession; /* invalid session id */ - u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */ - u_int32_t st_nodesc; /* op submitted w/o descriptors */ - u_int32_t st_badalg; /* unsupported algorithm */ - u_int32_t st_ringfull; /* PE descriptor ring full */ - u_int32_t st_peoperr; /* PE marked error */ - u_int32_t st_dmaerr; /* PE DMA error */ - u_int32_t st_bypasstoobig; /* bypass > 96 bytes */ - u_int32_t st_skipmismatch; /* enc part begins before auth part */ - u_int32_t st_lenmismatch; /* enc length different auth length */ - u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */ - u_int32_t st_cofftoobig; /* crypto offset > 255 words */ - u_int32_t st_iovmisaligned; /* iov op not aligned */ - u_int32_t st_iovnotuniform; /* iov op not suitable */ - u_int32_t st_unaligned; /* unaligned src caused copy */ - u_int32_t st_notuniform; /* non-uniform src caused copy */ - u_int32_t st_nomap; /* bus_dmamap_create failed */ - u_int32_t st_noload; /* bus_dmamap_load_* failed */ - u_int32_t st_nombuf; /* MGET* failed */ - u_int32_t st_nomcl; /* MCLGET* failed */ - u_int32_t st_maxqchip; /* max mcr1 ops out for processing */ - u_int32_t st_rng; /* RNG requests */ - u_int32_t st_rngalarm; /* RNG alarm requests */ - u_int32_t st_noicvcopy; /* ICV data copies suppressed */ -}; -#endif /* _SAFE_SAFEVAR_H_ */ diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c deleted file mode 100644 index e52cd5911e9..00000000000 --- a/sys/dev/pci/ubsec.c +++ /dev/null @@ -1,1742 +0,0 @@ -/* $OpenBSD: ubsec.c,v 1.168 2021/10/13 13:08:58 bluhm Exp $ */ - -/* - * Copyright (c) 2000 Jason L. Wright (jason@thought.net) - * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org) - * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -#undef UBSEC_DEBUG - -/* - * uBsec 5[56]01, 58xx hardware crypto accelerator - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/timeout.h> -#include <sys/errno.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/mbuf.h> -#include <sys/device.h> -#include <sys/queue.h> - -#include <crypto/cryptodev.h> -#include <crypto/cryptosoft.h> -#include <crypto/md5.h> -#include <crypto/sha1.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -#include <dev/pci/ubsecreg.h> -#include <dev/pci/ubsecvar.h> - -/* - * Prototypes and count for the pci_device structure - */ -int ubsec_probe(struct device *, void *, void *); -void ubsec_attach(struct device *, struct device *, void *); -void ubsec_reset_board(struct ubsec_softc *); -void ubsec_init_board(struct ubsec_softc *); -void ubsec_init_pciregs(struct pci_attach_args *pa); -void ubsec_cleanchip(struct ubsec_softc *); -void ubsec_totalreset(struct ubsec_softc *); -int ubsec_free_q(struct ubsec_softc*, struct ubsec_q *); - -struct cfattach ubsec_ca = { - sizeof(struct ubsec_softc), ubsec_probe, ubsec_attach, -}; - -struct cfdriver ubsec_cd = { - 0, "ubsec", DV_DULL -}; - -int ubsec_intr(void *); -int ubsec_newsession(u_int32_t *, struct cryptoini *); -int ubsec_freesession(u_int64_t); -int ubsec_process(struct cryptop *); -void ubsec_callback(struct ubsec_softc *, struct ubsec_q *); -void ubsec_feed(struct ubsec_softc *); -void ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *); -void ubsec_feed2(struct ubsec_softc *); -void ubsec_feed4(struct ubsec_softc *); -void ubsec_rng(void *); -int ubsec_dma_malloc(struct ubsec_softc *, bus_size_t, - struct ubsec_dma_alloc *, int); -void ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *); -int ubsec_dmamap_aligned(bus_dmamap_t); - -#define READ_REG(sc,r) \ - bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r)) - -#define WRITE_REG(sc,reg,val) \ - bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val) - -#define SWAP32(x) (x) = htole32(ntohl((x))) -#define HTOLE32(x) (x) = htole32(x) - - -struct ubsec_stats ubsecstats; - -const struct pci_matchid ubsec_devices[] = { - { PCI_VENDOR_BLUESTEEL, PCI_PRODUCT_BLUESTEEL_5501 }, - { PCI_VENDOR_BLUESTEEL, PCI_PRODUCT_BLUESTEEL_5601 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5801 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5802 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5805 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5820 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5821 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5822 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5823 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5825 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5860 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5861 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5862 }, - { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_SCA1K }, - { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_5821 }, -}; - -int -ubsec_probe(struct device *parent, void *match, void *aux) -{ - return (pci_matchbyid((struct pci_attach_args *)aux, ubsec_devices, - nitems(ubsec_devices))); -} - -void -ubsec_attach(struct device *parent, struct device *self, void *aux) -{ - struct ubsec_softc *sc = (struct ubsec_softc *)self; - struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; - pcireg_t memtype; - const char *intrstr = NULL; - struct ubsec_dma *dmap; - bus_size_t iosize; - u_int32_t i; - int algs[CRYPTO_ALGORITHM_MAX + 1]; - - SIMPLEQ_INIT(&sc->sc_queue); - SIMPLEQ_INIT(&sc->sc_qchip); - SIMPLEQ_INIT(&sc->sc_queue2); - SIMPLEQ_INIT(&sc->sc_qchip2); - SIMPLEQ_INIT(&sc->sc_queue4); - SIMPLEQ_INIT(&sc->sc_qchip4); - - sc->sc_statmask = BS_STAT_MCR1_DONE | BS_STAT_DMAERR; - sc->sc_maxaggr = UBS_MIN_AGGR; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5601) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5802 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5805)) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5820 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822)) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | - UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY; - - if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5821) || - (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SCA1K || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_5821))) { - sc->sc_statmask |= BS_STAT_MCR1_ALLEMPTY | - BS_STAT_MCR2_ALLEMPTY; - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | - UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY; - } - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5823 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5825)) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | - UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY | - UBS_FLAGS_AES; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5860 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5861 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5862)) { - sc->sc_maxaggr = UBS_MAX_AGGR; - sc->sc_statmask |= - BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | - BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY; - sc->sc_flags |= UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | - UBS_FLAGS_LONGCTX | UBS_FLAGS_AES | - UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY; -#if 0 - /* The RNG is not yet supported */ - sc->sc_flags |= UBS_FLAGS_RNG | UBS_FLAGS_RNG4; -#endif - } - - memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BS_BAR); - if (pci_mapreg_map(pa, BS_BAR, memtype, 0, - &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) { - printf(": can't find mem space\n"); - return; - } - sc->sc_dmat = pa->pa_dmat; - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); - return; - } - intrstr = pci_intr_string(pc, ih); - sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ubsec_intr, sc, - self->dv_xname); - if (sc->sc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); - return; - } - - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) { - pci_intr_disestablish(pc, sc->sc_ih); - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); - return; - } - - SIMPLEQ_INIT(&sc->sc_freequeue); - dmap = sc->sc_dmaa; - for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) { - struct ubsec_q *q; - - q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q), - M_DEVBUF, M_NOWAIT); - if (q == NULL) { - printf(": can't allocate queue buffers\n"); - break; - } - - if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk), - &dmap->d_alloc, 0)) { - printf(": can't allocate dma buffers\n"); - free(q, M_DEVBUF, 0); - break; - } - dmap->d_dma = (struct ubsec_dmachunk *)dmap->d_alloc.dma_vaddr; - - q->q_dma = dmap; - sc->sc_queuea[i] = q; - - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - } - - bzero(algs, sizeof(algs)); - algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - if (sc->sc_flags & UBS_FLAGS_AES) - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - crypto_register(sc->sc_cid, algs, ubsec_newsession, - ubsec_freesession, ubsec_process); - - /* - * Reset Broadcom chip - */ - ubsec_reset_board(sc); - - /* - * Init Broadcom specific PCI settings - */ - ubsec_init_pciregs(pa); - - /* - * Init Broadcom chip - */ - ubsec_init_board(sc); - - printf(": 3DES MD5 SHA1"); - if (sc->sc_flags & UBS_FLAGS_AES) - printf(" AES"); - -#ifndef UBSEC_NO_RNG - if (sc->sc_flags & UBS_FLAGS_RNG) { - if (sc->sc_flags & UBS_FLAGS_RNG4) - sc->sc_statmask |= BS_STAT_MCR4_DONE; - else - sc->sc_statmask |= BS_STAT_MCR2_DONE; - - if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), - &sc->sc_rng.rng_q.q_mcr, 0)) - goto skip_rng; - - if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass), - &sc->sc_rng.rng_q.q_ctx, 0)) { - ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); - goto skip_rng; - } - - if (ubsec_dma_malloc(sc, sizeof(u_int32_t) * - UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) { - ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx); - ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); - goto skip_rng; - } - - timeout_set(&sc->sc_rngto, ubsec_rng, sc); - sc->sc_rngms = 10; - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); - printf(" RNG"); -skip_rng: - ; - } -#endif /* UBSEC_NO_RNG */ - - if (sc->sc_flags & UBS_FLAGS_KEY) { - sc->sc_statmask |= BS_STAT_MCR2_DONE; - } - - printf(", %s\n", intrstr); -} - -/* - * UBSEC Interrupt routine - */ -int -ubsec_intr(void *arg) -{ - struct ubsec_softc *sc = arg; - volatile u_int32_t stat; - struct ubsec_q *q; - struct ubsec_dma *dmap; - u_int16_t flags; - int npkts = 0, i; - - stat = READ_REG(sc, BS_STAT); - - if ((stat & (BS_STAT_MCR1_DONE|BS_STAT_MCR2_DONE|BS_STAT_MCR4_DONE| - BS_STAT_DMAERR)) == 0) - return (0); - - stat &= sc->sc_statmask; - WRITE_REG(sc, BS_STAT, stat); /* IACK */ - - /* - * Check to see if we have any packets waiting for us - */ - if ((stat & BS_STAT_MCR1_DONE)) { - while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { - q = SIMPLEQ_FIRST(&sc->sc_qchip); - dmap = q->q_dma; - - if ((dmap->d_dma->d_mcr.mcr_flags & htole16(UBS_MCR_DONE)) == 0) - break; - - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q_next); - - npkts = q->q_nstacked_mcrs; - /* - * search for further sc_qchip ubsec_q's that share - * the same MCR, and complete them too, they must be - * at the top. - */ - for (i = 0; i < npkts; i++) { - if(q->q_stacked_mcr[i]) - ubsec_callback(sc, q->q_stacked_mcr[i]); - else - break; - } - ubsec_callback(sc, q); - } - - /* - * Don't send any more packet to chip if there has been - * a DMAERR. - */ - if (!(stat & BS_STAT_DMAERR)) - ubsec_feed(sc); - } - - /* - * Check to see if we have any key setups/rng's waiting for us - */ - if ((sc->sc_flags & (UBS_FLAGS_KEY|UBS_FLAGS_RNG)) && - (stat & BS_STAT_MCR2_DONE)) { - struct ubsec_q2 *q2; - struct ubsec_mcr *mcr; - - while (!SIMPLEQ_EMPTY(&sc->sc_qchip2)) { - q2 = SIMPLEQ_FIRST(&sc->sc_qchip2); - - bus_dmamap_sync(sc->sc_dmat, q2->q_mcr.dma_map, - 0, q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - - mcr = (struct ubsec_mcr *)q2->q_mcr.dma_vaddr; - - /* A bug in new devices requires to swap this field */ - if (sc->sc_flags & UBS_FLAGS_MULTIMCR) - flags = swap16(mcr->mcr_flags); - else - flags = mcr->mcr_flags; - if ((flags & htole16(UBS_MCR_DONE)) == 0) { - bus_dmamap_sync(sc->sc_dmat, - q2->q_mcr.dma_map, 0, - q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - break; - } - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip2, q_next); - ubsec_callback2(sc, q2); - /* - * Don't send any more packet to chip if there has been - * a DMAERR. - */ - if (!(stat & BS_STAT_DMAERR)) - ubsec_feed2(sc); - } - } - if ((sc->sc_flags & UBS_FLAGS_RNG4) && (stat & BS_STAT_MCR4_DONE)) { - struct ubsec_q2 *q2; - struct ubsec_mcr *mcr; - - while (!SIMPLEQ_EMPTY(&sc->sc_qchip4)) { - q2 = SIMPLEQ_FIRST(&sc->sc_qchip4); - - bus_dmamap_sync(sc->sc_dmat, q2->q_mcr.dma_map, - 0, q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - - mcr = (struct ubsec_mcr *)q2->q_mcr.dma_vaddr; - - /* A bug in new devices requires to swap this field */ - flags = swap16(mcr->mcr_flags); - - if ((flags & htole16(UBS_MCR_DONE)) == 0) { - bus_dmamap_sync(sc->sc_dmat, - q2->q_mcr.dma_map, 0, - q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - break; - } - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip4, q_next); - ubsec_callback2(sc, q2); - /* - * Don't send any more packet to chip if there has been - * a DMAERR. - */ - if (!(stat & BS_STAT_DMAERR)) - ubsec_feed4(sc); - } - } - - /* - * Check to see if we got any DMA Error - */ - if (stat & BS_STAT_DMAERR) { -#ifdef UBSEC_DEBUG - volatile u_int32_t a = READ_REG(sc, BS_ERR); - - printf("%s: dmaerr %s@%08x\n", sc->sc_dv.dv_xname, - (a & BS_ERR_READ) ? "read" : "write", a & BS_ERR_ADDR); -#endif /* UBSEC_DEBUG */ - ubsecstats.hst_dmaerr++; - ubsec_totalreset(sc); - ubsec_feed(sc); - } - - return (1); -} - -/* - * ubsec_feed() - aggregate and post requests to chip - * It is assumed that the caller set splnet() - */ -void -ubsec_feed(struct ubsec_softc *sc) -{ -#ifdef UBSEC_DEBUG - static int max; -#endif /* UBSEC_DEBUG */ - struct ubsec_q *q, *q2; - int npkts, i; - void *v; - u_int32_t stat; - - npkts = sc->sc_nqueue; - if (npkts > sc->sc_maxaggr) - npkts = sc->sc_maxaggr; - if (npkts < 2) - goto feed1; - - if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) { - if(stat & BS_STAT_DMAERR) { - ubsec_totalreset(sc); - ubsecstats.hst_dmaerr++; - } - return; - } - -#ifdef UBSEC_DEBUG - printf("merging %d records\n", npkts); - - /* XXX temporary aggregation statistics reporting code */ - if (max < npkts) { - max = npkts; - printf("%s: new max aggregate %d\n", sc->sc_dv.dv_xname, max); - } -#endif /* UBSEC_DEBUG */ - - q = SIMPLEQ_FIRST(&sc->sc_queue); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next); - --sc->sc_nqueue; - - bus_dmamap_sync(sc->sc_dmat, q->q_src_map, - 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (q->q_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, - 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - - q->q_nstacked_mcrs = npkts - 1; /* Number of packets stacked */ - - for (i = 0; i < q->q_nstacked_mcrs; i++) { - q2 = SIMPLEQ_FIRST(&sc->sc_queue); - bus_dmamap_sync(sc->sc_dmat, q2->q_src_map, - 0, q2->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (q2->q_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, q2->q_dst_map, - 0, q2->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next); - --sc->sc_nqueue; - - v = ((char *)&q2->q_dma->d_dma->d_mcr) + sizeof(struct ubsec_mcr) - - sizeof(struct ubsec_mcr_add); - bcopy(v, &q->q_dma->d_dma->d_mcradd[i], sizeof(struct ubsec_mcr_add)); - q->q_stacked_mcr[i] = q2; - } - q->q_dma->d_dma->d_mcr.mcr_pkts = htole16(npkts); - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next); - bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map, - 0, q->q_dma->d_alloc.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_mcr)); - return; - -feed1: - while (!SIMPLEQ_EMPTY(&sc->sc_queue)) { - if ((stat = READ_REG(sc, BS_STAT)) & - (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) { - if(stat & BS_STAT_DMAERR) { - ubsec_totalreset(sc); - ubsecstats.hst_dmaerr++; - } - break; - } - - q = SIMPLEQ_FIRST(&sc->sc_queue); - - bus_dmamap_sync(sc->sc_dmat, q->q_src_map, - 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (q->q_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, - 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map, - 0, q->q_dma->d_alloc.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_mcr)); -#ifdef UBSEC_DEBUG - printf("feed: q->chip %p %08x\n", q, - (u_int32_t)q->q_dma->d_alloc.dma_paddr); -#endif /* UBSEC_DEBUG */ - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next); - --sc->sc_nqueue; - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next); - } -} - -/* - * Allocate a new 'session' and return an encoded session id. 'sidp' - * contains our registration id, and should contain an encoded session - * id on successful allocation. - */ -int -ubsec_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct cryptoini *c, *encini = NULL, *macini = NULL; - struct ubsec_softc *sc = NULL; - struct ubsec_session *ses = NULL; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; - int i, sesn; - - if (sidp == NULL || cri == NULL) - return (EINVAL); - - for (i = 0; i < ubsec_cd.cd_ndevs; i++) { - sc = ubsec_cd.cd_devs[i]; - if (sc == NULL || sc->sc_cid == (*sidp)) - break; - } - if (sc == NULL) - return (EINVAL); - - for (c = cri; c != NULL; c = c->cri_next) { - if (c->cri_alg == CRYPTO_MD5_HMAC || - c->cri_alg == CRYPTO_SHA1_HMAC) { - if (macini) - return (EINVAL); - macini = c; - } else if (c->cri_alg == CRYPTO_3DES_CBC || - c->cri_alg == CRYPTO_AES_CBC) { - if (encini) - return (EINVAL); - encini = c; - } else - return (EINVAL); - } - if (encini == NULL && macini == NULL) - return (EINVAL); - - if (encini && encini->cri_alg == CRYPTO_AES_CBC) { - switch (encini->cri_klen) { - case 128: - case 192: - case 256: - break; - default: - return (EINVAL); - } - } - - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct ubsec_session *)malloc( - sizeof(struct ubsec_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - sesn = 0; - sc->sc_nsessions = 1; - } else { - for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { - if (sc->sc_sessions[sesn].ses_used == 0) { - ses = &sc->sc_sessions[sesn]; - break; - } - } - - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = mallocarray((sesn + 1), - sizeof(struct ubsec_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * - sizeof(struct ubsec_session)); - explicit_bzero(sc->sc_sessions, sesn * - sizeof(struct ubsec_session)); - free(sc->sc_sessions, M_DEVBUF, 0); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - - bzero(ses, sizeof(struct ubsec_session)); - ses->ses_used = 1; - if (encini) { - /* Go ahead and compute key in ubsec's byte order */ - if (encini->cri_alg == CRYPTO_AES_CBC) { - bcopy(encini->cri_key, ses->ses_key, - encini->cri_klen / 8); - } else - bcopy(encini->cri_key, ses->ses_key, 24); - - SWAP32(ses->ses_key[0]); - SWAP32(ses->ses_key[1]); - SWAP32(ses->ses_key[2]); - SWAP32(ses->ses_key[3]); - SWAP32(ses->ses_key[4]); - SWAP32(ses->ses_key[5]); - SWAP32(ses->ses_key[6]); - SWAP32(ses->ses_key[7]); - } - - if (macini) { - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_IPAD_VAL; - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_ipad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hminner, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_ipad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hminner, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_opad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hmouter, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_opad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hmouter, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_OPAD_VAL; - } - - *sidp = UBSEC_SID(sc->sc_dv.dv_unit, sesn); - return (0); -} - -/* - * Deallocate a session. - */ -int -ubsec_freesession(u_int64_t tid) -{ - struct ubsec_softc *sc; - int card, session; - u_int32_t sid = ((u_int32_t)tid) & 0xffffffff; - - card = UBSEC_CARD(sid); - if (card >= ubsec_cd.cd_ndevs || ubsec_cd.cd_devs[card] == NULL) - return (EINVAL); - sc = ubsec_cd.cd_devs[card]; - session = UBSEC_SESSION(sid); - explicit_bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session])); - return (0); -} - -int -ubsec_process(struct cryptop *crp) -{ - struct ubsec_q *q = NULL; - int card, err = 0, i, j, s, nicealign; - struct ubsec_softc *sc; - struct cryptodesc *crd1, *crd2 = NULL, *maccrd, *enccrd; - int encoffset = 0, macoffset = 0, cpskip, cpoffset; - int sskip, dskip, stheend, dtheend; - int16_t coffset; - struct ubsec_session *ses, key; - struct ubsec_dma *dmap = NULL; - u_int16_t flags = 0; - int ivlen = 0, keylen = 0; - - card = UBSEC_CARD(crp->crp_sid); - if (card >= ubsec_cd.cd_ndevs || ubsec_cd.cd_devs[card] == NULL) { - ubsecstats.hst_invalid++; - return (EINVAL); - } - - sc = ubsec_cd.cd_devs[card]; - - s = splnet(); - - if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) { - ubsecstats.hst_queuefull++; - splx(s); - err = ENOMEM; - goto errout2; - } - - q = SIMPLEQ_FIRST(&sc->sc_freequeue); - SIMPLEQ_REMOVE_HEAD(&sc->sc_freequeue, q_next); - splx(s); - - dmap = q->q_dma; /* Save dma pointer */ - bzero(q, sizeof(struct ubsec_q)); - bzero(&key, sizeof(key)); - - q->q_sesn = UBSEC_SESSION(crp->crp_sid); - q->q_dma = dmap; - ses = &sc->sc_sessions[q->q_sesn]; - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - q->q_src_m = (struct mbuf *)crp->crp_buf; - q->q_dst_m = (struct mbuf *)crp->crp_buf; - } else if (crp->crp_flags & CRYPTO_F_IOV) { - q->q_src_io = (struct uio *)crp->crp_buf; - q->q_dst_io = (struct uio *)crp->crp_buf; - } else { - err = EINVAL; - goto errout; /* XXX we don't handle contiguous blocks! */ - } - - bzero(&dmap->d_dma->d_mcr, sizeof(struct ubsec_mcr)); - - dmap->d_dma->d_mcr.mcr_pkts = htole16(1); - dmap->d_dma->d_mcr.mcr_flags = 0; - q->q_crp = crp; - - if (crp->crp_ndesc < 1) { - err = EINVAL; - goto errout; - } - crd1 = &crp->crp_desc[0]; - if (crp->crp_ndesc >= 2) - crd2 = &crp->crp_desc[1]; - - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) { - maccrd = crd1; - enccrd = NULL; - } else if (crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) { - maccrd = NULL; - enccrd = crd1; - } else { - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) && - (crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC) && - ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - /* - * We cannot order the ubsec as requested - */ - err = EINVAL; - goto errout; - } - } - - if (enccrd) { - if (enccrd->crd_alg == CRYPTO_AES_CBC) { - if ((sc->sc_flags & UBS_FLAGS_AES) == 0) { - err = EINVAL; - goto errout; - } - flags |= htole16(UBS_PKTCTX_ENC_AES); - switch (enccrd->crd_klen) { - case 128: - case 192: - case 256: - keylen = enccrd->crd_klen / 8; - break; - default: - err = EINVAL; - goto errout; - } - ivlen = 16; - } else { - flags |= htole16(UBS_PKTCTX_ENC_3DES); - ivlen = 8; - keylen = 24; - } - - encoffset = enccrd->crd_skip; - - if (enccrd->crd_flags & CRD_F_ENCRYPT) { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, key.ses_iv, ivlen); - else - arc4random_buf(key.ses_iv, ivlen); - - if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - err = m_copyback(q->q_src_m, - enccrd->crd_inject, - ivlen, key.ses_iv, M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback(q->q_src_io, - enccrd->crd_inject, - ivlen, key.ses_iv); - if (err) - goto errout; - } - } else { - flags |= htole16(UBS_PKTCTX_INBOUND); - - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, key.ses_iv, ivlen); - else if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata(q->q_src_m, enccrd->crd_inject, - ivlen, key.ses_iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata(q->q_src_io, - enccrd->crd_inject, ivlen, - (caddr_t)key.ses_iv); - } - - for (i = 0; i < (keylen / 4); i++) - key.ses_key[i] = ses->ses_key[i]; - for (i = 0; i < (ivlen / 4); i++) - SWAP32(key.ses_iv[i]); - } - - if (maccrd) { - macoffset = maccrd->crd_skip; - - if (maccrd->crd_alg == CRYPTO_MD5_HMAC) - flags |= htole16(UBS_PKTCTX_AUTH_MD5); - else - flags |= htole16(UBS_PKTCTX_AUTH_SHA1); - - for (i = 0; i < 5; i++) { - key.ses_hminner[i] = ses->ses_hminner[i]; - key.ses_hmouter[i] = ses->ses_hmouter[i]; - - HTOLE32(key.ses_hminner[i]); - HTOLE32(key.ses_hmouter[i]); - } - } - - if (enccrd && maccrd) { - /* - * ubsec cannot handle packets where the end of encryption - * and authentication are not the same, or where the - * encrypted part begins before the authenticated part. - */ - if (((encoffset + enccrd->crd_len) != - (macoffset + maccrd->crd_len)) || - (enccrd->crd_skip < maccrd->crd_skip)) { - err = EINVAL; - goto errout; - } - sskip = maccrd->crd_skip; - cpskip = dskip = enccrd->crd_skip; - stheend = maccrd->crd_len; - dtheend = enccrd->crd_len; - coffset = enccrd->crd_skip - maccrd->crd_skip; - cpoffset = cpskip + dtheend; -#ifdef UBSEC_DEBUG - printf("mac: skip %d, len %d, inject %d\n", - maccrd->crd_skip, maccrd->crd_len, maccrd->crd_inject); - printf("enc: skip %d, len %d, inject %d\n", - enccrd->crd_skip, enccrd->crd_len, enccrd->crd_inject); - printf("src: skip %d, len %d\n", sskip, stheend); - printf("dst: skip %d, len %d\n", dskip, dtheend); - printf("ubs: coffset %d, pktlen %d, cpskip %d, cpoffset %d\n", - coffset, stheend, cpskip, cpoffset); -#endif - } else { - cpskip = dskip = sskip = macoffset + encoffset; - dtheend = stheend = (enccrd)?enccrd->crd_len:maccrd->crd_len; - cpoffset = cpskip + dtheend; - coffset = 0; - } - - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER, - 0xfff0, 0, BUS_DMA_NOWAIT, &q->q_src_map) != 0) { - err = ENOMEM; - goto errout; - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, q->q_src_map, - q->q_src_m, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - q->q_src_map = NULL; - err = ENOMEM; - goto errout; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, q->q_src_map, - q->q_src_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - q->q_src_map = NULL; - err = ENOMEM; - goto errout; - } - } - nicealign = ubsec_dmamap_aligned(q->q_src_map); - - dmap->d_dma->d_mcr.mcr_pktlen = htole16(stheend); - -#ifdef UBSEC_DEBUG - printf("src skip: %d\n", sskip); -#endif - for (i = j = 0; i < q->q_src_map->dm_nsegs; i++) { - struct ubsec_pktbuf *pb; - bus_size_t packl = q->q_src_map->dm_segs[i].ds_len; - bus_addr_t packp = q->q_src_map->dm_segs[i].ds_addr; - - if (sskip >= packl) { - sskip -= packl; - continue; - } - - packl -= sskip; - packp += sskip; - sskip = 0; - - if (packl > 0xfffc) { - err = EIO; - goto errout; - } - - if (j == 0) - pb = &dmap->d_dma->d_mcr.mcr_ipktbuf; - else - pb = &dmap->d_dma->d_sbuf[j - 1]; - - pb->pb_addr = htole32(packp); - - if (stheend) { - if (packl > stheend) { - pb->pb_len = htole32(stheend); - stheend = 0; - } else { - pb->pb_len = htole32(packl); - stheend -= packl; - } - } else - pb->pb_len = htole32(packl); - - if ((i + 1) == q->q_src_map->dm_nsegs) - pb->pb_next = 0; - else - pb->pb_next = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_sbuf[j])); - j++; - } - - if (enccrd == NULL && maccrd != NULL) { - dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr = 0; - dmap->d_dma->d_mcr.mcr_opktbuf.pb_len = 0; - dmap->d_dma->d_mcr.mcr_opktbuf.pb_next = - htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_macbuf[0])); -#ifdef UBSEC_DEBUG - printf("opkt: %x %x %x\n", - dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr, - dmap->d_dma->d_mcr.mcr_opktbuf.pb_len, - dmap->d_dma->d_mcr.mcr_opktbuf.pb_next); -#endif - } else { - if (crp->crp_flags & CRYPTO_F_IOV) { - if (!nicealign) { - err = EINVAL; - goto errout; - } - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, - UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, - &q->q_dst_map) != 0) { - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_uio(sc->sc_dmat, q->q_dst_map, - q->q_dst_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - q->q_dst_map = NULL; - goto errout; - } - } else if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (nicealign) { - q->q_dst_m = q->q_src_m; - q->q_dst_map = q->q_src_map; - } else { - q->q_dst_m = m_dup_pkt(q->q_src_m, 0, - M_NOWAIT); - if (q->q_dst_m == NULL) { - err = ENOMEM; - goto errout; - } - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, - UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, - &q->q_dst_map) != 0) { - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, - q->q_dst_map, q->q_dst_m, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - q->q_dst_map); - q->q_dst_map = NULL; - err = ENOMEM; - goto errout; - } - } - } else { - err = EINVAL; - goto errout; - } - -#ifdef UBSEC_DEBUG - printf("dst skip: %d\n", dskip); -#endif - for (i = j = 0; i < q->q_dst_map->dm_nsegs; i++) { - struct ubsec_pktbuf *pb; - bus_size_t packl = q->q_dst_map->dm_segs[i].ds_len; - bus_addr_t packp = q->q_dst_map->dm_segs[i].ds_addr; - - if (dskip >= packl) { - dskip -= packl; - continue; - } - - packl -= dskip; - packp += dskip; - dskip = 0; - - if (packl > 0xfffc) { - err = EIO; - goto errout; - } - - if (j == 0) - pb = &dmap->d_dma->d_mcr.mcr_opktbuf; - else - pb = &dmap->d_dma->d_dbuf[j - 1]; - - pb->pb_addr = htole32(packp); - - if (dtheend) { - if (packl > dtheend) { - pb->pb_len = htole32(dtheend); - dtheend = 0; - } else { - pb->pb_len = htole32(packl); - dtheend -= packl; - } - } else - pb->pb_len = htole32(packl); - - if ((i + 1) == q->q_dst_map->dm_nsegs) { - if (maccrd) - pb->pb_next = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_macbuf[0])); - else - pb->pb_next = 0; - } else - pb->pb_next = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_dbuf[j])); - j++; - } - } - - dmap->d_dma->d_mcr.mcr_cmdctxp = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - if (enccrd && enccrd->crd_alg == CRYPTO_AES_CBC) { - struct ubsec_pktctx_aes128 *aes128; - struct ubsec_pktctx_aes192 *aes192; - struct ubsec_pktctx_aes256 *aes256; - struct ubsec_pktctx_hdr *ph; - u_int8_t *ctx; - - ctx = (u_int8_t *)(dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - ph = (struct ubsec_pktctx_hdr *)ctx; - ph->ph_type = htole16(UBS_PKTCTX_TYPE_IPSEC_AES); - ph->ph_flags = flags; - ph->ph_offset = htole16(coffset >> 2); - - switch (enccrd->crd_klen) { - case 128: - aes128 = (struct ubsec_pktctx_aes128 *)ctx; - ph->ph_len = htole16(sizeof(*aes128)); - ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_128); - for (i = 0; i < 4; i++) - aes128->pc_aeskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - aes128->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - aes128->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 4; i++) - aes128->pc_iv[i] = key.ses_iv[i]; - break; - case 192: - aes192 = (struct ubsec_pktctx_aes192 *)ctx; - ph->ph_len = htole16(sizeof(*aes192)); - ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_192); - for (i = 0; i < 6; i++) - aes192->pc_aeskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - aes192->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - aes192->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 4; i++) - aes192->pc_iv[i] = key.ses_iv[i]; - break; - case 256: - aes256 = (struct ubsec_pktctx_aes256 *)ctx; - ph->ph_len = htole16(sizeof(*aes256)); - ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_256); - for (i = 0; i < 8; i++) - aes256->pc_aeskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - aes256->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - aes256->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 4; i++) - aes256->pc_iv[i] = key.ses_iv[i]; - break; - } - } else if (sc->sc_flags & UBS_FLAGS_LONGCTX) { - struct ubsec_pktctx_3des *ctx; - struct ubsec_pktctx_hdr *ph; - - ctx = (struct ubsec_pktctx_3des *) - (dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - ph = (struct ubsec_pktctx_hdr *)ctx; - ph->ph_len = htole16(sizeof(*ctx)); - ph->ph_type = htole16(UBS_PKTCTX_TYPE_IPSEC_3DES); - ph->ph_flags = flags; - ph->ph_offset = htole16(coffset >> 2); - - for (i = 0; i < 6; i++) - ctx->pc_deskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - ctx->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - ctx->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 2; i++) - ctx->pc_iv[i] = key.ses_iv[i]; - } else { - struct ubsec_pktctx *ctx = (struct ubsec_pktctx *) - (dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - ctx->pc_flags = flags; - ctx->pc_offset = htole16(coffset >> 2); - for (i = 0; i < 6; i++) - ctx->pc_deskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - ctx->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - ctx->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 2; i++) - ctx->pc_iv[i] = key.ses_iv[i]; - } - - s = splnet(); - SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next); - sc->sc_nqueue++; - ubsecstats.hst_ipackets++; - ubsecstats.hst_ibytes += dmap->d_alloc.dma_map->dm_mapsize; - ubsec_feed(sc); - splx(s); - explicit_bzero(&key, sizeof(key)); - return (0); - -errout: - if (q != NULL) { - if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) - m_freem(q->q_dst_m); - - if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { - bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - } - if (q->q_src_map != NULL) { - bus_dmamap_unload(sc->sc_dmat, q->q_src_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - } - - s = splnet(); - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - splx(s); - } - if (err == EINVAL) - ubsecstats.hst_invalid++; - else - ubsecstats.hst_nomem++; -errout2: - crp->crp_etype = err; - crypto_done(crp); - explicit_bzero(&key, sizeof(key)); - return (0); -} - -void -ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q) -{ - struct cryptop *crp = (struct cryptop *)q->q_crp; - struct cryptodesc *crd; - struct ubsec_dma *dmap = q->q_dma; - u_int8_t *ctx = (u_int8_t *)(dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - struct ubsec_pktctx_hdr *ph = (struct ubsec_pktctx_hdr *)ctx; - int i; - - ubsecstats.hst_opackets++; - ubsecstats.hst_obytes += dmap->d_alloc.dma_size; - - bus_dmamap_sync(sc->sc_dmat, dmap->d_alloc.dma_map, 0, - dmap->d_alloc.dma_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { - bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, - 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - } - bus_dmamap_sync(sc->sc_dmat, q->q_src_map, - 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, q->q_src_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - - explicit_bzero(ctx, ph->ph_len); - - if ((crp->crp_flags & CRYPTO_F_IMBUF) && (q->q_src_m != q->q_dst_m)) { - m_freem(q->q_src_m); - crp->crp_buf = (caddr_t)q->q_dst_m; - } - - for (i = 0; i < crp->crp_ndesc; i++) { - crd = &crp->crp_desc[i]; - if (crd->crd_alg != CRYPTO_MD5_HMAC && - crd->crd_alg != CRYPTO_SHA1_HMAC) - continue; - if (crp->crp_flags & CRYPTO_F_IMBUF) - crp->crp_etype = m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, 12, - dmap->d_dma->d_macbuf, M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV && crp->crp_mac) - bcopy((caddr_t)dmap->d_dma->d_macbuf, - crp->crp_mac, 12); - break; - } - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - crypto_done(crp); -} - -/* - * feed the key generator, must be called at splnet() or higher. - */ -void -ubsec_feed2(struct ubsec_softc *sc) -{ - struct ubsec_q2 *q; - - while (!SIMPLEQ_EMPTY(&sc->sc_queue2)) { - if (READ_REG(sc, BS_STAT) & BS_STAT_MCR2_FULL) - break; - q = SIMPLEQ_FIRST(&sc->sc_queue2); - - bus_dmamap_sync(sc->sc_dmat, q->q_mcr.dma_map, 0, - q->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, - q->q_ctx.dma_map->dm_mapsize, - BUS_DMASYNC_PREWRITE); - - WRITE_REG(sc, BS_MCR2, q->q_mcr.dma_paddr); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue2, q_next); - --sc->sc_nqueue2; - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip2, q, q_next); - } -} - -/* - * feed the RNG (used instead of ubsec_feed2() on 5827+ devices) - */ -void -ubsec_feed4(struct ubsec_softc *sc) -{ - struct ubsec_q2 *q; - - while (!SIMPLEQ_EMPTY(&sc->sc_queue4)) { - if (READ_REG(sc, BS_STAT) & BS_STAT_MCR4_FULL) - break; - q = SIMPLEQ_FIRST(&sc->sc_queue4); - - bus_dmamap_sync(sc->sc_dmat, q->q_mcr.dma_map, 0, - q->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, - q->q_ctx.dma_map->dm_mapsize, - BUS_DMASYNC_PREWRITE); - - WRITE_REG(sc, BS_MCR4, q->q_mcr.dma_paddr); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue4, q_next); - --sc->sc_nqueue4; - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip4, q, q_next); - } -} - -/* - * Callback for handling random numbers - */ -void -ubsec_callback2(struct ubsec_softc *sc, struct ubsec_q2 *q) -{ - struct ubsec_ctx_keyop *ctx; - - ctx = (struct ubsec_ctx_keyop *)q->q_ctx.dma_vaddr; - bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, - q->q_ctx.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - - switch (q->q_type) { -#ifndef UBSEC_NO_RNG - case UBS_CTXOP_RNGSHA1: - case UBS_CTXOP_RNGBYPASS: { - struct ubsec_q2_rng *rng = (struct ubsec_q2_rng *)q; - u_int32_t *p; - int i; - - bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, - rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - p = (u_int32_t *)rng->rng_buf.dma_vaddr; - for (i = 0; i < UBSEC_RNG_BUFSIZ; p++, i++) - enqueue_randomness(*p); - rng->rng_used = 0; - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); - break; - } -#endif - default: - printf("%s: unknown ctx op: %x\n", sc->sc_dv.dv_xname, - letoh16(ctx->ctx_op)); - break; - } -} - -#ifndef UBSEC_NO_RNG -void -ubsec_rng(void *vsc) -{ - struct ubsec_softc *sc = vsc; - struct ubsec_q2_rng *rng = &sc->sc_rng; - struct ubsec_mcr *mcr; - struct ubsec_ctx_rngbypass *ctx; - int s, *nqueue; - - s = splnet(); - if (rng->rng_used) { - splx(s); - return; - } - if (sc->sc_flags & UBS_FLAGS_RNG4) - nqueue = &sc->sc_nqueue4; - else - nqueue = &sc->sc_nqueue2; - - (*nqueue)++; - if (*nqueue >= UBS_MAX_NQUEUE) - goto out; - - mcr = (struct ubsec_mcr *)rng->rng_q.q_mcr.dma_vaddr; - ctx = (struct ubsec_ctx_rngbypass *)rng->rng_q.q_ctx.dma_vaddr; - - mcr->mcr_pkts = htole16(1); - mcr->mcr_flags = 0; - mcr->mcr_cmdctxp = htole32(rng->rng_q.q_ctx.dma_paddr); - mcr->mcr_ipktbuf.pb_addr = mcr->mcr_ipktbuf.pb_next = 0; - mcr->mcr_ipktbuf.pb_len = 0; - mcr->mcr_reserved = mcr->mcr_pktlen = 0; - mcr->mcr_opktbuf.pb_addr = htole32(rng->rng_buf.dma_paddr); - mcr->mcr_opktbuf.pb_len = htole32(((sizeof(u_int32_t) * UBSEC_RNG_BUFSIZ)) & - UBS_PKTBUF_LEN); - mcr->mcr_opktbuf.pb_next = 0; - - ctx->rbp_len = htole16(sizeof(struct ubsec_ctx_rngbypass)); - ctx->rbp_op = htole16(UBS_CTXOP_RNGSHA1); - rng->rng_q.q_type = UBS_CTXOP_RNGSHA1; - - bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, - rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); - - if (sc->sc_flags & UBS_FLAGS_RNG4) { - SIMPLEQ_INSERT_TAIL(&sc->sc_queue4, &rng->rng_q, q_next); - rng->rng_used = 1; - ubsec_feed4(sc); - } else { - SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rng->rng_q, q_next); - rng->rng_used = 1; - ubsec_feed2(sc); - } - splx(s); - - return; - -out: - /* - * Something weird happened, generate our own call back. - */ - (*nqueue)--; - splx(s); - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); -} -#endif /* UBSEC_NO_RNG */ - -int -ubsec_dma_malloc(struct ubsec_softc *sc, bus_size_t size, - struct ubsec_dma_alloc *dma, int mapflags) -{ - int r; - - if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, - &dma->dma_seg, 1, &dma->dma_nseg, BUS_DMA_NOWAIT)) != 0) - goto fail_0; - - if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg, - size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0) - goto fail_1; - - if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_NOWAIT, &dma->dma_map)) != 0) - goto fail_2; - - if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr, - size, NULL, BUS_DMA_NOWAIT)) != 0) - goto fail_3; - - dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr; - dma->dma_size = size; - return (0); - -fail_3: - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -fail_2: - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size); -fail_1: - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); -fail_0: - dma->dma_map = NULL; - return (r); -} - -void -ubsec_dma_free(struct ubsec_softc *sc, struct ubsec_dma_alloc *dma) -{ - bus_dmamap_unload(sc->sc_dmat, dma->dma_map); - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size); - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -} - -/* - * Resets the board. Values in the regesters are left as is - * from the reset (i.e. initial values are assigned elsewhere). - */ -void -ubsec_reset_board(struct ubsec_softc *sc) -{ - volatile u_int32_t ctrl; - - /* Reset the device */ - ctrl = READ_REG(sc, BS_CTRL); - ctrl |= BS_CTRL_RESET; - WRITE_REG(sc, BS_CTRL, ctrl); - - /* - * Wait aprox. 30 PCI clocks = 900 ns = 0.9 us - */ - DELAY(10); - - /* Enable RNG and interrupts on newer devices */ - if (sc->sc_flags & UBS_FLAGS_MULTIMCR) { - WRITE_REG(sc, BS_CFG, BS_CFG_RNG); - WRITE_REG(sc, BS_INT, BS_INT_DMAINT); - } -} - -/* - * Init Broadcom registers - */ -void -ubsec_init_board(struct ubsec_softc *sc) -{ - u_int32_t ctrl; - - ctrl = READ_REG(sc, BS_CTRL); - ctrl &= ~(BS_CTRL_BE32 | BS_CTRL_BE64); - ctrl |= BS_CTRL_LITTLE_ENDIAN | BS_CTRL_MCR1INT; - - if (sc->sc_flags & UBS_FLAGS_KEY) - ctrl |= BS_CTRL_MCR2INT; - else - ctrl &= ~BS_CTRL_MCR2INT; - - if (sc->sc_flags & UBS_FLAGS_HWNORM) - ctrl &= ~BS_CTRL_SWNORM; - - if (sc->sc_flags & UBS_FLAGS_MULTIMCR) { - ctrl |= BS_CTRL_BSIZE240; - ctrl &= ~BS_CTRL_MCR3INT; /* MCR3 is reserved for SSL */ - - if (sc->sc_flags & UBS_FLAGS_RNG4) - ctrl |= BS_CTRL_MCR4INT; - else - ctrl &= ~BS_CTRL_MCR4INT; - } - - WRITE_REG(sc, BS_CTRL, ctrl); -} - -/* - * Init Broadcom PCI registers - */ -void -ubsec_init_pciregs(struct pci_attach_args *pa) -{ - pci_chipset_tag_t pc = pa->pa_pc; - u_int32_t misc; - - /* - * This will set the cache line size to 1, this will - * force the BCM58xx chip just to do burst read/writes. - * Cache line read/writes are to slow - */ - misc = pci_conf_read(pc, pa->pa_tag, PCI_BHLC_REG); - misc = (misc & ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT)) - | ((UBS_DEF_CACHELINE & 0xff) << PCI_CACHELINE_SHIFT); - pci_conf_write(pc, pa->pa_tag, PCI_BHLC_REG, misc); -} - -/* - * Clean up after a chip crash. - * It is assumed that the caller is in splnet() - */ -void -ubsec_cleanchip(struct ubsec_softc *sc) -{ - struct ubsec_q *q; - - while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { - q = SIMPLEQ_FIRST(&sc->sc_qchip); - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q_next); - ubsec_free_q(sc, q); - } -} - -/* - * free a ubsec_q - * It is assumed that the caller is within splnet() - */ -int -ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q) -{ - struct ubsec_q *q2; - struct cryptop *crp; - int npkts; - int i; - - npkts = q->q_nstacked_mcrs; - - for (i = 0; i < npkts; i++) { - if(q->q_stacked_mcr[i]) { - q2 = q->q_stacked_mcr[i]; - - if ((q2->q_dst_m != NULL) && (q2->q_src_m != q2->q_dst_m)) - m_freem(q2->q_dst_m); - - crp = (struct cryptop *)q2->q_crp; - - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q2, q_next); - - crp->crp_etype = EFAULT; - crypto_done(crp); - } else { - break; - } - } - - /* - * Free header MCR - */ - if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) - m_freem(q->q_dst_m); - - crp = (struct cryptop *)q->q_crp; - - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - - crp->crp_etype = EFAULT; - crypto_done(crp); - return(0); -} - -/* - * Routine to reset the chip and clean up. - * It is assumed that the caller is in splnet() - */ -void -ubsec_totalreset(struct ubsec_softc *sc) -{ - ubsec_reset_board(sc); - ubsec_init_board(sc); - ubsec_cleanchip(sc); -} - -int -ubsec_dmamap_aligned(bus_dmamap_t map) -{ - int i; - - for (i = 0; i < map->dm_nsegs; i++) { - if (map->dm_segs[i].ds_addr & 3) - return (0); - if ((i != (map->dm_nsegs - 1)) && - (map->dm_segs[i].ds_len & 3)) - return (0); - } - return (1); -} diff --git a/sys/dev/pci/ubsecreg.h b/sys/dev/pci/ubsecreg.h deleted file mode 100644 index 9e881f6b877..00000000000 --- a/sys/dev/pci/ubsecreg.h +++ /dev/null @@ -1,252 +0,0 @@ -/* $OpenBSD: ubsecreg.h,v 1.30 2009/03/27 13:31:30 reyk Exp $ */ - -/* - * Copyright (c) 2000 Theo de Raadt - * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -/* - * Register definitions for 5601 BlueSteel Networks Ubiquitous Broadband - * Security "uBSec" chip. Definitions from revision 2.8 of the product - * datasheet. - */ - -#define BS_BAR 0x10 /* DMA base address register */ -#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */ -#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */ - -#define UBS_PCI_RTY_SHIFT 8 -#define UBS_PCI_RTY_MASK 0xff -#define UBS_PCI_RTY(misc) \ - (((misc) >> UBS_PCI_RTY_SHIFT) & UBS_PCI_RTY_MASK) - -#define UBS_PCI_TOUT_SHIFT 0 -#define UBS_PCI_TOUT_MASK 0xff -#define UBS_PCI_TOUT(misc) \ - (((misc) >> PCI_TOUT_SHIFT) & PCI_TOUT_MASK) - -/* - * DMA Control & Status Registers (offset from BS_BAR) - */ -#define BS_MCR1 0x0000 /* DMA Master Command Record 1 */ -#define BS_CTRL 0x0004 /* DMA Control */ -#define BS_STAT 0x0008 /* DMA Status */ -#define BS_ERR 0x000c /* DMA Error Address */ -#define BS_MCR2 0x0010 /* DMA Master Command Record 2 */ -#define BS_MCR3 0x0014 /* 5827+, DMA Master Command Record 3 */ -#define BS_MCR4 0x001c /* 5827+, DMA Master Command Record 4 */ -#define BS_CFG 0x0700 /* 5827+, Configuration Register */ -#define BS_INT 0x0f00 /* 5827+, Interrupt Register */ - -/* BS_CTRL - DMA Control */ -#define BS_CTRL_RESET 0x80000000 /* hardware reset, 5805/5820 */ -#define BS_CTRL_MCR2INT 0x40000000 /* enable intr MCR for MCR2 */ -#define BS_CTRL_MCR1INT 0x20000000 /* enable intr MCR for MCR1 */ -#define BS_CTRL_OFM 0x10000000 /* Output fragment mode */ -#define BS_CTRL_BE32 0x08000000 /* big-endian, 32bit bytes */ -#define BS_CTRL_BE64 0x04000000 /* big-endian, 64bit bytes */ -#define BS_CTRL_DMAERR 0x02000000 /* enable intr DMA error */ -#define BS_CTRL_RNG_M 0x01800000 /* RNG mode */ -#define BS_CTRL_RNG_1 0x00000000 /* 1bit rn/one slow clock */ -#define BS_CTRL_RNG_4 0x00800000 /* 1bit rn/four slow clocks */ -#define BS_CTRL_RNG_8 0x01000000 /* 1bit rn/eight slow clocks */ -#define BS_CTRL_RNG_16 0x01800000 /* 1bit rn/16 slow clocks */ -#define BS_CTRL_SWNORM 0x00400000 /* 582[01], sw normalization */ -#define BS_CTRL_MCR3INT 0x00400000 /* 5827+, intr for MCR3 */ -#define BS_CTRL_MCR4INT 0x00200000 /* 5827+, intr for MCR4 */ -#define BS_CTRL_BSIZE240 0x000f0000 /* 5827+, burst size 240 */ -#define BS_CTRL_FRAG_M 0x0000ffff /* output fragment size mask */ -#define BS_CTRL_LITTLE_ENDIAN (BS_CTRL_BE32 | BS_CTRL_BE64) - -/* BS_STAT - DMA Status */ -#define BS_STAT_MCR_BUSY 0x80000000 /* MCR is busy */ -#define BS_STAT_MCR1_FULL 0x40000000 /* MCR1 is full */ -#define BS_STAT_MCR1_DONE 0x20000000 /* MCR1 is done */ -#define BS_STAT_DMAERR 0x10000000 /* DMA error */ -#define BS_STAT_MCR2_FULL 0x08000000 /* MCR2 is full */ -#define BS_STAT_MCR2_DONE 0x04000000 /* MCR2 is done */ -#define BS_STAT_MCR1_ALLEMPTY 0x02000000 /* 5821, MCR1 is empty */ -#define BS_STAT_MCR2_ALLEMPTY 0x01000000 /* 5821, MCR2 is empty */ -#define BS_STAT_MCR3_ALLEMPTY 0x00800000 /* 5827+, MCR3 is empty */ -#define BS_STAT_MCR4_ALLEMPTY 0x00400000 /* 5827+, MCR4 is empty */ -#define BS_STAT_MCR3_FULL 0x00080000 /* 5827+, MCR3 is full */ -#define BS_STAT_MCR3_DONE 0x00040000 /* 5827+, MCR3 is done */ -#define BS_STAT_MCR4_FULL 0x00020000 /* 5827+, MCR4 is full */ -#define BS_STAT_MCR4_DONE 0x00010000 /* 5827+, MCR4 is done */ - -/* BS_ERR - DMA Error Address */ -#define BS_ERR_ADDR 0xfffffffc /* error address mask */ -#define BS_ERR_READ 0x00000002 /* fault was on read */ - -/* BS_CFG */ -#define BS_CFG_RNG 0x00000001 /* 5827+, enable RNG */ - -/* BS_INT */ -#define BS_INT_DMAINT 0x80000000 /* 5827+, enable DMA intr */ - -/* DES/3DES */ -struct ubsec_pktctx { - u_int32_t pc_deskey[6]; /* 3DES key */ - u_int32_t pc_hminner[5]; /* hmac inner state */ - u_int32_t pc_hmouter[5]; /* hmac outer state */ - u_int32_t pc_iv[2]; /* [3]DES iv */ - u_int16_t pc_flags; /* flags, below */ - u_int16_t pc_offset; /* crypto offset */ -}; -#define UBS_PKTCTX_ENC_3DES 0x8000 /* use 3des */ -#define UBS_PKTCTX_ENC_NONE 0x0000 /* no encryption */ -#define UBS_PKTCTX_INBOUND 0x4000 /* inbound packet */ -#define UBS_PKTCTX_AUTH 0x3000 /* authentication mask */ -#define UBS_PKTCTX_AUTH_NONE 0x0000 /* no authentication */ -#define UBS_PKTCTX_AUTH_MD5 0x1000 /* use hmac-md5 */ -#define UBS_PKTCTX_AUTH_SHA1 0x2000 /* use hmac-sha1 */ - -/* "Long" cryptographic operations on newer chipsets */ -#define UBS_PKTCTX_TYPE_IPSEC_3DES 0x0000 -#define UBS_PKTCTX_TYPE_IPSEC_AES 0x0040 - -struct ubsec_pktctx_hdr { - volatile u_int16_t ph_len; /* length of ctx struct */ - volatile u_int16_t ph_type; /* context type, 0 */ - volatile u_int16_t ph_flags; /* flags, same as above */ - volatile u_int16_t ph_offset; /* crypto/auth offset */ -}; - -/* Long version of DES/3DES */ -struct ubsec_pktctx_3des { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_deskey[6]; /* 3DES key */ - volatile u_int32_t pc_iv[2]; /* [3]DES iv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; - -/* AES uses different structures for each supported key size */ -struct ubsec_pktctx_aes128 { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_aeskey[4]; /* AES128 key */ - volatile u_int32_t pc_iv[4]; /* AES iv/ucv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; - -struct ubsec_pktctx_aes192 { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_aeskey[6]; /* AES192 key */ - volatile u_int32_t pc_iv[4]; /* AES iv/icv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; - -struct ubsec_pktctx_aes256 { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_aeskey[8]; /* AES256 key */ - volatile u_int32_t pc_iv[4]; /* AES iv/icv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; -#define UBS_PKTCTX_ENC_AES 0x8000 /* use aes */ -#define UBS_PKTCTX_MODE_CBC 0x0000 /* Cipher Block Chaining mode */ -#define UBS_PKTCTX_MODE_CTR 0x0400 /* Counter mode */ -#define UBS_PKTCTX_KEYSIZE_128 0x0000 /* AES128 */ -#define UBS_PKTCTX_KEYSIZE_192 0x0100 /* AES192 */ -#define UBS_PKTCTX_KEYSIZE_256 0x0200 /* AES256 */ - -struct ubsec_pktbuf { - volatile u_int32_t pb_addr; /* address of buffer start */ - volatile u_int32_t pb_next; /* pointer to next pktbuf */ - volatile u_int32_t pb_len; /* packet length */ -}; -#define UBS_PKTBUF_LEN 0x0000ffff /* length mask */ - -struct ubsec_mcr { - volatile u_int16_t mcr_pkts; /* #pkts in this mcr */ - volatile u_int16_t mcr_flags; /* mcr flags (below) */ - volatile u_int32_t mcr_cmdctxp; /* command ctx pointer */ - struct ubsec_pktbuf mcr_ipktbuf; /* input chain header */ - volatile u_int16_t mcr_reserved; - volatile u_int16_t mcr_pktlen; - struct ubsec_pktbuf mcr_opktbuf; /* output chain header */ -}; - -struct ubsec_mcr_add { - volatile u_int32_t mcr_cmdctxp; /* command ctx pointer */ - struct ubsec_pktbuf mcr_ipktbuf; /* input chain header */ - volatile u_int16_t mcr_reserved; - volatile u_int16_t mcr_pktlen; - struct ubsec_pktbuf mcr_opktbuf; /* output chain header */ -}; - -#define UBS_MCR_DONE 0x0001 /* mcr has been processed */ -#define UBS_MCR_ERROR 0x0002 /* error in processing */ -#define UBS_MCR_ERRORCODE 0xff00 /* error type */ - -struct ubsec_ctx_keyop { - volatile u_int16_t ctx_len; /* command length */ - volatile u_int16_t ctx_op; /* operation code */ - volatile u_int8_t ctx_pad[60]; /* padding */ -}; -#define UBS_CTXOP_DHPKGEN 0x01 /* dh public key generation */ -#define UBS_CTXOP_DHSSGEN 0x02 /* dh shared secret gen. */ -#define UBS_CTXOP_RSAPUB 0x03 /* rsa public key op */ -#define UBS_CTXOP_RSAPRIV 0x04 /* rsa private key op */ -#define UBS_CTXOP_DSASIGN 0x05 /* dsa signing op */ -#define UBS_CTXOP_DSAVRFY 0x06 /* dsa verification */ -#define UBS_CTXOP_RNGBYPASS 0x41 /* rng direct test mode */ -#define UBS_CTXOP_RNGSHA1 0x42 /* rng sha1 test mode */ -#define UBS_CTXOP_MODADD 0x43 /* modular addition */ -#define UBS_CTXOP_MODSUB 0x44 /* modular subtraction */ -#define UBS_CTXOP_MODMUL 0x45 /* modular multiplication */ -#define UBS_CTXOP_MODRED 0x46 /* modular reduction */ -#define UBS_CTXOP_MODEXP 0x47 /* modular exponentiation */ -#define UBS_CTXOP_MODINV 0x48 /* modular inverse */ - -struct ubsec_ctx_rngbypass { - volatile u_int16_t rbp_len; /* command length, 64 */ - volatile u_int16_t rbp_op; /* rng bypass, 0x41 */ - volatile u_int8_t rbp_pad[60]; /* padding */ -}; - -/* modexp: C = (M ^ E) mod N */ -struct ubsec_ctx_modexp { - volatile u_int16_t me_len; /* command length */ - volatile u_int16_t me_op; /* modexp, 0x47 */ - volatile u_int16_t me_E_len; /* E (bits) */ - volatile u_int16_t me_N_len; /* N (bits) */ - u_int8_t me_N[2048/8]; /* N */ -}; - -struct ubsec_ctx_rsapriv { - volatile u_int16_t rpr_len; /* command length */ - volatile u_int16_t rpr_op; /* rsaprivate, 0x04 */ - volatile u_int16_t rpr_q_len; /* q (bits) */ - volatile u_int16_t rpr_p_len; /* p (bits) */ - u_int8_t rpr_buf[5 * 1024 / 8]; /* parameters: */ - /* p, q, dp, dq, pinv */ -}; diff --git a/sys/dev/pci/ubsecvar.h b/sys/dev/pci/ubsecvar.h deleted file mode 100644 index cb5cd9b3773..00000000000 --- a/sys/dev/pci/ubsecvar.h +++ /dev/null @@ -1,175 +0,0 @@ -/* $OpenBSD: ubsecvar.h,v 1.41 2020/01/10 23:09:23 cheloha Exp $ */ - -/* - * Copyright (c) 2000 Theo de Raadt - * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -/* Maximum queue length */ -#ifndef UBS_MAX_NQUEUE -#define UBS_MAX_NQUEUE 60 -#endif - -#define UBS_MAX_SCATTER 64 /* Maximum scatter/gather depth */ - -#ifndef UBS_MAX_AGGR -#define UBS_MAX_AGGR 17 /* Maximum aggregation count */ -#endif - -#ifndef UBS_MIN_AGGR -#define UBS_MIN_AGGR 5 /* < 5827, Maximum aggregation count */ -#endif - -#define UBSEC_CARD(sid) (((sid) & 0xf0000000) >> 28) -#define UBSEC_SESSION(sid) ( (sid) & 0x0fffffff) -#define UBSEC_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff)) - -#define UBS_DEF_RTY 0xff /* PCI Retry Timeout */ -#define UBS_DEF_TOUT 0xff /* PCI TRDY Timeout */ -#define UBS_DEF_CACHELINE 0x01 /* Cache Line setting */ - -struct ubsec_dma_alloc { - u_int32_t dma_paddr; - caddr_t dma_vaddr; - bus_dmamap_t dma_map; - bus_dma_segment_t dma_seg; - bus_size_t dma_size; - int dma_nseg; -}; - -struct ubsec_q2 { - SIMPLEQ_ENTRY(ubsec_q2) q_next; - struct ubsec_dma_alloc q_mcr; - struct ubsec_dma_alloc q_ctx; - u_int q_type; -}; - -struct ubsec_q2_rng { - struct ubsec_q2 rng_q; - struct ubsec_dma_alloc rng_buf; - int rng_used; -}; - -#define UBSEC_RNG_BUFSIZ 16 /* measured in 32bit words */ - -struct ubsec_dmachunk { - struct ubsec_mcr d_mcr; - struct ubsec_mcr_add d_mcradd[UBS_MAX_AGGR-1]; - struct ubsec_pktbuf d_sbuf[UBS_MAX_SCATTER-1]; - struct ubsec_pktbuf d_dbuf[UBS_MAX_SCATTER-1]; - u_int32_t d_macbuf[5]; - union { - struct ubsec_pktctx_aes256 ctx_aes256; - struct ubsec_pktctx_aes192 ctx_aes192; - struct ubsec_pktctx_aes128 ctx_aes128; - struct ubsec_pktctx_3des ctx_3des; - struct ubsec_pktctx ctx; - } d_ctx; -}; - -struct ubsec_dma { - SIMPLEQ_ENTRY(ubsec_dma) d_next; - struct ubsec_dmachunk *d_dma; - struct ubsec_dma_alloc d_alloc; -}; - -#define UBS_FLAGS_KEY 0x01 /* has key accelerator */ -#define UBS_FLAGS_LONGCTX 0x02 /* uses long ipsec ctx */ -#define UBS_FLAGS_BIGKEY 0x04 /* 2048bit keys */ -#define UBS_FLAGS_HWNORM 0x08 /* hardware normalization */ -#define UBS_FLAGS_RNG 0x10 /* hardware rng */ -#define UBS_FLAGS_AES 0x20 /* supports aes */ -#define UBS_FLAGS_MULTIMCR 0x40 /* 5827+ with 4 MCRs */ -#define UBS_FLAGS_RNG4 0x80 /* 5827+ RNG on MCR4 */ - -struct ubsec_q { - SIMPLEQ_ENTRY(ubsec_q) q_next; - int q_nstacked_mcrs; - struct ubsec_q *q_stacked_mcr[UBS_MAX_AGGR-1]; - struct cryptop *q_crp; - struct ubsec_dma *q_dma; - - struct mbuf *q_src_m, *q_dst_m; - struct uio *q_src_io, *q_dst_io; - - bus_dmamap_t q_src_map; - bus_dmamap_t q_dst_map; - - int q_sesn; -}; - -struct ubsec_softc { - struct device sc_dv; /* generic device */ - void *sc_ih; /* interrupt handler cookie */ - bus_space_handle_t sc_sh; /* memory handle */ - bus_space_tag_t sc_st; /* memory tag */ - bus_dma_tag_t sc_dmat; /* dma tag */ - int sc_flags; /* device specific flags */ - u_int32_t sc_statmask; /* interrupt status mask */ - int32_t sc_cid; /* crypto tag */ - int sc_maxaggr; /* max pkt aggregation */ - SIMPLEQ_HEAD(,ubsec_q) sc_queue; /* packet queue, mcr1 */ - int sc_nqueue; /* count enqueued, mcr1 */ - SIMPLEQ_HEAD(,ubsec_q) sc_qchip; /* on chip, mcr1 */ - SIMPLEQ_HEAD(,ubsec_q) sc_freequeue; /* list of free queue elements */ - SIMPLEQ_HEAD(,ubsec_q2) sc_queue2; /* packet queue, mcr2 */ - int sc_nqueue2; /* count enqueued, mcr2 */ - SIMPLEQ_HEAD(,ubsec_q2) sc_qchip2; /* on chip, mcr2 */ - SIMPLEQ_HEAD(,ubsec_q2) sc_queue4; /* packet queue, mcr4 */ - int sc_nqueue4; /* count enqueued, mcr4 */ - SIMPLEQ_HEAD(,ubsec_q2) sc_qchip4; /* on chip, mcr4 */ - int sc_nsessions; /* # of sessions */ - struct ubsec_session *sc_sessions; /* sessions */ - struct timeout sc_rngto; /* rng timeout */ - int sc_rngms; /* rng poll time (msecs) */ - struct ubsec_q2_rng sc_rng; - struct ubsec_dma sc_dmaa[UBS_MAX_NQUEUE]; - struct ubsec_q *sc_queuea[UBS_MAX_NQUEUE]; -}; - -struct ubsec_session { - u_int32_t ses_used; - u_int32_t ses_key[8]; /* 3DES/AES key */ - u_int32_t ses_hminner[5]; /* hmac inner state */ - u_int32_t ses_hmouter[5]; /* hmac outer state */ - u_int32_t ses_iv[4]; /* [3]DES iv or AES iv/icv */ -}; - -struct ubsec_stats { - u_int64_t hst_ibytes; - u_int64_t hst_obytes; - u_int32_t hst_ipackets; - u_int32_t hst_opackets; - u_int32_t hst_invalid; - u_int32_t hst_nomem; - u_int32_t hst_queuefull; - u_int32_t hst_dmaerr; - u_int32_t hst_mcrerr; - u_int32_t hst_nodmafree; -}; |