diff options
author | sam <sam@FreeBSD.org> | 2007-03-21 03:42:51 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2007-03-21 03:42:51 +0000 |
commit | f96ba7ffdacde02e9c3e989c8f6e3e7539b74b46 (patch) | |
tree | 05fc03ec94859546cbef49b9fe30d492c4f7bf19 /sys/dev | |
parent | 3f9dd9edcb00155dff6a9b7686ce432606296d79 (diff) | |
download | FreeBSD-src-f96ba7ffdacde02e9c3e989c8f6e3e7539b74b46.zip FreeBSD-src-f96ba7ffdacde02e9c3e989c8f6e3e7539b74b46.tar.gz |
Overhaul driver/subsystem api's:
o make all crypto drivers have a device_t; pseudo drivers like the s/w
crypto driver synthesize one
o change the api between the crypto subsystem and drivers to use kobj;
cryptodev_if.m defines this api
o use the fact that all crypto drivers now have a device_t to add support
for specifying which of several potential devices to use when doing
crypto operations
o add new ioctls that allow user apps to select a specific crypto device
to use (previous ioctls maintained for compatibility)
o overhaul crypto subsystem code to eliminate lots of cruft and hide
implementation details from drivers
o bring in numerous fixes from Michale Richardson/hifn; mostly for
795x parts
o add an optional mechanism for mmap'ing the hifn 795x public key h/w
to user space for use by openssl (not enabled by default)
o update crypto test tools to use new ioctl's and add cmd line options
to specify a device to use for tests
These changes will also enable much future work on improving the core
crypto subsystem; including proper load balancing and interposing code
between the core and drivers to dispatch small operations to the s/w
driver as appropriate.
These changes were instigated by the work of Michael Richardson.
Reviewed by: pjd
Approved by: re
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/hifn/hifn7751.c | 262 | ||||
-rw-r--r-- | sys/dev/hifn/hifn7751reg.h | 41 | ||||
-rw-r--r-- | sys/dev/hifn/hifn7751var.h | 3 | ||||
-rw-r--r-- | sys/dev/safe/safe.c | 56 | ||||
-rw-r--r-- | sys/dev/ubsec/ubsec.c | 54 |
5 files changed, 276 insertions, 140 deletions
diff --git a/sys/dev/hifn/hifn7751.c b/sys/dev/hifn/hifn7751.c index 6f2666f..d3a66e6 100644 --- a/sys/dev/hifn/hifn7751.c +++ b/sys/dev/hifn/hifn7751.c @@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/cryptodev.h> #include <sys/random.h> +#include <sys/kobj.h> + +#include "cryptodev_if.h" #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> @@ -80,6 +83,13 @@ __FBSDID("$FreeBSD$"); #include <dev/hifn/hifn7751reg.h> #include <dev/hifn/hifn7751var.h> +#ifdef HIFN_VULCANDEV +#include <sys/conf.h> +#include <sys/uio.h> + +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */ +#endif + /* * Prototypes and count for the pci_device structure */ @@ -90,6 +100,10 @@ static int hifn_suspend(device_t); static int hifn_resume(device_t); static void hifn_shutdown(device_t); +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *); +static int hifn_freesession(device_t, u_int64_t); +static int hifn_process(device_t, struct cryptop *, int); + static device_method_t hifn_methods[] = { /* Device interface */ DEVMETHOD(device_probe, hifn_probe), @@ -103,6 +117,11 @@ static device_method_t hifn_methods[] = { DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_driver_added, bus_generic_driver_added), + /* crypto device methods */ + DEVMETHOD(cryptodev_newsession, hifn_newsession), + DEVMETHOD(cryptodev_freesession,hifn_freesession), + DEVMETHOD(cryptodev_process, hifn_process), + { 0, 0 } }; static driver_t hifn_driver = { @@ -132,9 +151,6 @@ static void hifn_sessions(struct hifn_softc *); static void hifn_intr(void *); static u_int hifn_write_command(struct hifn_command *, u_int8_t *); static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt); -static int hifn_newsession(void *, u_int32_t *, struct cryptoini *); -static int hifn_freesession(void *, u_int64_t); -static int hifn_process(void *, struct cryptop *, int); static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *); static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int); static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *); @@ -279,6 +295,12 @@ checkmaxmin(device_t dev, const char *what, u_int v, u_int min, u_int max) * always will allow the card to work. If a card is using the PCI * bus clock and in a 33MHz slot then it will be operating at half * speed until the correct information is provided. + * + * We use a default setting of "ext66" because according to Mike Ham + * of HiFn, almost every board in existence has an external crystal + * populated at 66Mhz. Using PCI can be a problem on modern motherboards, + * because PCI33 can have clocks from 0 to 33Mhz, and some have + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll. */ static void hifn_getpllconfig(device_t dev, u_int *pll) @@ -290,7 +312,7 @@ hifn_getpllconfig(device_t dev, u_int *pll) if (resource_string_value("hifn", device_get_unit(dev), "pllconfig", &pllspec)) - pllspec = "pci66"; + pllspec = "ext66"; fl = 33, fh = 66; pllconfig = 0; if (strncmp(pllspec, "ext", 3) == 0) { @@ -559,7 +581,7 @@ hifn_attach(device_t dev) 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11)); printf("\n"); - sc->sc_cid = crypto_get_driverid(0); + sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE); if (sc->sc_cid < 0) { device_printf(dev, "could not get crypto driver id\n"); goto fail_intr; @@ -571,26 +593,17 @@ hifn_attach(device_t dev) switch (ena) { case HIFN_PUSTAT_ENA_2: - crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); - crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0); if (sc->sc_flags & HIFN_HAS_AES) - crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, - hifn_newsession, hifn_freesession, - hifn_process, sc); + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0); /*FALLTHROUGH*/ case HIFN_PUSTAT_ENA_1: - crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); - crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); - crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); - crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); - crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, - hifn_newsession, hifn_freesession, hifn_process, sc); + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0); break; } @@ -790,6 +803,12 @@ hifn_init_pubrng(struct hifn_softc *sc) 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); +#ifdef HIFN_VULCANDEV + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0, + UID_ROOT, GID_WHEEL, 0666, + "vulcanpk"); + sc->sc_pkdev->si_drv1 = sc; +#endif } return (0); @@ -804,6 +823,7 @@ hifn_rng(void *vsc) int i; if (sc->sc_flags & HIFN_IS_7811) { + /* ONLY VALID ON 7811!!!! */ for (i = 0; i < 5; i++) { sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS); if (sts & HIFN_7811_RNGSTS_UFL) { @@ -846,10 +866,15 @@ static void hifn_puc_wait(struct hifn_softc *sc) { int i; + int reg = HIFN_0_PUCTRL; + + if (sc->sc_flags & HIFN_IS_7956) { + reg = HIFN_0_PUCTRL2; + } for (i = 5000; i > 0; i--) { DELAY(1); - if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET)) + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET)) break; } if (!i) @@ -863,7 +888,13 @@ static void hifn_reset_puc(struct hifn_softc *sc) { /* Reset processing unit */ - WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA); + int reg = HIFN_0_PUCTRL; + + if (sc->sc_flags & HIFN_IS_7956) { + reg = HIFN_0_PUCTRL2; + } + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA); + hifn_puc_wait(sc); } @@ -932,7 +963,16 @@ hifn_reset_board(struct hifn_softc *sc, int full) } if (reg == 1000) printf(": cram init timeout\n"); - } + } else { + /* set up DMA configuration register #2 */ + /* turn off all PK and BAR0 swaps */ + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2, + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)| + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)| + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)| + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT)); + } + } static u_int32_t @@ -1170,13 +1210,15 @@ hifn_init_pci_registers(struct hifn_softc *sc) /* turn off the clocks and insure bypass is set */ pll = READ_REG_1(sc, HIFN_1_PLL); pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL)) - | HIFN_PLL_BP; + | HIFN_PLL_BP | HIFN_PLL_MBSET; WRITE_REG_1(sc, HIFN_1_PLL, pll); DELAY(10*1000); /* 10ms */ + /* change configuration */ pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig; WRITE_REG_1(sc, HIFN_1_PLL, pll); DELAY(10*1000); /* 10ms */ + /* disable bypass */ pll &= ~HIFN_PLL_BP; WRITE_REG_1(sc, HIFN_1_PLL, pll); @@ -1657,6 +1699,21 @@ hifn_dmamap_aligned(struct hifn_operand *op) return (1); } +static __inline int +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx) +{ + struct hifn_dma *dma = sc->sc_dma; + + 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; + } + return (idx); +} + static int hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd) { @@ -1674,13 +1731,7 @@ hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd) 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; - } + idx = hifn_dmamap_dstwrap(sc, idx); } if (cmd->sloplen == 0) { @@ -1702,13 +1753,7 @@ hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd) 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; - } + idx = hifn_dmamap_dstwrap(sc, idx); } } dma->dstr[idx].p = htole32(p); @@ -1716,19 +1761,28 @@ hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd) 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; - } + idx = hifn_dmamap_dstwrap(sc, idx); dma->dsti = idx; dma->dstu += used; return (idx); } +static __inline int +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx) +{ + struct hifn_dma *dma = sc->sc_dma; + + 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; + } + return (idx); +} + static int hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd) { @@ -1748,13 +1802,7 @@ hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd) 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; - } + idx = hifn_dmamap_srcwrap(sc, idx); } dma->srci = idx; dma->srcu += src->nsegs; @@ -1782,7 +1830,7 @@ hifn_crypto( int hint) { struct hifn_dma *dma = sc->sc_dma; - u_int32_t cmdlen; + u_int32_t cmdlen, csr; int cmdi, resi, err = 0; /* @@ -1995,10 +2043,6 @@ hifn_crypto( 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; - } /* * We don't worry about missing an interrupt (which a "command wait" @@ -2014,10 +2058,6 @@ hifn_crypto( hifnstats.hst_ibytes += cmd->src_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; - } /* * Unlike other descriptors, we don't mask done interrupt from @@ -2054,20 +2094,31 @@ hifn_crypto( 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; - } if (cmd->sloplen) cmd->slopidx = resi; hifn_dmamap_load_dst(sc, cmd); + csr = 0; + if (sc->sc_c_busy == 0) { + csr |= HIFN_DMACSR_C_CTRL_ENA; + sc->sc_c_busy = 1; + } + if (sc->sc_s_busy == 0) { + csr |= HIFN_DMACSR_S_CTRL_ENA; + sc->sc_s_busy = 1; + } + if (sc->sc_r_busy == 0) { + csr |= HIFN_DMACSR_R_CTRL_ENA; + sc->sc_r_busy = 1; + } if (sc->sc_d_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); + csr |= HIFN_DMACSR_D_CTRL_ENA; sc->sc_d_busy = 1; } + if (csr) + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr); #ifdef HIFN_DEBUG if (hifn_debug) { @@ -2292,10 +2343,10 @@ hifn_intr(void *arg) * id on successful allocation. */ static int -hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri) { + struct hifn_softc *sc = device_get_softc(dev); struct cryptoini *c; - struct hifn_softc *sc = arg; int mac = 0, cry = 0, sesn; struct hifn_session *ses = NULL; @@ -2303,11 +2354,14 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) if (sidp == NULL || cri == NULL || sc == NULL) return (EINVAL); + HIFN_LOCK(sc); if (sc->sc_sessions == NULL) { ses = sc->sc_sessions = (struct hifn_session *)malloc( sizeof(*ses), M_DEVBUF, M_NOWAIT); - if (ses == NULL) + if (ses == NULL) { + HIFN_UNLOCK(sc); return (ENOMEM); + } sesn = 0; sc->sc_nsessions = 1; } else { @@ -2322,8 +2376,10 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) sesn = sc->sc_nsessions; ses = (struct hifn_session *)malloc((sesn + 1) * sizeof(*ses), M_DEVBUF, M_NOWAIT); - if (ses == NULL) + if (ses == NULL) { + HIFN_UNLOCK(sc); return (ENOMEM); + } bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses)); bzero(sc->sc_sessions, sesn * sizeof(*ses)); free(sc->sc_sessions, M_DEVBUF); @@ -2332,6 +2388,8 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) sc->sc_nsessions++; } } + HIFN_UNLOCK(sc); + bzero(ses, sizeof(*ses)); ses->hs_used = 1; @@ -2389,28 +2447,32 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) * XXX to blow away any keys already stored there. */ static int -hifn_freesession(void *arg, u_int64_t tid) +hifn_freesession(device_t dev, u_int64_t tid) { - struct hifn_softc *sc = arg; - int session; + struct hifn_softc *sc = device_get_softc(dev); + int session, error; u_int32_t sid = CRYPTO_SESID2LID(tid); KASSERT(sc != NULL, ("hifn_freesession: null softc")); if (sc == NULL) return (EINVAL); + HIFN_LOCK(sc); session = HIFN_SESSION(sid); - if (session >= sc->sc_nsessions) - return (EINVAL); + if (session < sc->sc_nsessions) { + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session)); + error = 0; + } else + error = EINVAL; + HIFN_UNLOCK(sc); - bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session])); - return (0); + return (error); } static int -hifn_process(void *arg, struct cryptop *crp, int hint) +hifn_process(device_t dev, struct cryptop *crp, int hint) { - struct hifn_softc *sc = arg; + struct hifn_softc *sc = device_get_softc(dev); struct hifn_command *cmd = NULL; int session, err, ivlen; struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; @@ -2858,3 +2920,41 @@ hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val) } bus_space_write_4(sc->sc_st1, sc->sc_sh1, reg, val); } + +#ifdef HIFN_VULCANDEV +/* + * this code provides support for mapping the PK engine's register + * into a userspace program. + * + */ +static int +vulcanpk_mmap(struct cdev *dev, vm_offset_t offset, + vm_paddr_t *paddr, int nprot) +{ + struct hifn_softc *sc; + vm_paddr_t pd; + void *b; + + sc = dev->si_drv1; + + pd = rman_get_start(sc->sc_bar1res); + b = rman_get_virtual(sc->sc_bar1res); + +#if 0 + printf("vpk mmap: %p(%08x) offset=%d\n", b, pd, offset); + hexdump(b, HIFN_1_PUB_MEMEND, "vpk", 0); +#endif + + if (offset == 0) { + *paddr = pd; + return (0); + } + return (-1); +} + +static struct cdevsw vulcanpk_cdevsw = { + .d_version = D_VERSION, + .d_mmap = vulcanpk_mmap, + .d_name = "vulcanpk", +}; +#endif /* HIFN_VULCANDEV */ diff --git a/sys/dev/hifn/hifn7751reg.h b/sys/dev/hifn/hifn7751reg.h index a102288..c3b3438 100644 --- a/sys/dev/hifn/hifn7751reg.h +++ b/sys/dev/hifn/hifn7751reg.h @@ -118,7 +118,10 @@ typedef struct hifn_desc { #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 */ +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */ +#define HIFN_0_MUTE1 0x80 +#define HIFN_0_MUTE2 0x90 +#define HIFN_0_SPACESIZE 0x100 /* Register space size */ /* Processing Unit Control Register (HIFN_0_PUCTRL) */ #define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */ @@ -200,7 +203,7 @@ typedef struct hifn_desc { #define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */ /* FIFO Configuration Register (HIFN_0_FIFOCNFG) */ -#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as 1 */ +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */ /* * DMA Interface Registers (offset from BASEREG1) @@ -217,17 +220,21 @@ typedef struct hifn_desc { #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_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */ #define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */ #define HIFN_1_REVID 0x98 /* Revision ID */ #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 nable */ +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */ +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */ +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat 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_MODE 0x320 /* PK mode */ +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */ +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */ #define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */ #define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */ @@ -305,6 +312,16 @@ typedef struct hifn_desc { #define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */ #define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */ +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */ +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */ +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */ +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */ +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */ +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12 +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8 +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4 +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0 + /* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */ #define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */ @@ -358,6 +375,11 @@ typedef struct hifn_desc { /* Public status register (HIFN_1_PUB_STATUS) */ #define HIFN_PUBSTS_DONE 0x00000001 /* operation done */ #define HIFN_PUBSTS_CARRY 0x00000002 /* carry */ +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */ +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */ +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */ +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */ +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */ /* Public interrupt enable register (HIFN_1_PUB_IEN) */ #define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */ @@ -407,6 +429,13 @@ typedef struct hifn_desc { */ #define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL) +/* + * Public Key Engine Mode Register + */ +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */ +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */ + + /********************************************************************* * Structs for board commands * diff --git a/sys/dev/hifn/hifn7751var.h b/sys/dev/hifn/hifn7751var.h index def3e0a..0874943 100644 --- a/sys/dev/hifn/hifn7751var.h +++ b/sys/dev/hifn/hifn7751var.h @@ -183,6 +183,9 @@ struct hifn_softc { int sc_needwakeup; /* ops q'd wating on resources */ int sc_curbatch; /* # ops submitted w/o int */ int sc_suspended; +#ifdef HIFN_VULCANDEV + struct cdev *sc_pkdev; +#endif }; #define HIFN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) diff --git a/sys/dev/safe/safe.c b/sys/dev/safe/safe.c index 7551e14..c594295 100644 --- a/sys/dev/safe/safe.c +++ b/sys/dev/safe/safe.c @@ -59,6 +59,9 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/cryptosoft.h> #include <sys/md5.h> #include <sys/random.h> +#include <sys/kobj.h> + +#include "cryptodev_if.h" #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> @@ -83,6 +86,10 @@ static int safe_suspend(device_t); static int safe_resume(device_t); static void safe_shutdown(device_t); +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *); +static int safe_freesession(device_t, u_int64_t); +static int safe_process(device_t, struct cryptop *, int); + static device_method_t safe_methods[] = { /* Device interface */ DEVMETHOD(device_probe, safe_probe), @@ -96,6 +103,11 @@ static device_method_t safe_methods[] = { DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_driver_added, bus_generic_driver_added), + /* crypto device methods */ + DEVMETHOD(cryptodev_newsession, safe_newsession), + DEVMETHOD(cryptodev_freesession,safe_freesession), + DEVMETHOD(cryptodev_process, safe_process), + { 0, 0 } }; static driver_t safe_driver = { @@ -112,9 +124,6 @@ MODULE_DEPEND(safe, rndtest, 1, 1, 1); #endif static void safe_intr(void *); -static int safe_newsession(void *, u_int32_t *, struct cryptoini *); -static int safe_freesession(void *, u_int64_t); -static int safe_process(void *, struct cryptop *, int); static void safe_callback(struct safe_softc *, struct safe_ringentry *); static void safe_feed(struct safe_softc *, struct safe_ringentry *); static void safe_mcopy(struct mbuf *, struct mbuf *, u_int); @@ -270,7 +279,7 @@ safe_attach(device_t dev) goto bad2; } - sc->sc_cid = crypto_get_driverid(0); + sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE); if (sc->sc_cid < 0) { device_printf(dev, "could not get crypto driver id\n"); goto bad3; @@ -388,39 +397,30 @@ safe_attach(device_t dev) #if 0 printf(" key"); sc->sc_flags |= SAFE_FLAGS_KEY; - crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0, - safe_kprocess, sc); - crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0, - safe_kprocess, sc); + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0); + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0); #endif } if (devinfo & SAFE_DEVINFO_DES) { printf(" des/3des"); - crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); - crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0); } if (devinfo & SAFE_DEVINFO_AES) { printf(" aes"); - crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0); } if (devinfo & SAFE_DEVINFO_MD5) { printf(" md5"); - crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0); } if (devinfo & SAFE_DEVINFO_SHA1) { printf(" sha1"); - crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0); } printf(" null"); - crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); - crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0, - safe_newsession, safe_freesession, safe_process, sc); + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0); /* XXX other supported algorithms */ printf("\n"); @@ -710,10 +710,10 @@ safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen) * id on successful allocation. */ static int -safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri) { + struct safe_softc *sc = device_get_softc(dev); struct cryptoini *c, *encini = NULL, *macini = NULL; - struct safe_softc *sc = arg; struct safe_session *ses = NULL; int sesn; @@ -826,9 +826,9 @@ safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) * Deallocate a session. */ static int -safe_freesession(void *arg, u_int64_t tid) +safe_freesession(device_t dev, u_int64_t tid) { - struct safe_softc *sc = arg; + struct safe_softc *sc = device_get_softc(dev); int session, ret; u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; @@ -859,10 +859,10 @@ safe_op_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, int } static int -safe_process(void *arg, struct cryptop *crp, int hint) +safe_process(device_t dev, struct cryptop *crp, int hint) { + struct safe_softc *sc = device_get_softc(dev); int err = 0, i, nicealign, uniform; - struct safe_softc *sc = arg; struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; int bypass, oplen, ivsize; caddr_t iv; diff --git a/sys/dev/ubsec/ubsec.c b/sys/dev/ubsec/ubsec.c index 8cd2f74..f0e5399 100644 --- a/sys/dev/ubsec/ubsec.c +++ b/sys/dev/ubsec/ubsec.c @@ -73,6 +73,9 @@ __FBSDID("$FreeBSD$"); #include <opencrypto/cryptosoft.h> #include <sys/md5.h> #include <sys/random.h> +#include <sys/kobj.h> + +#include "cryptodev_if.h" #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> @@ -106,6 +109,11 @@ static int ubsec_suspend(device_t); static int ubsec_resume(device_t); static void ubsec_shutdown(device_t); +static int ubsec_newsession(device_t, u_int32_t *, struct cryptoini *); +static int ubsec_freesession(device_t, u_int64_t); +static int ubsec_process(device_t, struct cryptop *, int); +static int ubsec_kprocess(device_t, struct cryptkop *, int); + static device_method_t ubsec_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ubsec_probe), @@ -119,6 +127,12 @@ static device_method_t ubsec_methods[] = { DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_driver_added, bus_generic_driver_added), + /* crypto device methods */ + DEVMETHOD(cryptodev_newsession, ubsec_newsession), + DEVMETHOD(cryptodev_freesession,ubsec_freesession), + DEVMETHOD(cryptodev_process, ubsec_process), + DEVMETHOD(cryptodev_kprocess, ubsec_kprocess), + { 0, 0 } }; static driver_t ubsec_driver = { @@ -135,9 +149,6 @@ MODULE_DEPEND(ubsec, rndtest, 1, 1, 1); #endif static void ubsec_intr(void *); -static int ubsec_newsession(void *, u_int32_t *, struct cryptoini *); -static int ubsec_freesession(void *, u_int64_t); -static int ubsec_process(void *, struct cryptop *, int); static void ubsec_callback(struct ubsec_softc *, struct ubsec_q *); static void ubsec_feed(struct ubsec_softc *); static void ubsec_mcopy(struct mbuf *, struct mbuf *, int, int); @@ -158,7 +169,6 @@ static void ubsec_totalreset(struct ubsec_softc *sc); static int ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q); -static int ubsec_kprocess(void*, struct cryptkop *, int); static int ubsec_kprocess_modexp_hw(struct ubsec_softc *, struct cryptkop *, int); static int ubsec_kprocess_modexp_sw(struct ubsec_softc *, struct cryptkop *, int); static int ubsec_kprocess_rsapriv(struct ubsec_softc *, struct cryptkop *, int); @@ -350,7 +360,7 @@ ubsec_attach(device_t dev) goto bad2; } - sc->sc_cid = crypto_get_driverid(0); + sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE); if (sc->sc_cid < 0) { device_printf(dev, "could not get crypto driver id\n"); goto bad3; @@ -405,14 +415,10 @@ ubsec_attach(device_t dev) device_printf(sc->sc_dev, "%s\n", ubsec_partname(sc)); - crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, - ubsec_newsession, ubsec_freesession, ubsec_process, sc); - crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, - ubsec_newsession, ubsec_freesession, ubsec_process, sc); - crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, - ubsec_newsession, ubsec_freesession, ubsec_process, sc); - crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, - ubsec_newsession, ubsec_freesession, ubsec_process, sc); + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0); + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0); /* * Reset Broadcom chip @@ -475,11 +481,9 @@ skip_rng: if (sc->sc_flags & UBS_FLAGS_KEY) { sc->sc_statmask |= BS_STAT_MCR2_DONE; - crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0, - ubsec_kprocess, sc); + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0); #if 0 - crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0, - ubsec_kprocess, sc); + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0); #endif } return (0); @@ -900,10 +904,10 @@ ubsec_setup_mackey(struct ubsec_session *ses, int algo, caddr_t key, int klen) * id on successful allocation. */ static int -ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) +ubsec_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri) { + struct ubsec_softc *sc = device_get_softc(dev); struct cryptoini *c, *encini = NULL, *macini = NULL; - struct ubsec_softc *sc = arg; struct ubsec_session *ses = NULL; int sesn; @@ -995,9 +999,9 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) * Deallocate a session. */ static int -ubsec_freesession(void *arg, u_int64_t tid) +ubsec_freesession(device_t dev, u_int64_t tid) { - struct ubsec_softc *sc = arg; + struct ubsec_softc *sc = device_get_softc(dev); int session, ret; u_int32_t sid = CRYPTO_SESID2LID(tid); @@ -1035,11 +1039,11 @@ ubsec_op_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, in } static int -ubsec_process(void *arg, struct cryptop *crp, int hint) +ubsec_process(device_t dev, struct cryptop *crp, int hint) { + struct ubsec_softc *sc = device_get_softc(dev); struct ubsec_q *q = NULL; int err = 0, i, j, nicealign; - struct ubsec_softc *sc = arg; struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; int encoffset = 0, macoffset = 0, cpskip, cpoffset; int sskip, dskip, stheend, dtheend; @@ -2110,9 +2114,9 @@ ubsec_kfree(struct ubsec_softc *sc, struct ubsec_q2 *q) } static int -ubsec_kprocess(void *arg, struct cryptkop *krp, int hint) +ubsec_kprocess(device_t dev, struct cryptkop *krp, int hint) { - struct ubsec_softc *sc = arg; + struct ubsec_softc *sc = device_get_softc(dev); int r; if (krp == NULL || krp->krp_callback == NULL) |