diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2003-08-14 15:26:04 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2003-08-14 15:26:04 +0000 |
commit | 7bfb36ebbb69a872490a86feb0dc96be035fa603 (patch) | |
tree | 2bc4463867569f0b12bbd6f70a506357427359c6 /sys | |
parent | 0e8986d036e9f3924367cde1cd1c0b87f9f6f9a0 (diff) |
- remove some uneeded junk (mainly leftovers from ubsec cut/paste)
- fix interrupt printing
- make shared structure entries volatile to ensure ordering
- swap the key, iv, and mackey arguments appropriately
- treat particle descriptor as two 32 elements (necessary for swabbing)
- set the endian control byte correctly and flip off swabbing on the packet data
(now works on macppc)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/safe.c | 116 | ||||
-rw-r--r-- | sys/dev/pci/safereg.h | 69 | ||||
-rw-r--r-- | sys/dev/pci/safevar.h | 6 |
3 files changed, 93 insertions, 98 deletions
diff --git a/sys/dev/pci/safe.c b/sys/dev/pci/safe.c index 69d7a9eb173..3a566d2beb1 100644 --- a/sys/dev/pci/safe.c +++ b/sys/dev/pci/safe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: safe.c,v 1.3 2003/08/12 23:08:46 jason Exp $ */ +/* $OpenBSD: safe.c,v 1.4 2003/08/14 15:26:03 jason Exp $ */ /*- * Copyright (c) 2003 Sam Leffler, Errno Consulting @@ -103,7 +103,6 @@ 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 *); -void safe_totalreset(struct safe_softc *); __inline u_int32_t safe_rng_read(struct safe_softc *); int safe_free_entry(struct safe_softc *, struct safe_ringentry *); @@ -179,7 +178,7 @@ safe_attach(struct device *parent, struct device *self, void *aux) /* * Setup memory-mapping of PCI registers. */ - if (pci_mapreg_map(pa, BS_BAR, PCI_MAPREG_TYPE_MEM, 0, + 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; @@ -265,14 +264,14 @@ safe_attach(struct device *parent, struct device *self, void *aux) sc->sc_dpfree = sc->sc_dpring; bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc)); - printf(":"); + printf(": %s", intrstr); devinfo = READ_REG(sc, SAFE_DEVINFO); if (devinfo & SAFE_DEVINFO_RNG) printf(" rng"); bzero(algs, sizeof(algs)); -#if 0 +#ifdef notyet /* Key ops not supported yet */ if (devinfo & SAFE_DEVINFO_PKEY) { printf(" key"); @@ -335,13 +334,12 @@ safe_process(struct cryptop *crp) struct safe_softc *sc; struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; int bypass, oplen, ivsize, card; - caddr_t iv; 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; + u_int32_t cmd0, cmd1, staterec, iv[4]; s = splnet(); if (crp == NULL || crp->crp_callback == NULL) { @@ -482,34 +480,34 @@ safe_process(struct cryptop *crp) cmd0 |= SAFE_SA_CMD0_OUTBOUND; if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - iv = enccrd->crd_iv; + bcopy(enccrd->crd_iv, iv, ivsize); else - iv = (caddr_t) ses->ses_iv; + bcopy(ses->ses_iv, iv, ivsize); if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { if (crp->crp_flags & CRYPTO_F_IMBUF) m_copyback(re->re_src_m, - enccrd->crd_inject, ivsize, iv); + enccrd->crd_inject, ivsize, iv); else if (crp->crp_flags & CRYPTO_F_IOV) cuio_copyback(re->re_src_io, - enccrd->crd_inject, ivsize, iv); + enccrd->crd_inject, ivsize, iv); } - bcopy(iv, re->re_sastate.sa_saved_iv, ivsize); + 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; re->re_flags |= SAFE_QFLAGS_COPYOUTIV; } else { cmd0 |= SAFE_SA_CMD0_INBOUND; if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, - re->re_sastate.sa_saved_iv, ivsize); + bcopy(enccrd->crd_iv, iv, ivsize); else if (crp->crp_flags & CRYPTO_F_IMBUF) m_copydata(re->re_src_m, enccrd->crd_inject, - ivsize, - (caddr_t)re->re_sastate.sa_saved_iv); + ivsize, (caddr_t)iv); else if (crp->crp_flags & CRYPTO_F_IOV) cuio_copydata(re->re_src_io, enccrd->crd_inject, - ivsize, - (caddr_t)re->re_sastate.sa_saved_iv); + 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; } /* @@ -523,7 +521,8 @@ safe_process(struct cryptop *crp) cmd0 |= SAFE_SA_CMD0_PAD_ZERO; /* XXX assert key bufs have the same size */ - bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key)); + for (i = 0; i < sizeof(sa->sa_key)/sizeof(sa->sa_key[0]); i++) + sa->sa_key[i] = ses->ses_key[i]; } if (maccrd) { @@ -542,10 +541,12 @@ safe_process(struct cryptop *crp) * retrieve it for return to the caller. */ /* XXX assert digest bufs have the same size */ - bcopy(ses->ses_hminner, sa->sa_indigest, - sizeof(sa->sa_indigest)); - bcopy(ses->ses_hmouter, sa->sa_outdigest, - sizeof(sa->sa_outdigest)); + for (i = 0; + i < sizeof(sa->sa_outdigest)/sizeof(sa->sa_outdigest[i]); + 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; @@ -680,8 +681,9 @@ safe_process(struct cryptop *crp) ("bogus source particle descriptor; flags %x", pd->pd_flags)); pd->pd_addr = re->re_src_segs[i].ds_addr; - pd->pd_size = re->re_src_segs[i].ds_len; - pd->pd_flags = SAFE_PD_READY; + 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 { @@ -915,7 +917,7 @@ safe_process(struct cryptop *crp) 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_flags = SAFE_PD_READY; + pd->pd_ctrl = SAFE_PD_READY; } cmd0 |= SAFE_SA_CMD0_OSCATTER; } else { @@ -1013,20 +1015,23 @@ safe_init_board(struct safe_softc *sc) { u_int32_t v, dwords; - v = READ_REG(sc, SAFE_PE_DMACFG);; - v &=~ SAFE_PE_DMACFG_PEMODE; + 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_ESSA /* endian-swap SA's */ | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */ + | SAFE_PE_DMACFG_ESSA /* endian-swap SA data */ ; WRITE_REG(sc, SAFE_PE_DMACFG, v); -#if 0 - /* XXX select byte swap based on host byte order */ - WRITE_REG(sc, SAFE_ENDIAN, 0x1b); + +#if BYTE_ORDER == LITTLE_ENDIAN + WRITE_REG(sc, SAFE_ENDIAN, 0x00e400e4); +#elif BYTE_ORDER == BIG_ENDIAN + WRITE_REG(sc, SAFE_ENDIAN, 0x00e4001b); #endif + if (sc->sc_chiprev == SAFE_REV(1,0)) { /* * Avoid large PCI DMA transfers. Rev 1.0 has a bug where @@ -1043,6 +1048,12 @@ safe_init_board(struct safe_softc *sc) SAFE_REV_MIN(sc->sc_chiprev)); } + /* + * XXX: not sure why this delay is necessary. Without it, my MacPPC + * hangs on every boot. + */ + DELAY(1000); + /* 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); @@ -1050,16 +1061,16 @@ safe_init_board(struct safe_softc *sc) * 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!")); + ("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); + (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); + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART); /* * NB: destination particles are fixed size. We use * an mbuf cluster and require all results go to @@ -1189,7 +1200,7 @@ safe_rng_read(struct safe_softc *sc) i = 0; while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT) ; - return READ_REG(sc, SAFE_RNG_OUT); + return (READ_REG(sc, SAFE_RNG_OUT)); } void @@ -1357,7 +1368,6 @@ safe_newsession(u_int32_t *sidp, struct cryptoini *cri) ses->ses_klen = encini->cri_klen; bcopy(encini->cri_key, ses->ses_key, ses->ses_klen / 8); - /* PE is little-endian, insure proper byte order */ for (i = 0; i < sizeof(ses->ses_key)/sizeof(ses->ses_key[0]); i++) ses->ses_key[i] = htole32(ses->ses_key[i]); @@ -1450,18 +1460,6 @@ safe_freesession(u_int64_t tid) } /* - * Routine to reset the chip and clean up. - * It is assumed that the caller is in splimp() - */ -void -safe_totalreset(struct safe_softc *sc) -{ - safe_reset_board(sc); - safe_init_board(sc); - safe_cleanchip(sc); -} - -/* * 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. @@ -1524,7 +1522,7 @@ safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re) crp->crp_etype = EFAULT; crypto_done(crp); - return(0); + return (0); } /* @@ -1569,17 +1567,16 @@ safe_feed(struct safe_softc *sc, struct safe_ringentry *re) int safe_dmamap_uniform(const struct safe_operand *op) { - int result = 1; + int result = 1, i; - if (op->map->dm_nsegs > 0) { - int 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; - } + 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); } @@ -1899,4 +1896,5 @@ safe_dump_ring(struct safe_softc *sc, const char *tag) } while (re != sc->sc_front); } } + #endif /* SAFE_DEBUG */ diff --git a/sys/dev/pci/safereg.h b/sys/dev/pci/safereg.h index 249a617059a..67b22aae572 100644 --- a/sys/dev/pci/safereg.h +++ b/sys/dev/pci/safereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: safereg.h,v 1.1 2003/08/12 18:48:13 jason Exp $ */ +/* $OpenBSD: safereg.h,v 1.2 2003/08/14 15:26:03 jason Exp $ */ /*- * Copyright (c) 2003 Sam Leffler, Errno Consulting @@ -36,9 +36,7 @@ * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual. */ -#define BS_BAR 0x10 /* DMA base address register */ -#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */ -#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */ +#define SAFE_BAR 0x10 /* DMA base address register */ #define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */ @@ -163,8 +161,10 @@ #define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */ #define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */ -#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */ -#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */ +#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 */ @@ -287,11 +287,11 @@ * list of ``particle descriptors'' when using scatter/gather i/o. */ struct safe_desc { - u_int32_t d_csr; /* per-packet control/status */ - u_int32_t d_src; /* source address */ - u_int32_t d_dst; /* destination address */ - u_int32_t d_sa; /* SA address */ - u_int32_t d_len; /* length, bypass, status */ + 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 */ }; /* @@ -301,34 +301,35 @@ struct safe_desc { * by the setting of the SAFE_PE_PARTCFG register. */ struct safe_pdesc { - u_int32_t pd_addr; /* particle address */ - u_int16_t pd_flags; /* control word */ - u_int16_t pd_size; /* particle size (bytes) */ + volatile u_int32_t pd_addr; /* particle address */ + volatile u_int32_t pd_ctrl; /* length/flags */ }; -#define SAFE_PD_READY 0x0001 /* ready for processing */ -#define SAFE_PD_DONE 0x0002 /* h/w completed processing */ +#define SAFE_PD_LEN_M 0x0000ffff /* 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 { - u_int32_t sa_cmd0; - u_int32_t sa_cmd1; - u_int32_t sa_resv0; - u_int32_t sa_resv1; - u_int32_t sa_key[8]; /* DES/3DES/AES key */ - u_int32_t sa_indigest[5]; /* inner digest */ - u_int32_t sa_outdigest[5]; /* outer digest */ - u_int32_t sa_spi; /* SPI */ - u_int32_t sa_seqnum; /* sequence number */ - u_int32_t sa_seqmask[2]; /* sequence number mask */ - u_int32_t sa_resv2; - u_int32_t sa_staterec; /* address of state record */ - u_int32_t sa_resv3[2]; - u_int32_t sa_samgmt0; /* SA management field 0 */ - u_int32_t sa_samgmt1; /* SA management field 0 */ + 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 */ @@ -407,8 +408,8 @@ struct safe_sarec { * Security Associate State Record (Rev 1). */ struct safe_sastate { - u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */ - u_int32_t sa_saved_hashbc; /* saved hash byte count */ - u_int32_t sa_saved_indigest[5]; /* saved inner digest */ + 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 index e508ad844f4..794857f621e 100644 --- a/sys/dev/pci/safevar.h +++ b/sys/dev/pci/safevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: safevar.h,v 1.3 2003/08/12 23:08:46 jason Exp $ */ +/* $OpenBSD: safevar.h,v 1.4 2003/08/14 15:26:03 jason Exp $ */ /*- * Copyright (c) 2003 Sam Leffler, Errno Consulting @@ -51,10 +51,6 @@ #define SAFE_SESSION(sid) ( (sid) & 0x0fffffff) #define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff)) -#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */ -#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */ -#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */ - #ifdef _KERNEL /* * State associated with the allocation of each chunk |