[BACK]Return to safe.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/safe.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: safe.c,v 1.21 2007/02/28 22:16:55 deraadt Exp $       */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2003 Sam Leffler, Errno Consulting
                      5:  * Copyright (c) 2003 Global Technology Associates, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  *
                     29:  * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safe.c,v 1.1 2003/07/21 21:46:07 sam Exp $
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
                     33:
                     34: /*
                     35:  * SafeNet SafeXcel-1141 hardware crypto accelerator
                     36:  */
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/proc.h>
                     40: #include <sys/errno.h>
                     41: #include <sys/malloc.h>
                     42: #include <sys/kernel.h>
                     43: #include <sys/mbuf.h>
                     44: #include <sys/device.h>
                     45: #include <sys/timeout.h>
                     46:
                     47: #include <machine/bus.h>
                     48:
                     49: #include <crypto/md5.h>
                     50: #include <crypto/sha1.h>
                     51: #include <crypto/cryptodev.h>
                     52: #include <crypto/cryptosoft.h>
                     53: #include <dev/rndvar.h>
                     54:
                     55: #include <dev/pci/pcivar.h>
                     56: #include <dev/pci/pcireg.h>
                     57: #include <dev/pci/pcidevs.h>
                     58:
                     59: #include <dev/pci/safereg.h>
                     60: #include <dev/pci/safevar.h>
                     61:
                     62: #ifndef bswap32
                     63: #define        bswap32 NTOHL
                     64: #endif
                     65:
                     66: #define        KASSERT_X(x,y)
                     67:
                     68: /*
                     69:  * Prototypes and count for the pci_device structure
                     70:  */
                     71: int safe_probe(struct device *, void *, void *);
                     72: void safe_attach(struct device *, struct device *, void *);
                     73:
                     74: struct cfattach safe_ca = {
                     75:        sizeof(struct safe_softc), safe_probe, safe_attach
                     76: };
                     77:
                     78: struct cfdriver safe_cd = {
                     79:        0, "safe", DV_DULL
                     80: };
                     81:
                     82: int safe_intr(void *);
                     83: int safe_newsession(u_int32_t *, struct cryptoini *);
                     84: int safe_freesession(u_int64_t);
                     85: int safe_process(struct cryptop *);
                     86: int safe_kprocess(struct cryptkop *);
                     87: int safe_kstart(struct safe_softc *);
                     88: void safe_kload_reg(struct safe_softc *, u_int32_t, u_int32_t,
                     89:     struct crparam *);
                     90: struct safe_softc *safe_kfind(struct cryptkop *);
                     91: void safe_kpoll(void *);
                     92: void safe_kfeed(struct safe_softc *);
                     93: int safe_ksigbits(struct crparam *cr);
                     94: void safe_callback(struct safe_softc *, struct safe_ringentry *);
                     95: void safe_feed(struct safe_softc *, struct safe_ringentry *);
                     96: void safe_mcopy(struct mbuf *, struct mbuf *, u_int);
                     97: void safe_rng_init(struct safe_softc *);
                     98: void safe_rng(void *);
                     99: int safe_dma_malloc(struct safe_softc *, bus_size_t,
                    100:                struct safe_dma_alloc *, int);
                    101: #define        safe_dma_sync(_sc, _dma, _flags) \
                    102:        bus_dmamap_sync((_sc)->sc_dmat, (_dma)->dma_map, 0,             \
                    103:            (_dma)->dma_map->dm_mapsize, (_flags))
                    104: void safe_dma_free(struct safe_softc *, struct safe_dma_alloc *);
                    105: int safe_dmamap_aligned(const struct safe_operand *);
                    106: int safe_dmamap_uniform(const struct safe_operand *);
                    107:
                    108: void safe_reset_board(struct safe_softc *);
                    109: void safe_init_board(struct safe_softc *);
                    110: void safe_init_pciregs(struct safe_softc *);
                    111: void safe_cleanchip(struct safe_softc *);
                    112: __inline u_int32_t safe_rng_read(struct safe_softc *);
                    113:
                    114: int safe_free_entry(struct safe_softc *, struct safe_ringentry *);
                    115:
                    116: #ifdef SAFE_DEBUG
                    117: int safe_debug;
                    118: #define        DPRINTF(_x)     if (safe_debug) printf _x
                    119:
                    120: void safe_dump_dmastatus(struct safe_softc *, const char *);
                    121: void safe_dump_intrstate(struct safe_softc *, const char *);
                    122: void safe_dump_ringstate(struct safe_softc *, const char *);
                    123: void safe_dump_request(struct safe_softc *, const char *,
                    124:     struct safe_ringentry *);
                    125: void safe_dump_ring(struct safe_softc *sc, const char *tag);
                    126: #else
                    127: #define        DPRINTF(_x)
                    128: #endif
                    129:
                    130: #define        READ_REG(sc,r) \
                    131:        bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r))
                    132:
                    133: #define WRITE_REG(sc,reg,val) \
                    134:        bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val)
                    135:
                    136: struct safe_stats safestats;
                    137:
                    138: int safe_rnginterval = 1;              /* poll once a second */
                    139: int safe_rngbufsize = 16;              /* 64 bytes each poll  */
                    140: int safe_rngmaxalarm = 8;              /* max alarms before reset */
                    141:
                    142: int
                    143: safe_probe(struct device *parent, void *match, void *aux)
                    144: {
                    145:        struct pci_attach_args *pa = aux;
                    146:
                    147:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SAFENET &&
                    148:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SAFENET_SAFEXCEL)
                    149:                return (1);
                    150:        return (0);
                    151: }
                    152:
                    153: void
                    154: safe_attach(struct device *parent, struct device *self, void *aux)
                    155: {
                    156:        struct safe_softc *sc = (struct safe_softc *)self;
                    157:        struct pci_attach_args *pa = aux;
                    158:        pci_intr_handle_t ih;
                    159:        const char *intrstr = NULL;
                    160:        bus_size_t iosize;
                    161:        bus_addr_t raddr;
                    162:        u_int32_t devinfo;
                    163:        int algs[CRYPTO_ALGORITHM_MAX + 1], i;
                    164:
                    165:        /* XXX handle power management */
                    166:
                    167:        SIMPLEQ_INIT(&sc->sc_pkq);
                    168:        sc->sc_dmat = pa->pa_dmat;
                    169:
                    170:        /*
                    171:         * Setup memory-mapping of PCI registers.
                    172:         */
                    173:        if (pci_mapreg_map(pa, SAFE_BAR, PCI_MAPREG_TYPE_MEM, 0,
                    174:            &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) {
                    175:                printf(": can't map register space\n");
                    176:                goto bad;
                    177:        }
                    178:
                    179:        if (pci_intr_map(pa, &ih)) {
                    180:                printf(": couldn't map interrupt\n");
                    181:                goto bad1;
                    182:        }
                    183:        intrstr = pci_intr_string(pa->pa_pc, ih);
                    184:        sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, safe_intr, sc,
                    185:            self->dv_xname);
                    186:        if (sc->sc_ih == NULL) {
                    187:                printf(": couldn't establish interrupt");
                    188:                if (intrstr != NULL)
                    189:                        printf(" at %s", intrstr);
                    190:                printf("\n");
                    191:                goto bad2;
                    192:        }
                    193:
                    194:        sc->sc_cid = crypto_get_driverid(0);
                    195:        if (sc->sc_cid < 0) {
                    196:                printf(": could not get crypto driver id\n");
                    197:                goto bad3;
                    198:        }
                    199:
                    200:        sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
                    201:                (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
                    202:
                    203:        /*
                    204:         * Allocate packet engine descriptors.
                    205:         */
                    206:        if (safe_dma_malloc(sc,
                    207:            SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
                    208:            &sc->sc_ringalloc, 0)) {
                    209:                printf(": cannot allocate PE descriptor ring\n");
                    210:                goto bad4;
                    211:        }
                    212:        /*
                    213:         * Hookup the static portion of all our data structures.
                    214:         */
                    215:        sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
                    216:        sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
                    217:        sc->sc_front = sc->sc_ring;
                    218:        sc->sc_back = sc->sc_ring;
                    219:        raddr = sc->sc_ringalloc.dma_paddr;
                    220:        bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
                    221:        for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
                    222:                struct safe_ringentry *re = &sc->sc_ring[i];
                    223:
                    224:                re->re_desc.d_sa = raddr +
                    225:                        offsetof(struct safe_ringentry, re_sa);
                    226:                re->re_sa.sa_staterec = raddr +
                    227:                        offsetof(struct safe_ringentry, re_sastate);
                    228:
                    229:                raddr += sizeof (struct safe_ringentry);
                    230:        }
                    231:
                    232:        /*
                    233:         * Allocate scatter and gather particle descriptors.
                    234:         */
                    235:        if (safe_dma_malloc(sc, SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
                    236:            &sc->sc_spalloc, 0)) {
                    237:                printf(": cannot allocate source particle descriptor ring\n");
                    238:                safe_dma_free(sc, &sc->sc_ringalloc);
                    239:                goto bad4;
                    240:        }
                    241:        sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
                    242:        sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
                    243:        sc->sc_spfree = sc->sc_spring;
                    244:        bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
                    245:
                    246:        if (safe_dma_malloc(sc, SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
                    247:            &sc->sc_dpalloc, 0)) {
                    248:                printf(": cannot allocate destination particle "
                    249:                        "descriptor ring\n");
                    250:                safe_dma_free(sc, &sc->sc_spalloc);
                    251:                safe_dma_free(sc, &sc->sc_ringalloc);
                    252:                goto bad4;
                    253:        }
                    254:        sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
                    255:        sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
                    256:        sc->sc_dpfree = sc->sc_dpring;
                    257:        bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
                    258:
                    259:        printf(":");
                    260:
                    261:        devinfo = READ_REG(sc, SAFE_DEVINFO);
                    262:        if (devinfo & SAFE_DEVINFO_RNG)
                    263:                printf(" RNG");
                    264:
                    265:        bzero(algs, sizeof(algs));
                    266:        if (devinfo & SAFE_DEVINFO_PKEY) {
                    267:                printf(" PK");
                    268:                algs[CRK_MOD_EXP] = CRYPTO_ALG_FLAG_SUPPORTED;
                    269:                crypto_kregister(sc->sc_cid, algs, safe_kprocess);
                    270:                timeout_set(&sc->sc_pkto, safe_kpoll, sc);
                    271:        }
                    272:
                    273:        bzero(algs, sizeof(algs));
                    274:        if (devinfo & SAFE_DEVINFO_DES) {
                    275:                printf(" 3DES");
                    276:                algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    277:                algs[CRYPTO_DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    278:        }
                    279:        if (devinfo & SAFE_DEVINFO_AES) {
                    280:                printf(" AES");
                    281:                algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    282:        }
                    283:        if (devinfo & SAFE_DEVINFO_MD5) {
                    284:                printf(" MD5");
                    285:                algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    286:        }
                    287:        if (devinfo & SAFE_DEVINFO_SHA1) {
                    288:                printf(" SHA1");
                    289:                algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    290:        }
                    291:        crypto_register(sc->sc_cid, algs, safe_newsession,
                    292:            safe_freesession, safe_process);
                    293:        /* XXX other supported algorithms? */
                    294:
                    295:        printf(", %s\n", intrstr);
                    296:
                    297:        safe_reset_board(sc);           /* reset h/w */
                    298:        safe_init_pciregs(sc);          /* init pci settings */
                    299:        safe_init_board(sc);            /* init h/w */
                    300:
                    301:        if (devinfo & SAFE_DEVINFO_RNG) {
                    302:                safe_rng_init(sc);
                    303:
                    304:                timeout_set(&sc->sc_rngto, safe_rng, sc);
                    305:                timeout_add(&sc->sc_rngto, hz * safe_rnginterval);
                    306:        }
                    307:        return;
                    308:
                    309: bad4:
                    310:        /* XXX crypto_unregister_all(sc->sc_cid); */
                    311: bad3:
                    312:        pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
                    313: bad2:
                    314:        /* pci_intr_unmap? */;
                    315: bad1:
                    316:        bus_space_unmap(sc->sc_st, sc->sc_sh, iosize);
                    317: bad:
                    318:        return;
                    319: }
                    320:
                    321: int
                    322: safe_process(struct cryptop *crp)
                    323: {
                    324:        int err = 0, i, nicealign, uniform, s;
                    325:        struct safe_softc *sc;
                    326:        struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
                    327:        int bypass, oplen, ivsize, card;
                    328:        int16_t coffset;
                    329:        struct safe_session *ses;
                    330:        struct safe_ringentry *re;
                    331:        struct safe_sarec *sa;
                    332:        struct safe_pdesc *pd;
                    333:        u_int32_t cmd0, cmd1, staterec, iv[4];
                    334:
                    335:        s = splnet();
                    336:        if (crp == NULL || crp->crp_callback == NULL) {
                    337:                safestats.st_invalid++;
                    338:                splx(s);
                    339:                return (EINVAL);
                    340:        }
                    341:        card = SAFE_CARD(crp->crp_sid);
                    342:        if (card >= safe_cd.cd_ndevs || safe_cd.cd_devs[card] == NULL) {
                    343:                safestats.st_invalid++;
                    344:                splx(s);
                    345:                return (EINVAL);
                    346:        }
                    347:        sc = safe_cd.cd_devs[card];
                    348:
                    349:        if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
                    350:                safestats.st_badsession++;
                    351:                splx(s);
                    352:                return (EINVAL);
                    353:        }
                    354:
                    355:        if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
                    356:                safestats.st_ringfull++;
                    357:                splx(s);
                    358:                return (ERESTART);
                    359:        }
                    360:        re = sc->sc_front;
                    361:
                    362:        staterec = re->re_sa.sa_staterec;       /* save */
                    363:        /* NB: zero everything but the PE descriptor */
                    364:        bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
                    365:        re->re_sa.sa_staterec = staterec;       /* restore */
                    366:
                    367:        re->re_crp = crp;
                    368:        re->re_sesn = SAFE_SESSION(crp->crp_sid);
                    369:
                    370:        if (crp->crp_flags & CRYPTO_F_IMBUF) {
                    371:                re->re_src_m = (struct mbuf *)crp->crp_buf;
                    372:                re->re_dst_m = (struct mbuf *)crp->crp_buf;
                    373:        } else if (crp->crp_flags & CRYPTO_F_IOV) {
                    374:                re->re_src_io = (struct uio *)crp->crp_buf;
                    375:                re->re_dst_io = (struct uio *)crp->crp_buf;
                    376:        } else {
                    377:                safestats.st_badflags++;
                    378:                err = EINVAL;
                    379:                goto errout;    /* XXX we don't handle contiguous blocks! */
                    380:        }
                    381:
                    382:        sa = &re->re_sa;
                    383:        ses = &sc->sc_sessions[re->re_sesn];
                    384:
                    385:        crd1 = crp->crp_desc;
                    386:        if (crd1 == NULL) {
                    387:                safestats.st_nodesc++;
                    388:                err = EINVAL;
                    389:                goto errout;
                    390:        }
                    391:        crd2 = crd1->crd_next;
                    392:
                    393:        cmd0 = SAFE_SA_CMD0_BASIC;              /* basic group operation */
                    394:        cmd1 = 0;
                    395:        if (crd2 == NULL) {
                    396:                if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
                    397:                    crd1->crd_alg == CRYPTO_SHA1_HMAC) {
                    398:                        maccrd = crd1;
                    399:                        enccrd = NULL;
                    400:                        cmd0 |= SAFE_SA_CMD0_OP_HASH;
                    401:                } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
                    402:                    crd1->crd_alg == CRYPTO_3DES_CBC ||
                    403:                    crd1->crd_alg == CRYPTO_AES_CBC) {
                    404:                        maccrd = NULL;
                    405:                        enccrd = crd1;
                    406:                        cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
                    407:                } else {
                    408:                        safestats.st_badalg++;
                    409:                        err = EINVAL;
                    410:                        goto errout;
                    411:                }
                    412:        } else {
                    413:                if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
                    414:                    crd1->crd_alg == CRYPTO_SHA1_HMAC) &&
                    415:                   (crd2->crd_alg == CRYPTO_DES_CBC ||
                    416:                    crd2->crd_alg == CRYPTO_3DES_CBC ||
                    417:                    crd2->crd_alg == CRYPTO_AES_CBC) &&
                    418:                    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
                    419:                        maccrd = crd1;
                    420:                        enccrd = crd2;
                    421:                } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
                    422:                    crd1->crd_alg == CRYPTO_3DES_CBC ||
                    423:                    crd1->crd_alg == CRYPTO_AES_CBC) &&
                    424:                    (crd2->crd_alg == CRYPTO_MD5_HMAC ||
                    425:                     crd2->crd_alg == CRYPTO_SHA1_HMAC) &&
                    426:                    (crd1->crd_flags & CRD_F_ENCRYPT)) {
                    427:                        enccrd = crd1;
                    428:                        maccrd = crd2;
                    429:                } else {
                    430:                        safestats.st_badalg++;
                    431:                        err = EINVAL;
                    432:                        goto errout;
                    433:                }
                    434:                cmd0 |= SAFE_SA_CMD0_OP_BOTH;
                    435:        }
                    436:
                    437:        if (enccrd) {
                    438:                if (enccrd->crd_alg == CRYPTO_DES_CBC) {
                    439:                        cmd0 |= SAFE_SA_CMD0_DES;
                    440:                        cmd1 |= SAFE_SA_CMD1_CBC;
                    441:                        ivsize = 2*sizeof(u_int32_t);
                    442:                } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
                    443:                        cmd0 |= SAFE_SA_CMD0_3DES;
                    444:                        cmd1 |= SAFE_SA_CMD1_CBC;
                    445:                        ivsize = 2*sizeof(u_int32_t);
                    446:                } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
                    447:                        cmd0 |= SAFE_SA_CMD0_AES;
                    448:                        cmd1 |= SAFE_SA_CMD1_CBC;
                    449:                        if (ses->ses_klen == 128)
                    450:                             cmd1 |=  SAFE_SA_CMD1_AES128;
                    451:                        else if (ses->ses_klen == 192)
                    452:                             cmd1 |=  SAFE_SA_CMD1_AES192;
                    453:                        else
                    454:                             cmd1 |=  SAFE_SA_CMD1_AES256;
                    455:                        ivsize = 4*sizeof(u_int32_t);
                    456:                } else {
                    457:                        cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
                    458:                        ivsize = 0;
                    459:                }
                    460:
                    461:                /*
                    462:                 * Setup encrypt/decrypt state.  When using basic ops
                    463:                 * we can't use an inline IV because hash/crypt offset
                    464:                 * must be from the end of the IV to the start of the
                    465:                 * crypt data and this leaves out the preceding header
                    466:                 * from the hash calculation.  Instead we place the IV
                    467:                 * in the state record and set the hash/crypt offset to
                    468:                 * copy both the header+IV.
                    469:                 */
                    470:                if (enccrd->crd_flags & CRD_F_ENCRYPT) {
                    471:                        cmd0 |= SAFE_SA_CMD0_OUTBOUND;
                    472:
                    473:                        if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
                    474:                                bcopy(enccrd->crd_iv, iv, ivsize);
                    475:                        else
                    476:                                bcopy(ses->ses_iv, iv, ivsize);
                    477:                        if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
                    478:                                if (crp->crp_flags & CRYPTO_F_IMBUF)
                    479:                                        m_copyback(re->re_src_m,
                    480:                                            enccrd->crd_inject, ivsize, iv);
                    481:                                else if (crp->crp_flags & CRYPTO_F_IOV)
                    482:                                        cuio_copyback(re->re_src_io,
                    483:                                            enccrd->crd_inject, ivsize, iv);
                    484:                        }
                    485:                        for (i = 0; i < ivsize / sizeof(iv[0]); i++)
                    486:                                re->re_sastate.sa_saved_iv[i] = htole32(iv[i]);
                    487:                        cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
                    488:                        re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
                    489:                } else {
                    490:                        cmd0 |= SAFE_SA_CMD0_INBOUND;
                    491:
                    492:                        if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
                    493:                                bcopy(enccrd->crd_iv, iv, ivsize);
                    494:                        else if (crp->crp_flags & CRYPTO_F_IMBUF)
                    495:                                m_copydata(re->re_src_m, enccrd->crd_inject,
                    496:                                    ivsize, (caddr_t)iv);
                    497:                        else if (crp->crp_flags & CRYPTO_F_IOV)
                    498:                                cuio_copydata(re->re_src_io, enccrd->crd_inject,
                    499:                                    ivsize, (caddr_t)iv);
                    500:                        for (i = 0; i < ivsize / sizeof(iv[0]); i++)
                    501:                                re->re_sastate.sa_saved_iv[i] = htole32(iv[i]);
                    502:                        cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
                    503:                }
                    504:                /*
                    505:                 * For basic encryption use the zero pad algorithm.
                    506:                 * This pads results to an 8-byte boundary and
                    507:                 * suppresses padding verification for inbound (i.e.
                    508:                 * decrypt) operations.
                    509:                 *
                    510:                 * NB: Not sure if the 8-byte pad boundary is a problem.
                    511:                 */
                    512:                cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
                    513:
                    514:                /* XXX assert key bufs have the same size */
                    515:                for (i = 0; i < sizeof(sa->sa_key)/sizeof(sa->sa_key[0]); i++)
                    516:                        sa->sa_key[i] = ses->ses_key[i];
                    517:        }
                    518:
                    519:        if (maccrd) {
                    520:                if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
                    521:                        cmd0 |= SAFE_SA_CMD0_MD5;
                    522:                        cmd1 |= SAFE_SA_CMD1_HMAC;      /* NB: enable HMAC */
                    523:                } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
                    524:                        cmd0 |= SAFE_SA_CMD0_SHA1;
                    525:                        cmd1 |= SAFE_SA_CMD1_HMAC;      /* NB: enable HMAC */
                    526:                } else {
                    527:                        cmd0 |= SAFE_SA_CMD0_HASH_NULL;
                    528:                }
                    529:                /*
                    530:                 * Digest data is loaded from the SA and the hash
                    531:                 * result is saved to the state block where we
                    532:                 * retrieve it for return to the caller.
                    533:                 */
                    534:                /* XXX assert digest bufs have the same size */
                    535:                for (i = 0;
                    536:                     i < sizeof(sa->sa_outdigest)/sizeof(sa->sa_outdigest[i]);
                    537:                     i++) {
                    538:                        sa->sa_indigest[i] = ses->ses_hminner[i];
                    539:                        sa->sa_outdigest[i] = ses->ses_hmouter[i];
                    540:                }
                    541:
                    542:                cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
                    543:                re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
                    544:        }
                    545:
                    546:        if (enccrd && maccrd) {
                    547:                /*
                    548:                 * The offset from hash data to the start of
                    549:                 * crypt data is the difference in the skips.
                    550:                 */
                    551:                bypass = maccrd->crd_skip;
                    552:                coffset = enccrd->crd_skip - maccrd->crd_skip;
                    553:                if (coffset < 0) {
                    554:                        DPRINTF(("%s: hash does not precede crypt; "
                    555:                                "mac skip %u enc skip %u\n",
                    556:                                __func__, maccrd->crd_skip, enccrd->crd_skip));
                    557:                        safestats.st_skipmismatch++;
                    558:                        err = EINVAL;
                    559:                        goto errout;
                    560:                }
                    561:                oplen = enccrd->crd_skip + enccrd->crd_len;
                    562:                if (maccrd->crd_skip + maccrd->crd_len != oplen) {
                    563:                        DPRINTF(("%s: hash amount %u != crypt amount %u\n",
                    564:                                __func__, maccrd->crd_skip + maccrd->crd_len,
                    565:                                oplen));
                    566:                        safestats.st_lenmismatch++;
                    567:                        err = EINVAL;
                    568:                        goto errout;
                    569:                }
                    570: #ifdef SAFE_DEBUG
                    571:                if (safe_debug) {
                    572:                        printf("mac: skip %d, len %d, inject %d\n",
                    573:                            maccrd->crd_skip, maccrd->crd_len,
                    574:                            maccrd->crd_inject);
                    575:                        printf("enc: skip %d, len %d, inject %d\n",
                    576:                            enccrd->crd_skip, enccrd->crd_len,
                    577:                            enccrd->crd_inject);
                    578:                        printf("bypass %d coffset %d oplen %d\n",
                    579:                                bypass, coffset, oplen);
                    580:                }
                    581: #endif
                    582:                if (coffset & 3) {      /* offset must be 32-bit aligned */
                    583:                        DPRINTF(("%s: coffset %u misaligned\n",
                    584:                                __func__, coffset));
                    585:                        safestats.st_coffmisaligned++;
                    586:                        err = EINVAL;
                    587:                        goto errout;
                    588:                }
                    589:                coffset >>= 2;
                    590:                if (coffset > 255) {    /* offset must be <256 dwords */
                    591:                        DPRINTF(("%s: coffset %u too big\n",
                    592:                                __func__, coffset));
                    593:                        safestats.st_cofftoobig++;
                    594:                        err = EINVAL;
                    595:                        goto errout;
                    596:                }
                    597:                /*
                    598:                 * Tell the hardware to copy the header to the output.
                    599:                 * The header is defined as the data from the end of
                    600:                 * the bypass to the start of data to be encrypted.
                    601:                 * Typically this is the inline IV.  Note that you need
                    602:                 * to do this even if src+dst are the same; it appears
                    603:                 * that w/o this bit the crypted data is written
                    604:                 * immediately after the bypass data.
                    605:                 */
                    606:                cmd1 |= SAFE_SA_CMD1_HDRCOPY;
                    607:                /*
                    608:                 * Disable IP header mutable bit handling.  This is
                    609:                 * needed to get correct HMAC calculations.
                    610:                 */
                    611:                cmd1 |= SAFE_SA_CMD1_MUTABLE;
                    612:        } else {
                    613:                if (enccrd) {
                    614:                        bypass = enccrd->crd_skip;
                    615:                        oplen = bypass + enccrd->crd_len;
                    616:                } else {
                    617:                        bypass = maccrd->crd_skip;
                    618:                        oplen = bypass + maccrd->crd_len;
                    619:                }
                    620:                coffset = 0;
                    621:        }
                    622:        /* XXX verify multiple of 4 when using s/g */
                    623:        if (bypass > 96) {              /* bypass offset must be <= 96 bytes */
                    624:                DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
                    625:                safestats.st_bypasstoobig++;
                    626:                err = EINVAL;
                    627:                goto errout;
                    628:        }
                    629:
                    630:        if (bus_dmamap_create(sc->sc_dmat, SAFE_MAX_DMA, SAFE_MAX_PART,
                    631:            SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT,
                    632:            &re->re_src_map)) {
                    633:                safestats.st_nomap++;
                    634:                err = ENOMEM;
                    635:                goto errout;
                    636:        }
                    637:        if (crp->crp_flags & CRYPTO_F_IMBUF) {
                    638:                if (bus_dmamap_load_mbuf(sc->sc_dmat, re->re_src_map,
                    639:                    re->re_src_m, BUS_DMA_NOWAIT)) {
                    640:                        bus_dmamap_destroy(sc->sc_dmat, re->re_src_map);
                    641:                        re->re_src_map = NULL;
                    642:                        safestats.st_noload++;
                    643:                        err = ENOMEM;
                    644:                        goto errout;
                    645:                }
                    646:        } else if (crp->crp_flags & CRYPTO_F_IOV) {
                    647:                if (bus_dmamap_load_uio(sc->sc_dmat, re->re_src_map,
                    648:                    re->re_src_io, BUS_DMA_NOWAIT) != 0) {
                    649:                        bus_dmamap_destroy(sc->sc_dmat, re->re_src_map);
                    650:                        re->re_src_map = NULL;
                    651:                        safestats.st_noload++;
                    652:                        err = ENOMEM;
                    653:                        goto errout;
                    654:                }
                    655:        }
                    656:        nicealign = safe_dmamap_aligned(&re->re_src);
                    657:        uniform = safe_dmamap_uniform(&re->re_src);
                    658:
                    659:        DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
                    660:                nicealign, uniform, re->re_src_nsegs));
                    661:        if (re->re_src_nsegs > 1) {
                    662:                re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
                    663:                        ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
                    664:                for (i = 0; i < re->re_src_nsegs; i++) {
                    665:                        /* NB: no need to check if there's space */
                    666:                        pd = sc->sc_spfree;
                    667:                        if (++(sc->sc_spfree) == sc->sc_springtop)
                    668:                                sc->sc_spfree = sc->sc_spring;
                    669:
                    670:                        KASSERT_X((pd->pd_flags&3) == 0 ||
                    671:                                (pd->pd_flags&3) == SAFE_PD_DONE,
                    672:                                ("bogus source particle descriptor; flags %x",
                    673:                                pd->pd_flags));
                    674:                        pd->pd_addr = re->re_src_segs[i].ds_addr;
                    675:                        pd->pd_ctrl = SAFE_PD_READY |
                    676:                            ((re->re_src_segs[i].ds_len << SAFE_PD_LEN_S)
                    677:                            & SAFE_PD_LEN_M);
                    678:                }
                    679:                cmd0 |= SAFE_SA_CMD0_IGATHER;
                    680:        } else {
                    681:                /*
                    682:                 * No need for gather, reference the operand directly.
                    683:                 */
                    684:                re->re_desc.d_src = re->re_src_segs[0].ds_addr;
                    685:        }
                    686:
                    687:        if (enccrd == NULL && maccrd != NULL) {
                    688:                /*
                    689:                 * Hash op; no destination needed.
                    690:                 */
                    691:        } else {
                    692:                if (crp->crp_flags & CRYPTO_F_IOV) {
                    693:                        if (!nicealign) {
                    694:                                safestats.st_iovmisaligned++;
                    695:                                err = EINVAL;
                    696:                                goto errout;
                    697:                        }
                    698:                        if (uniform != 1) {
                    699:                                /*
                    700:                                 * Source is not suitable for direct use as
                    701:                                 * the destination.  Create a new scatter/gather
                    702:                                 * list based on the destination requirements
                    703:                                 * and check if that's ok.
                    704:                                 */
                    705:                                if (bus_dmamap_create(sc->sc_dmat,
                    706:                                    SAFE_MAX_DMA, SAFE_MAX_PART,
                    707:                                    SAFE_MAX_DSIZE, SAFE_MAX_DSIZE,
                    708:                                    BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT,
                    709:                                    &re->re_dst_map)) {
                    710:                                        safestats.st_nomap++;
                    711:                                        err = ENOMEM;
                    712:                                        goto errout;
                    713:                                }
                    714:                                if (bus_dmamap_load_uio(sc->sc_dmat,
                    715:                                    re->re_dst_map, re->re_dst_io,
                    716:                                    BUS_DMA_NOWAIT) != 0) {
                    717:                                        bus_dmamap_destroy(sc->sc_dmat,
                    718:                                                re->re_dst_map);
                    719:                                        re->re_dst_map = NULL;
                    720:                                        safestats.st_noload++;
                    721:                                        err = ENOMEM;
                    722:                                        goto errout;
                    723:                                }
                    724:                                uniform = safe_dmamap_uniform(&re->re_dst);
                    725:                                if (!uniform) {
                    726:                                        /*
                    727:                                         * There's no way to handle the DMA
                    728:                                         * requirements with this uio.  We
                    729:                                         * could create a separate DMA area for
                    730:                                         * the result and then copy it back,
                    731:                                         * but for now we just bail and return
                    732:                                         * an error.  Note that uio requests
                    733:                                         * > SAFE_MAX_DSIZE are handled because
                    734:                                         * the DMA map and segment list for the
                    735:                                         * destination will result in a
                    736:                                         * destination particle list that does
                    737:                                         * the necessary scatter DMA.
                    738:                                         */
                    739:                                        safestats.st_iovnotuniform++;
                    740:                                        err = EINVAL;
                    741:                                        goto errout;
                    742:                                }
                    743:                        } else
                    744:                                re->re_dst = re->re_src;
                    745:                } else if (crp->crp_flags & CRYPTO_F_IMBUF) {
                    746:                        if (nicealign && uniform == 1) {
                    747:                                /*
                    748:                                 * Source layout is suitable for direct
                    749:                                 * sharing of the DMA map and segment list.
                    750:                                 */
                    751:                                re->re_dst = re->re_src;
                    752:                        } else if (nicealign && uniform == 2) {
                    753:                                /*
                    754:                                 * The source is properly aligned but requires a
                    755:                                 * different particle list to handle DMA of the
                    756:                                 * result.  Create a new map and do the load to
                    757:                                 * create the segment list.  The particle
                    758:                                 * descriptor setup code below will handle the
                    759:                                 * rest.
                    760:                                 */
                    761:                                if (bus_dmamap_create(sc->sc_dmat,
                    762:                                    SAFE_MAX_DMA, SAFE_MAX_PART,
                    763:                                    SAFE_MAX_DSIZE, SAFE_MAX_DSIZE,
                    764:                                    BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT,
                    765:                                    &re->re_dst_map)) {
                    766:                                        safestats.st_nomap++;
                    767:                                        err = ENOMEM;
                    768:                                        goto errout;
                    769:                                }
                    770:                                if (bus_dmamap_load_mbuf(sc->sc_dmat,
                    771:                                    re->re_dst_map, re->re_dst_m,
                    772:                                    BUS_DMA_NOWAIT) != 0) {
                    773:                                        bus_dmamap_destroy(sc->sc_dmat,
                    774:                                                re->re_dst_map);
                    775:                                        re->re_dst_map = NULL;
                    776:                                        safestats.st_noload++;
                    777:                                        err = ENOMEM;
                    778:                                        goto errout;
                    779:                                }
                    780:                        } else {                /* !(aligned and/or uniform) */
                    781:                                int totlen, len;
                    782:                                struct mbuf *m, *top, **mp;
                    783:
                    784:                                /*
                    785:                                 * DMA constraints require that we allocate a
                    786:                                 * new mbuf chain for the destination.  We
                    787:                                 * allocate an entire new set of mbufs of
                    788:                                 * optimal/required size and then tell the
                    789:                                 * hardware to copy any bits that are not
                    790:                                 * created as a byproduct of the operation.
                    791:                                 */
                    792:                                if (!nicealign)
                    793:                                        safestats.st_unaligned++;
                    794:                                if (!uniform)
                    795:                                        safestats.st_notuniform++;
                    796:                                totlen = re->re_src_mapsize;
                    797:                                if (re->re_src_m->m_flags & M_PKTHDR) {
                    798:                                        len = MHLEN;
                    799:                                        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    800:                                } else {
                    801:                                        len = MLEN;
                    802:                                        MGET(m, M_DONTWAIT, MT_DATA);
                    803:                                }
                    804:                                if (m == NULL) {
                    805:                                        safestats.st_nombuf++;
                    806:                                        err = sc->sc_nqchip ? ERESTART : ENOMEM;
                    807:                                        goto errout;
                    808:                                }
                    809:                                if (len == MHLEN)
                    810:                                        M_DUP_PKTHDR(m, re->re_src_m);
                    811:                                if (totlen >= MINCLSIZE) {
                    812:                                        MCLGET(m, M_DONTWAIT);
                    813:                                        if ((m->m_flags & M_EXT) == 0) {
                    814:                                                m_free(m);
                    815:                                                safestats.st_nomcl++;
                    816:                                                err = sc->sc_nqchip ?
                    817:                                                        ERESTART : ENOMEM;
                    818:                                                goto errout;
                    819:                                        }
                    820:                                        len = MCLBYTES;
                    821:                                }
                    822:                                m->m_len = len;
                    823:                                top = NULL;
                    824:                                mp = &top;
                    825:
                    826:                                while (totlen > 0) {
                    827:                                        if (top) {
                    828:                                                MGET(m, M_DONTWAIT, MT_DATA);
                    829:                                                if (m == NULL) {
                    830:                                                        m_freem(top);
                    831:                                                        safestats.st_nombuf++;
                    832:                                                        err = sc->sc_nqchip ?
                    833:                                                            ERESTART : ENOMEM;
                    834:                                                        goto errout;
                    835:                                                }
                    836:                                                len = MLEN;
                    837:                                        }
                    838:                                        if (top && totlen >= MINCLSIZE) {
                    839:                                                MCLGET(m, M_DONTWAIT);
                    840:                                                if ((m->m_flags & M_EXT) == 0) {
                    841:                                                        *mp = m;
                    842:                                                        m_freem(top);
                    843:                                                        safestats.st_nomcl++;
                    844:                                                        err = sc->sc_nqchip ?
                    845:                                                            ERESTART : ENOMEM;
                    846:                                                        goto errout;
                    847:                                                }
                    848:                                                len = MCLBYTES;
                    849:                                        }
                    850:                                        m->m_len = len = min(totlen, len);
                    851:                                        totlen -= len;
                    852:                                        *mp = m;
                    853:                                        mp = &m->m_next;
                    854:                                }
                    855:                                re->re_dst_m = top;
                    856:                                if (bus_dmamap_create(sc->sc_dmat,
                    857:                                    SAFE_MAX_DMA, SAFE_MAX_PART,
                    858:                                    SAFE_MAX_DSIZE, SAFE_MAX_DSIZE,
                    859:                                    BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT,
                    860:                                    &re->re_dst_map) != 0) {
                    861:                                        safestats.st_nomap++;
                    862:                                        err = ENOMEM;
                    863:                                        goto errout;
                    864:                                }
                    865:                                if (bus_dmamap_load_mbuf(sc->sc_dmat,
                    866:                                    re->re_dst_map, re->re_dst_m,
                    867:                                    BUS_DMA_NOWAIT) != 0) {
                    868:                                        bus_dmamap_destroy(sc->sc_dmat,
                    869:                                        re->re_dst_map);
                    870:                                        re->re_dst_map = NULL;
                    871:                                        safestats.st_noload++;
                    872:                                        err = ENOMEM;
                    873:                                        goto errout;
                    874:                                }
                    875:                                if (re->re_src_mapsize > oplen) {
                    876:                                        /*
                    877:                                         * There's data following what the
                    878:                                         * hardware will copy for us.  If this
                    879:                                         * isn't just the ICV (that's going to
                    880:                                         * be written on completion), copy it
                    881:                                         * to the new mbufs
                    882:                                         */
                    883:                                        if (!(maccrd &&
                    884:                                            (re->re_src_mapsize-oplen) == 12 &&
                    885:                                            maccrd->crd_inject == oplen))
                    886:                                                safe_mcopy(re->re_src_m,
                    887:                                                           re->re_dst_m,
                    888:                                                           oplen);
                    889:                                        else
                    890:                                                safestats.st_noicvcopy++;
                    891:                                }
                    892:                        }
                    893:                } else {
                    894:                        safestats.st_badflags++;
                    895:                        err = EINVAL;
                    896:                        goto errout;
                    897:                }
                    898:
                    899:                if (re->re_dst_nsegs > 1) {
                    900:                        re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
                    901:                            ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
                    902:                        for (i = 0; i < re->re_dst_nsegs; i++) {
                    903:                                pd = sc->sc_dpfree;
                    904:                                KASSERT_X((pd->pd_flags&3) == 0 ||
                    905:                                        (pd->pd_flags&3) == SAFE_PD_DONE,
                    906:                                        ("bogus dest particle descriptor; flags %x",
                    907:                                                pd->pd_flags));
                    908:                                if (++(sc->sc_dpfree) == sc->sc_dpringtop)
                    909:                                        sc->sc_dpfree = sc->sc_dpring;
                    910:                                pd->pd_addr = re->re_dst_segs[i].ds_addr;
                    911:                                pd->pd_ctrl = SAFE_PD_READY;
                    912:                        }
                    913:                        cmd0 |= SAFE_SA_CMD0_OSCATTER;
                    914:                } else {
                    915:                        /*
                    916:                         * No need for scatter, reference the operand directly.
                    917:                         */
                    918:                        re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
                    919:                }
                    920:        }
                    921:
                    922:        /*
                    923:         * All done with setup; fillin the SA command words
                    924:         * and the packet engine descriptor.  The operation
                    925:         * is now ready for submission to the hardware.
                    926:         */
                    927:        sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
                    928:        sa->sa_cmd1 = cmd1
                    929:            | (coffset << SAFE_SA_CMD1_OFFSET_S)
                    930:            | SAFE_SA_CMD1_SAREV1       /* Rev 1 SA data structure */
                    931:            | SAFE_SA_CMD1_SRPCI;
                    932:
                    933:        /*
                    934:         * NB: the order of writes is important here.  In case the
                    935:         * chip is scanning the ring because of an outstanding request
                    936:         * it might nab this one too.  In that case we need to make
                    937:         * sure the setup is complete before we write the length
                    938:         * field of the descriptor as it signals the descriptor is
                    939:         * ready for processing.
                    940:         */
                    941:        re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
                    942:        if (maccrd)
                    943:                re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
                    944:        re->re_desc.d_len = oplen
                    945:                          | SAFE_PE_LEN_READY
                    946:                          | (bypass << SAFE_PE_LEN_BYPASS_S)
                    947:                          ;
                    948:
                    949:        safestats.st_ipackets++;
                    950:        safestats.st_ibytes += oplen;
                    951:
                    952:        if (++(sc->sc_front) == sc->sc_ringtop)
                    953:                sc->sc_front = sc->sc_ring;
                    954:
                    955:        /* XXX honor batching */
                    956:        safe_feed(sc, re);
                    957:        splx(s);
                    958:        return (0);
                    959:
                    960: errout:
                    961:        if ((re->re_dst_m != NULL) && (re->re_src_m != re->re_dst_m))
                    962:                m_freem(re->re_dst_m);
                    963:
                    964:        if (re->re_dst_map != NULL && re->re_dst_map != re->re_src_map) {
                    965:                bus_dmamap_unload(sc->sc_dmat, re->re_dst_map);
                    966:                bus_dmamap_destroy(sc->sc_dmat, re->re_dst_map);
                    967:        }
                    968:        if (re->re_src_map != NULL) {
                    969:                bus_dmamap_unload(sc->sc_dmat, re->re_src_map);
                    970:                bus_dmamap_destroy(sc->sc_dmat, re->re_src_map);
                    971:        }
                    972:        crp->crp_etype = err;
                    973:        crypto_done(crp);
                    974:        splx(s);
                    975:        return (err);
                    976: }
                    977:
                    978: /*
                    979:  * Resets the board.  Values in the regesters are left as is
                    980:  * from the reset (i.e. initial values are assigned elsewhere).
                    981:  */
                    982: void
                    983: safe_reset_board(struct safe_softc *sc)
                    984: {
                    985:        u_int32_t v;
                    986:
                    987:        /*
                    988:         * Reset the device.  The manual says no delay
                    989:         * is needed between marking and clearing reset.
                    990:         */
                    991:        v = READ_REG(sc, SAFE_PE_DMACFG) &
                    992:            ~(SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
                    993:            SAFE_PE_DMACFG_SGRESET);
                    994:        WRITE_REG(sc, SAFE_PE_DMACFG, v
                    995:            | SAFE_PE_DMACFG_PERESET
                    996:            | SAFE_PE_DMACFG_PDRRESET
                    997:            | SAFE_PE_DMACFG_SGRESET);
                    998:        WRITE_REG(sc, SAFE_PE_DMACFG, v);
                    999: }
                   1000:
                   1001: /*
                   1002:  * Initialize registers we need to touch only once.
                   1003:  */
                   1004: void
                   1005: safe_init_board(struct safe_softc *sc)
                   1006: {
                   1007:        u_int32_t v, dwords;
                   1008:
                   1009:        v = READ_REG(sc, SAFE_PE_DMACFG);
                   1010:        v &= ~(SAFE_PE_DMACFG_PEMODE | SAFE_PE_DMACFG_ESPACKET);
                   1011:        v |= SAFE_PE_DMACFG_FSENA               /* failsafe enable */
                   1012:          |  SAFE_PE_DMACFG_GPRPCI              /* gather ring on PCI */
                   1013:          |  SAFE_PE_DMACFG_SPRPCI              /* scatter ring on PCI */
                   1014:          |  SAFE_PE_DMACFG_ESDESC              /* endian-swap descriptors */
                   1015:          |  SAFE_PE_DMACFG_ESPDESC             /* endian-swap part. desc's */
                   1016:          |  SAFE_PE_DMACFG_ESSA                /* endian-swap SA data */
                   1017:          ;
                   1018:        WRITE_REG(sc, SAFE_PE_DMACFG, v);
                   1019:
                   1020:        WRITE_REG(sc, SAFE_CRYPTO_CTRL, SAFE_CRYPTO_CTRL_PKEY |
                   1021:            SAFE_CRYPTO_CTRL_3DES | SAFE_CRYPTO_CTRL_RNG);
                   1022:
                   1023: #if BYTE_ORDER == LITTLE_ENDIAN
                   1024:        WRITE_REG(sc, SAFE_ENDIAN, SAFE_ENDIAN_TGT_PASS|SAFE_ENDIAN_DMA_PASS);
                   1025: #elif BYTE_ORDER == BIG_ENDIAN
                   1026:        WRITE_REG(sc, SAFE_ENDIAN, SAFE_ENDIAN_TGT_PASS|SAFE_ENDIAN_DMA_SWAB);
                   1027: #endif
                   1028:
                   1029:        if (sc->sc_chiprev == SAFE_REV(1,0)) {
                   1030:                /*
                   1031:                 * Avoid large PCI DMA transfers.  Rev 1.0 has a bug where
                   1032:                 * "target mode transfers" done while the chip is DMA'ing
                   1033:                 * >1020 bytes cause the hardware to lockup.  To avoid this
                   1034:                 * we reduce the max PCI transfer size and use small source
                   1035:                 * particle descriptors (<= 256 bytes).
                   1036:                 */
                   1037:                WRITE_REG(sc, SAFE_DMA_CFG, 256);
                   1038:                printf("%s: Reduce max DMA size to %u words for rev %u.%u WAR\n",
                   1039:                    sc->sc_dev.dv_xname,
                   1040:                    (READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff,
                   1041:                    SAFE_REV_MAJ(sc->sc_chiprev),
                   1042:                    SAFE_REV_MIN(sc->sc_chiprev));
                   1043:        }
                   1044:
                   1045:        /* NB: operands+results are overlaid */
                   1046:        WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
                   1047:        WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
                   1048:        /*
                   1049:         * Configure ring entry size and number of items in the ring.
                   1050:         */
                   1051:        KASSERT_X((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
                   1052:            ("PE ring entry not 32-bit aligned!"));
                   1053:        dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
                   1054:        WRITE_REG(sc, SAFE_PE_RINGCFG,
                   1055:            (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
                   1056:        WRITE_REG(sc, SAFE_PE_RINGPOLL, 0);     /* disable polling */
                   1057:
                   1058:        WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
                   1059:        WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
                   1060:        WRITE_REG(sc, SAFE_PE_PARTSIZE,
                   1061:            (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
                   1062:        /*
                   1063:         * NB: destination particles are fixed size.  We use
                   1064:         *     an mbuf cluster and require all results go to
                   1065:         *     clusters or smaller.
                   1066:         */
                   1067:        WRITE_REG(sc, SAFE_PE_PARTCFG, SAFE_MAX_DSIZE);
                   1068:
                   1069:        WRITE_REG(sc, SAFE_HI_CLR, SAFE_INT_PE_CDONE | SAFE_INT_PE_DDONE |
                   1070:            SAFE_INT_PE_ERROR | SAFE_INT_PE_ODONE);
                   1071:
                   1072:        /* it's now safe to enable PE mode, do it */
                   1073:        WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
                   1074:
                   1075:        /*
                   1076:         * Configure hardware to use level-triggered interrupts and
                   1077:         * to interrupt after each descriptor is processed.
                   1078:         */
                   1079:        DELAY(1000);
                   1080:        WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
                   1081:        DELAY(1000);
                   1082:        WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
                   1083:        DELAY(1000);
                   1084:        WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
                   1085:        DELAY(1000);
                   1086: }
                   1087:
                   1088: /*
                   1089:  * Init PCI registers
                   1090:  */
                   1091: void
                   1092: safe_init_pciregs(struct safe_softc *sc)
                   1093: {
                   1094: }
                   1095:
                   1096: int
                   1097: safe_dma_malloc(struct safe_softc *sc, bus_size_t size,
                   1098:     struct safe_dma_alloc *dma,        int mapflags)
                   1099: {
                   1100:        int r;
                   1101:
                   1102:        if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
                   1103:            &dma->dma_seg, 1, &dma->dma_nseg, BUS_DMA_NOWAIT)) != 0)
                   1104:                goto fail_0;
                   1105:
                   1106:        if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg,
                   1107:            size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0)
                   1108:                goto fail_1;
                   1109:
                   1110:        if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
                   1111:            BUS_DMA_NOWAIT, &dma->dma_map)) != 0)
                   1112:                goto fail_2;
                   1113:
                   1114:        if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr,
                   1115:            size, NULL, BUS_DMA_NOWAIT)) != 0)
                   1116:                goto fail_3;
                   1117:
                   1118:        dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr;
                   1119:        dma->dma_size = size;
                   1120:        return (0);
                   1121:
                   1122: fail_3:
                   1123:        bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
                   1124: fail_2:
                   1125:        bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size);
                   1126: fail_1:
                   1127:        bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg);
                   1128: fail_0:
                   1129:        dma->dma_map = NULL;
                   1130:        return (r);
                   1131: }
                   1132:
                   1133: void
                   1134: safe_dma_free(struct safe_softc *sc, struct safe_dma_alloc *dma)
                   1135: {
                   1136:        bus_dmamap_unload(sc->sc_dmat, dma->dma_map);
                   1137:        bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size);
                   1138:        bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg);
                   1139:        bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
                   1140: }
                   1141:
                   1142:
                   1143: #define        SAFE_RNG_MAXWAIT        1000
                   1144:
                   1145: void
                   1146: safe_rng_init(struct safe_softc *sc)
                   1147: {
                   1148:        u_int32_t w, v;
                   1149:        int i;
                   1150:
                   1151:        WRITE_REG(sc, SAFE_RNG_CTRL, 0);
                   1152:        /* use default value according to the manual */
                   1153:        WRITE_REG(sc, SAFE_RNG_CNFG, 0x834);    /* magic from SafeNet */
                   1154:        WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
                   1155:
                   1156:        /*
                   1157:         * There is a bug in rev 1.0 of the 1140 that when the RNG
                   1158:         * is brought out of reset the ready status flag does not
                   1159:         * work until the RNG has finished its internal initialization.
                   1160:         *
                   1161:         * So in order to determine the device is through its
                   1162:         * initialization we must read the data register, using the
                   1163:         * status reg in the read in case it is initialized.  Then read
                   1164:         * the data register until it changes from the first read.
                   1165:         * Once it changes read the data register until it changes
                   1166:         * again.  At this time the RNG is considered initialized.
                   1167:         * This could take between 750ms - 1000ms in time.
                   1168:         */
                   1169:        i = 0;
                   1170:        w = READ_REG(sc, SAFE_RNG_OUT);
                   1171:        do {
                   1172:                v = READ_REG(sc, SAFE_RNG_OUT);
                   1173:                if (v != w) {
                   1174:                        w = v;
                   1175:                        break;
                   1176:                }
                   1177:                DELAY(10);
                   1178:        } while (++i < SAFE_RNG_MAXWAIT);
                   1179:
                   1180:        /* Wait Until data changes again */
                   1181:        i = 0;
                   1182:        do {
                   1183:                v = READ_REG(sc, SAFE_RNG_OUT);
                   1184:                if (v != w)
                   1185:                        break;
                   1186:                DELAY(10);
                   1187:        } while (++i < SAFE_RNG_MAXWAIT);
                   1188: }
                   1189:
                   1190: __inline u_int32_t
                   1191: safe_rng_read(struct safe_softc *sc)
                   1192: {
                   1193:        int i;
                   1194:
                   1195:        i = 0;
                   1196:        while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
                   1197:                ;
                   1198:        return (READ_REG(sc, SAFE_RNG_OUT));
                   1199: }
                   1200:
                   1201: void
                   1202: safe_rng(void *arg)
                   1203: {
                   1204:        struct safe_softc *sc = arg;
                   1205:        u_int32_t buf[SAFE_RNG_MAXBUFSIZ];      /* NB: maybe move to softc */
                   1206:        u_int maxwords;
                   1207:        int i;
                   1208:
                   1209:        safestats.st_rng++;
                   1210:        /*
                   1211:         * Fetch the next block of data.
                   1212:         */
                   1213:        maxwords = safe_rngbufsize;
                   1214:        if (maxwords > SAFE_RNG_MAXBUFSIZ)
                   1215:                maxwords = SAFE_RNG_MAXBUFSIZ;
                   1216: retry:
                   1217:        for (i = 0; i < maxwords; i++)
                   1218:                buf[i] = safe_rng_read(sc);
                   1219:        /*
                   1220:         * Check the comparator alarm count and reset the h/w if
                   1221:         * it exceeds our threshold.  This guards against the
                   1222:         * hardware oscillators resonating with external signals.
                   1223:         */
                   1224:        if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
                   1225:                u_int32_t freq_inc, w;
                   1226:
                   1227:                DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
                   1228:                        READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
                   1229:                safestats.st_rngalarm++;
                   1230:                WRITE_REG(sc, SAFE_RNG_CTRL,
                   1231:                    READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
                   1232:                freq_inc = 18;
                   1233:                for (i = 0; i < 64; i++) {
                   1234:                        w = READ_REG(sc, SAFE_RNG_CNFG);
                   1235:                        freq_inc = ((w + freq_inc) & 0x3fL);
                   1236:                        w = ((w & ~0x3fL) | freq_inc);
                   1237:                        WRITE_REG(sc, SAFE_RNG_CNFG, w);
                   1238:
                   1239:                        WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
                   1240:
                   1241:                        (void) safe_rng_read(sc);
                   1242:                        DELAY(25);
                   1243:
                   1244:                        if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
                   1245:                                WRITE_REG(sc, SAFE_RNG_CTRL,
                   1246:                                    READ_REG(sc, SAFE_RNG_CTRL) &
                   1247:                                    ~SAFE_RNG_CTRL_SHORTEN);
                   1248:                                goto retry;
                   1249:                        }
                   1250:                        freq_inc = 1;
                   1251:                }
                   1252:                WRITE_REG(sc, SAFE_RNG_CTRL,
                   1253:                    READ_REG(sc, SAFE_RNG_CTRL) & ~SAFE_RNG_CTRL_SHORTEN);
                   1254:        } else
                   1255:                WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
                   1256:
                   1257:        for (i = 0; i < maxwords; i++)
                   1258:                add_true_randomness(buf[i]);
                   1259:
                   1260:        timeout_add(&sc->sc_rngto, hz * safe_rnginterval);
                   1261: }
                   1262:
                   1263: /*
                   1264:  * Allocate a new 'session' and return an encoded session id.  'sidp'
                   1265:  * contains our registration id, and should contain an encoded session
                   1266:  * id on successful allocation.
                   1267:  */
                   1268: int
                   1269: safe_newsession(u_int32_t *sidp, struct cryptoini *cri)
                   1270: {
                   1271:        struct cryptoini *c, *encini = NULL, *macini = NULL;
                   1272:        struct safe_softc *sc = NULL;
                   1273:        struct safe_session *ses = NULL;
                   1274:        MD5_CTX md5ctx;
                   1275:        SHA1_CTX sha1ctx;
                   1276:        int i, sesn;
                   1277:
                   1278:        if (sidp == NULL || cri == NULL)
                   1279:                return (EINVAL);
                   1280:        for (i = 0; i < safe_cd.cd_ndevs; i++) {
                   1281:                sc = safe_cd.cd_devs[i];
                   1282:                if (sc == NULL || sc->sc_cid == (*sidp))
                   1283:                        break;
                   1284:        }
                   1285:        if (sc == NULL)
                   1286:                return (EINVAL);
                   1287:
                   1288:        for (c = cri; c != NULL; c = c->cri_next) {
                   1289:                if (c->cri_alg == CRYPTO_MD5_HMAC ||
                   1290:                    c->cri_alg == CRYPTO_SHA1_HMAC) {
                   1291:                        if (macini)
                   1292:                                return (EINVAL);
                   1293:                        macini = c;
                   1294:                } else if (c->cri_alg == CRYPTO_DES_CBC ||
                   1295:                    c->cri_alg == CRYPTO_3DES_CBC ||
                   1296:                    c->cri_alg == CRYPTO_AES_CBC) {
                   1297:                        if (encini)
                   1298:                                return (EINVAL);
                   1299:                        encini = c;
                   1300:                } else
                   1301:                        return (EINVAL);
                   1302:        }
                   1303:        if (encini == NULL && macini == NULL)
                   1304:                return (EINVAL);
                   1305:        if (encini) {                   /* validate key length */
                   1306:                switch (encini->cri_alg) {
                   1307:                case CRYPTO_DES_CBC:
                   1308:                        if (encini->cri_klen != 64)
                   1309:                                return (EINVAL);
                   1310:                        break;
                   1311:                case CRYPTO_3DES_CBC:
                   1312:                        if (encini->cri_klen != 192)
                   1313:                                return (EINVAL);
                   1314:                        break;
                   1315:                case CRYPTO_AES_CBC:
                   1316:                        if (encini->cri_klen != 128 &&
                   1317:                            encini->cri_klen != 192 &&
                   1318:                            encini->cri_klen != 256)
                   1319:                                return (EINVAL);
                   1320:                        break;
                   1321:                }
                   1322:        }
                   1323:
                   1324:        if (sc->sc_sessions == NULL) {
                   1325:                ses = sc->sc_sessions = (struct safe_session *)malloc(
                   1326:                    sizeof(struct safe_session), M_DEVBUF, M_NOWAIT);
                   1327:                if (ses == NULL)
                   1328:                        return (ENOMEM);
                   1329:                sesn = 0;
                   1330:                sc->sc_nsessions = 1;
                   1331:        } else {
                   1332:                for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
                   1333:                        if (sc->sc_sessions[sesn].ses_used == 0) {
                   1334:                                ses = &sc->sc_sessions[sesn];
                   1335:                                break;
                   1336:                        }
                   1337:                }
                   1338:
                   1339:                if (ses == NULL) {
                   1340:                        sesn = sc->sc_nsessions;
                   1341:                        ses = (struct safe_session *)malloc((sesn + 1) *
                   1342:                            sizeof(struct safe_session), M_DEVBUF, M_NOWAIT);
                   1343:                        if (ses == NULL)
                   1344:                                return (ENOMEM);
                   1345:                        bcopy(sc->sc_sessions, ses, sesn *
                   1346:                            sizeof(struct safe_session));
                   1347:                        bzero(sc->sc_sessions, sesn *
                   1348:                            sizeof(struct safe_session));
                   1349:                        free(sc->sc_sessions, M_DEVBUF);
                   1350:                        sc->sc_sessions = ses;
                   1351:                        ses = &sc->sc_sessions[sesn];
                   1352:                        sc->sc_nsessions++;
                   1353:                }
                   1354:        }
                   1355:
                   1356:        bzero(ses, sizeof(struct safe_session));
                   1357:        ses->ses_used = 1;
                   1358:
                   1359:        if (encini) {
                   1360:                /* get an IV */
                   1361:                get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv));
                   1362:
                   1363:                ses->ses_klen = encini->cri_klen;
                   1364:                bcopy(encini->cri_key, ses->ses_key, ses->ses_klen / 8);
                   1365:
                   1366:                for (i = 0;
                   1367:                     i < sizeof(ses->ses_key)/sizeof(ses->ses_key[0]); i++)
                   1368:                        ses->ses_key[i] = htole32(ses->ses_key[i]);
                   1369:        }
                   1370:
                   1371:        if (macini) {
                   1372:                for (i = 0; i < macini->cri_klen / 8; i++)
                   1373:                        macini->cri_key[i] ^= HMAC_IPAD_VAL;
                   1374:
                   1375:                if (macini->cri_alg == CRYPTO_MD5_HMAC) {
                   1376:                        MD5Init(&md5ctx);
                   1377:                        MD5Update(&md5ctx, macini->cri_key,
                   1378:                            macini->cri_klen / 8);
                   1379:                        MD5Update(&md5ctx, hmac_ipad_buffer,
                   1380:                            HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                   1381:                        bcopy(md5ctx.state, ses->ses_hminner,
                   1382:                            sizeof(md5ctx.state));
                   1383:                } else {
                   1384:                        SHA1Init(&sha1ctx);
                   1385:                        SHA1Update(&sha1ctx, macini->cri_key,
                   1386:                            macini->cri_klen / 8);
                   1387:                        SHA1Update(&sha1ctx, hmac_ipad_buffer,
                   1388:                            HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                   1389:                        bcopy(sha1ctx.state, ses->ses_hminner,
                   1390:                            sizeof(sha1ctx.state));
                   1391:                }
                   1392:
                   1393:                for (i = 0; i < macini->cri_klen / 8; i++)
                   1394:                        macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
                   1395:
                   1396:                if (macini->cri_alg == CRYPTO_MD5_HMAC) {
                   1397:                        MD5Init(&md5ctx);
                   1398:                        MD5Update(&md5ctx, macini->cri_key,
                   1399:                            macini->cri_klen / 8);
                   1400:                        MD5Update(&md5ctx, hmac_opad_buffer,
                   1401:                            HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                   1402:                        bcopy(md5ctx.state, ses->ses_hmouter,
                   1403:                            sizeof(md5ctx.state));
                   1404:                } else {
                   1405:                        SHA1Init(&sha1ctx);
                   1406:                        SHA1Update(&sha1ctx, macini->cri_key,
                   1407:                            macini->cri_klen / 8);
                   1408:                        SHA1Update(&sha1ctx, hmac_opad_buffer,
                   1409:                            HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                   1410:                        bcopy(sha1ctx.state, ses->ses_hmouter,
                   1411:                            sizeof(sha1ctx.state));
                   1412:                }
                   1413:
                   1414:                for (i = 0; i < macini->cri_klen / 8; i++)
                   1415:                        macini->cri_key[i] ^= HMAC_OPAD_VAL;
                   1416:
                   1417:                /* PE is little-endian, insure proper byte order */
                   1418:                for (i = 0;
                   1419:                     i < sizeof(ses->ses_hminner)/sizeof(ses->ses_hminner[0]);
                   1420:                     i++) {
                   1421:                        ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
                   1422:                        ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
                   1423:                }
                   1424:        }
                   1425:
                   1426:        *sidp = SAFE_SID(sc->sc_dev.dv_unit, sesn);
                   1427:        return (0);
                   1428: }
                   1429:
                   1430: /*
                   1431:  * Deallocate a session.
                   1432:  */
                   1433: int
                   1434: safe_freesession(u_int64_t tid)
                   1435: {
                   1436:        struct safe_softc *sc;
                   1437:        int session, ret, card;
                   1438:        u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
                   1439:
                   1440:        card = SAFE_CARD(sid);
                   1441:        if (card >= safe_cd.cd_ndevs || safe_cd.cd_devs[card] == NULL)
                   1442:                return (EINVAL);
                   1443:        sc = safe_cd.cd_devs[card];
                   1444:
                   1445:        if (sc == NULL)
                   1446:                return (EINVAL);
                   1447:
                   1448:        session = SAFE_SESSION(sid);
                   1449:        if (session < sc->sc_nsessions) {
                   1450:                bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
                   1451:                ret = 0;
                   1452:        } else
                   1453:                ret = EINVAL;
                   1454:        return (ret);
                   1455: }
                   1456:
                   1457: /*
                   1458:  * Is the operand suitable aligned for direct DMA.  Each
                   1459:  * segment must be aligned on a 32-bit boundary and all
                   1460:  * but the last segment must be a multiple of 4 bytes.
                   1461:  */
                   1462: int
                   1463: safe_dmamap_aligned(const struct safe_operand *op)
                   1464: {
                   1465:        int i;
                   1466:
                   1467:        for (i = 0; i < op->map->dm_nsegs; i++) {
                   1468:                if (op->map->dm_segs[i].ds_addr & 3)
                   1469:                        return (0);
                   1470:                if (i != (op->map->dm_nsegs - 1) &&
                   1471:                    (op->map->dm_segs[i].ds_len & 3))
                   1472:                        return (0);
                   1473:        }
                   1474:        return (1);
                   1475: }
                   1476:
                   1477: /*
                   1478:  * Clean up after a chip crash.
                   1479:  * It is assumed that the caller in splnet()
                   1480:  */
                   1481: void
                   1482: safe_cleanchip(struct safe_softc *sc)
                   1483: {
                   1484:
                   1485:        if (sc->sc_nqchip != 0) {
                   1486:                struct safe_ringentry *re = sc->sc_back;
                   1487:
                   1488:                while (re != sc->sc_front) {
                   1489:                        if (re->re_desc.d_csr != 0)
                   1490:                                safe_free_entry(sc, re);
                   1491:                        if (++re == sc->sc_ringtop)
                   1492:                                re = sc->sc_ring;
                   1493:                }
                   1494:                sc->sc_back = re;
                   1495:                sc->sc_nqchip = 0;
                   1496:        }
                   1497: }
                   1498:
                   1499: /*
                   1500:  * free a safe_q
                   1501:  * It is assumed that the caller is within splnet().
                   1502:  */
                   1503: int
                   1504: safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
                   1505: {
                   1506:        struct cryptop *crp;
                   1507:
                   1508:        /*
                   1509:         * Free header MCR
                   1510:         */
                   1511:        if ((re->re_dst_m != NULL) && (re->re_src_m != re->re_dst_m))
                   1512:                m_freem(re->re_dst_m);
                   1513:
                   1514:        crp = (struct cryptop *)re->re_crp;
                   1515:
                   1516:        re->re_desc.d_csr = 0;
                   1517:
                   1518:        crp->crp_etype = EFAULT;
                   1519:        crypto_done(crp);
                   1520:        return (0);
                   1521: }
                   1522:
                   1523: /*
                   1524:  * safe_feed() - post a request to chip
                   1525:  */
                   1526: void
                   1527: safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
                   1528: {
                   1529:        bus_dmamap_sync(sc->sc_dmat, re->re_src_map,
                   1530:            0, re->re_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
                   1531:        if (re->re_dst_map != NULL)
                   1532:                bus_dmamap_sync(sc->sc_dmat, re->re_dst_map, 0,
                   1533:                    re->re_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD);
                   1534:        /* XXX have no smaller granularity */
                   1535:        safe_dma_sync(sc, &sc->sc_ringalloc,
                   1536:                BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
                   1537:        safe_dma_sync(sc, &sc->sc_spalloc, BUS_DMASYNC_PREWRITE);
                   1538:        safe_dma_sync(sc, &sc->sc_dpalloc, BUS_DMASYNC_PREWRITE);
                   1539:
                   1540: #ifdef SAFE_DEBUG
                   1541:        if (safe_debug) {
                   1542:                safe_dump_ringstate(sc, __func__);
                   1543:                safe_dump_request(sc, __func__, re);
                   1544:        }
                   1545: #endif
                   1546:        sc->sc_nqchip++;
                   1547:        if (sc->sc_nqchip > safestats.st_maxqchip)
                   1548:                safestats.st_maxqchip = sc->sc_nqchip;
                   1549:        /* poke h/w to check descriptor ring, any value can be written */
                   1550:        WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
                   1551: }
                   1552:
                   1553: /*
                   1554:  * Is the operand suitable for direct DMA as the destination
                   1555:  * of an operation.  The hardware requires that each ``particle''
                   1556:  * but the last in an operation result have the same size.  We
                   1557:  * fix that size at SAFE_MAX_DSIZE bytes.  This routine returns
                   1558:  * 0 if some segment is not a multiple of this size, 1 if all
                   1559:  * segments are exactly this size, or 2 if segments are at worst
                   1560:  * a multple of this size.
                   1561:  */
                   1562: int
                   1563: safe_dmamap_uniform(const struct safe_operand *op)
                   1564: {
                   1565:        int result = 1, i;
                   1566:
                   1567:        if (op->map->dm_nsegs <= 0)
                   1568:                return (result);
                   1569:
                   1570:        for (i = 0; i < op->map->dm_nsegs-1; i++) {
                   1571:                if (op->map->dm_segs[i].ds_len % SAFE_MAX_DSIZE)
                   1572:                        return (0);
                   1573:                if (op->map->dm_segs[i].ds_len != SAFE_MAX_DSIZE)
                   1574:                        result = 2;
                   1575:        }
                   1576:        return (result);
                   1577: }
                   1578:
                   1579: /*
                   1580:  * Copy all data past offset from srcm to dstm.
                   1581:  */
                   1582: void
                   1583: safe_mcopy(struct mbuf *srcm, struct mbuf *dstm, u_int offset)
                   1584: {
                   1585:        u_int j, dlen, slen;
                   1586:        caddr_t dptr, sptr;
                   1587:
                   1588:        /*
                   1589:         * Advance src and dst to offset.
                   1590:         */
                   1591:        for (j = offset; srcm->m_len <= j;) {
                   1592:                j -= srcm->m_len;
                   1593:                srcm = srcm->m_next;
                   1594:                if (srcm == NULL)
                   1595:                        return;
                   1596:        }
                   1597:        sptr = mtod(srcm, caddr_t) + j;
                   1598:        slen = srcm->m_len - j;
                   1599:
                   1600:        for (j = offset; dstm->m_len <= j;) {
                   1601:                j -= dstm->m_len;
                   1602:                dstm = dstm->m_next;
                   1603:                if (dstm == NULL)
                   1604:                        return;
                   1605:        }
                   1606:        dptr = mtod(dstm, caddr_t) + j;
                   1607:        dlen = dstm->m_len - j;
                   1608:
                   1609:        /*
                   1610:         * Copy everything that remains.
                   1611:         */
                   1612:        for (;;) {
                   1613:                j = min(slen, dlen);
                   1614:                bcopy(sptr, dptr, j);
                   1615:                if (slen == j) {
                   1616:                        srcm = srcm->m_next;
                   1617:                        if (srcm == NULL)
                   1618:                                return;
                   1619:                        sptr = srcm->m_data;
                   1620:                        slen = srcm->m_len;
                   1621:                } else
                   1622:                        sptr += j, slen -= j;
                   1623:                if (dlen == j) {
                   1624:                        dstm = dstm->m_next;
                   1625:                        if (dstm == NULL)
                   1626:                                return;
                   1627:                        dptr = dstm->m_data;
                   1628:                        dlen = dstm->m_len;
                   1629:                } else
                   1630:                        dptr += j, dlen -= j;
                   1631:        }
                   1632: }
                   1633:
                   1634: void
                   1635: safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
                   1636: {
                   1637:        struct cryptop *crp = (struct cryptop *)re->re_crp;
                   1638:        struct cryptodesc *crd;
                   1639:
                   1640:        safestats.st_opackets++;
                   1641:        safestats.st_obytes += (re->re_dst_map == NULL) ?
                   1642:            re->re_src_mapsize : re->re_dst_mapsize;
                   1643:
                   1644:        safe_dma_sync(sc, &sc->sc_ringalloc,
                   1645:                BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1646:        if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
                   1647:                printf("%s: csr 0x%x cmd0 0x%x cmd1 0x%x\n",
                   1648:                    sc->sc_dev.dv_xname, re->re_desc.d_csr,
                   1649:                        re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
                   1650:                safestats.st_peoperr++;
                   1651:                crp->crp_etype = EIO;           /* something more meaningful? */
                   1652:        }
                   1653:        if (re->re_dst_map != NULL && re->re_dst_map != re->re_src_map) {
                   1654:                bus_dmamap_sync(sc->sc_dmat, re->re_dst_map, 0,
                   1655:                    re->re_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1656:                bus_dmamap_unload(sc->sc_dmat, re->re_dst_map);
                   1657:                bus_dmamap_destroy(sc->sc_dmat, re->re_dst_map);
                   1658:        }
                   1659:        bus_dmamap_sync(sc->sc_dmat, re->re_src_map, 0,
                   1660:            re->re_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1661:        bus_dmamap_unload(sc->sc_dmat, re->re_src_map);
                   1662:        bus_dmamap_destroy(sc->sc_dmat, re->re_src_map);
                   1663:
                   1664:        /*
                   1665:         * If result was written to a different mbuf chain, swap
                   1666:         * it in as the return value and reclaim the original.
                   1667:         */
                   1668:        if ((crp->crp_flags & CRYPTO_F_IMBUF) && re->re_src_m != re->re_dst_m) {
                   1669:                m_freem(re->re_src_m);
                   1670:                crp->crp_buf = (caddr_t)re->re_dst_m;
                   1671:        }
                   1672:
                   1673:        if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
                   1674:                /* copy out IV for future use */
                   1675:                for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
                   1676:                        int ivsize;
                   1677:
                   1678:                        if (crd->crd_alg == CRYPTO_DES_CBC ||
                   1679:                            crd->crd_alg == CRYPTO_3DES_CBC) {
                   1680:                                ivsize = 2*sizeof(u_int32_t);
                   1681:                        } else if (crd->crd_alg == CRYPTO_AES_CBC) {
                   1682:                                ivsize = 4*sizeof(u_int32_t);
                   1683:                        } else
                   1684:                                continue;
                   1685:                        if (crp->crp_flags & CRYPTO_F_IMBUF) {
                   1686:                                m_copydata((struct mbuf *)crp->crp_buf,
                   1687:                                        crd->crd_skip + crd->crd_len - ivsize,
                   1688:                                        ivsize,
                   1689:                                        (caddr_t) sc->sc_sessions[re->re_sesn].ses_iv);
                   1690:                        } else if (crp->crp_flags & CRYPTO_F_IOV) {
                   1691:                                cuio_copydata((struct uio *)crp->crp_buf,
                   1692:                                        crd->crd_skip + crd->crd_len - ivsize,
                   1693:                                        ivsize,
                   1694:                                        (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
                   1695:                        }
                   1696:                        break;
                   1697:                }
                   1698:        }
                   1699:
                   1700:        if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
                   1701:                /* copy out ICV result */
                   1702:                for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
                   1703:                        if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
                   1704:                            crd->crd_alg == CRYPTO_SHA1_HMAC))
                   1705:                                continue;
                   1706:                        if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
                   1707:                                /*
                   1708:                                 * SHA-1 ICV's are byte-swapped; fix 'em up
                   1709:                                 * before copy them to their destination.
                   1710:                                 */
                   1711:                                bswap32(re->re_sastate.sa_saved_indigest[0]);
                   1712:                                bswap32(re->re_sastate.sa_saved_indigest[1]);
                   1713:                                bswap32(re->re_sastate.sa_saved_indigest[2]);
                   1714:                        }
                   1715:                        if (crp->crp_flags & CRYPTO_F_IMBUF) {
                   1716:                                m_copyback((struct mbuf *)crp->crp_buf,
                   1717:                                        crd->crd_inject, 12,
                   1718:                                        (caddr_t)re->re_sastate.sa_saved_indigest);
                   1719:                        } else if (crp->crp_flags & CRYPTO_F_IOV && crp->crp_mac) {
                   1720:                                bcopy((caddr_t)re->re_sastate.sa_saved_indigest,
                   1721:                                        crp->crp_mac, 12);
                   1722:                        }
                   1723:                        break;
                   1724:                }
                   1725:        }
                   1726:
                   1727:        crypto_done(crp);
                   1728: }
                   1729:
                   1730: /*
                   1731:  * SafeXcel Interrupt routine
                   1732:  */
                   1733: int
                   1734: safe_intr(void *arg)
                   1735: {
                   1736:        struct safe_softc *sc = arg;
                   1737:        volatile u_int32_t stat;
                   1738:
                   1739:        stat = READ_REG(sc, SAFE_HM_STAT);
                   1740:        if (stat == 0)                  /* shared irq, not for us */
                   1741:                return (0);
                   1742:
                   1743:        WRITE_REG(sc, SAFE_HI_CLR, stat);       /* IACK */
                   1744:
                   1745:        if ((stat & SAFE_INT_PE_DDONE)) {
                   1746:                /*
                   1747:                 * Descriptor(s) done; scan the ring and
                   1748:                 * process completed operations.
                   1749:                 */
                   1750:                while (sc->sc_back != sc->sc_front) {
                   1751:                        struct safe_ringentry *re = sc->sc_back;
                   1752: #ifdef SAFE_DEBUG
                   1753:                        if (safe_debug) {
                   1754:                                safe_dump_ringstate(sc, __func__);
                   1755:                                safe_dump_request(sc, __func__, re);
                   1756:                        }
                   1757: #endif
                   1758:                        /*
                   1759:                         * safe_process marks ring entries that were allocated
                   1760:                         * but not used with a csr of zero.  This insures the
                   1761:                         * ring front pointer never needs to be set backwards
                   1762:                         * in the event that an entry is allocated but not used
                   1763:                         * because of a setup error.
                   1764:                         */
                   1765:                        if (re->re_desc.d_csr != 0) {
                   1766:                                if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr))
                   1767:                                        break;
                   1768:                                if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len))
                   1769:                                        break;
                   1770:                                sc->sc_nqchip--;
                   1771:                                safe_callback(sc, re);
                   1772:                        }
                   1773:                        if (++(sc->sc_back) == sc->sc_ringtop)
                   1774:                                sc->sc_back = sc->sc_ring;
                   1775:                }
                   1776:        }
                   1777:
                   1778:        return (1);
                   1779: }
                   1780:
                   1781: struct safe_softc *
                   1782: safe_kfind(struct cryptkop *krp)
                   1783: {
                   1784:        struct safe_softc *sc;
                   1785:        int i;
                   1786:
                   1787:        for (i = 0; i < safe_cd.cd_ndevs; i++) {
                   1788:                sc = safe_cd.cd_devs[i];
                   1789:                if (sc == NULL)
                   1790:                        continue;
                   1791:                if (sc->sc_cid == krp->krp_hid)
                   1792:                        return (sc);
                   1793:        }
                   1794:        return (NULL);
                   1795: }
                   1796:
                   1797: int
                   1798: safe_kprocess(struct cryptkop *krp)
                   1799: {
                   1800:        struct safe_softc *sc;
                   1801:        struct safe_pkq *q;
                   1802:        int s;
                   1803:
                   1804:        if ((sc = safe_kfind(krp)) == NULL) {
                   1805:                krp->krp_status = EINVAL;
                   1806:                goto err;
                   1807:        }
                   1808:
                   1809:        if (krp->krp_op != CRK_MOD_EXP) {
                   1810:                krp->krp_status = EOPNOTSUPP;
                   1811:                goto err;
                   1812:        }
                   1813:
                   1814:        q = (struct safe_pkq *)malloc(sizeof(*q), M_DEVBUF, M_NOWAIT);
                   1815:        if (q == NULL) {
                   1816:                krp->krp_status = ENOMEM;
                   1817:                goto err;
                   1818:        }
                   1819:        q->pkq_krp = krp;
                   1820:
                   1821:        s = splnet();
                   1822:        SIMPLEQ_INSERT_TAIL(&sc->sc_pkq, q, pkq_next);
                   1823:        safe_kfeed(sc);
                   1824:        splx(s);
                   1825:        return (0);
                   1826:
                   1827: err:
                   1828:        crypto_kdone(krp);
                   1829:        return (0);
                   1830: }
                   1831:
                   1832: #define        SAFE_CRK_PARAM_BASE     0
                   1833: #define        SAFE_CRK_PARAM_EXP      1
                   1834: #define        SAFE_CRK_PARAM_MOD      2
                   1835:
                   1836: int
                   1837: safe_kstart(struct safe_softc *sc)
                   1838: {
                   1839:        struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
                   1840:        int exp_bits, mod_bits, base_bits;
                   1841:        u_int32_t op, a_off, b_off, c_off, d_off;
                   1842:
                   1843:        if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
                   1844:                krp->krp_status = EINVAL;
                   1845:                return (1);
                   1846:        }
                   1847:
                   1848:        base_bits = safe_ksigbits(&krp->krp_param[SAFE_CRK_PARAM_BASE]);
                   1849:        if (base_bits > 2048)
                   1850:                goto too_big;
                   1851:        if (base_bits <= 0)             /* 5. base not zero */
                   1852:                goto too_small;
                   1853:
                   1854:        exp_bits = safe_ksigbits(&krp->krp_param[SAFE_CRK_PARAM_EXP]);
                   1855:        if (exp_bits > 2048)
                   1856:                goto too_big;
                   1857:        if (exp_bits <= 0)              /* 1. exponent word length > 0 */
                   1858:                goto too_small;         /* 4. exponent not zero */
                   1859:
                   1860:        mod_bits = safe_ksigbits(&krp->krp_param[SAFE_CRK_PARAM_MOD]);
                   1861:        if (mod_bits > 2048)
                   1862:                goto too_big;
                   1863:        if (mod_bits <= 32)             /* 2. modulus word length > 1 */
                   1864:                goto too_small;         /* 8. MSW of modulus != zero */
                   1865:        if (mod_bits < exp_bits)        /* 3 modulus len >= exponent len */
                   1866:                goto too_small;
                   1867:        if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
                   1868:                goto bad_domain;        /* 6. modulus is odd */
                   1869:        if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
                   1870:                goto too_small;         /* make sure result will fit */
                   1871:
                   1872:        /* 7. modulus > base */
                   1873:        if (mod_bits < base_bits)
                   1874:                goto too_small;
                   1875:        if (mod_bits == base_bits) {
                   1876:                u_int8_t *basep, *modp;
                   1877:                int i;
                   1878:
                   1879:                basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
                   1880:                    ((base_bits + 7) / 8) - 1;
                   1881:                modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
                   1882:                    ((mod_bits + 7) / 8) - 1;
                   1883:
                   1884:                for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
                   1885:                        if (*modp < *basep)
                   1886:                                goto too_small;
                   1887:                        if (*modp > *basep)
                   1888:                                break;
                   1889:                }
                   1890:        }
                   1891:
                   1892:        /* And on the 9th step, he rested. */
                   1893:
                   1894:        WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
                   1895:        WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
                   1896:        if (mod_bits > 1024) {
                   1897:                op = SAFE_PK_FUNC_EXP4;
                   1898:                a_off = 0x000;
                   1899:                b_off = 0x100;
                   1900:                c_off = 0x200;
                   1901:                d_off = 0x300;
                   1902:        } else {
                   1903:                op = SAFE_PK_FUNC_EXP16;
                   1904:                a_off = 0x000;
                   1905:                b_off = 0x080;
                   1906:                c_off = 0x100;
                   1907:                d_off = 0x180;
                   1908:        }
                   1909:        sc->sc_pk_reslen = b_off - a_off;
                   1910:        sc->sc_pk_resoff = d_off;
                   1911:
                   1912:        /* A is exponent, B is modulus, C is base, D is result */
                   1913:        safe_kload_reg(sc, a_off, b_off - a_off,
                   1914:            &krp->krp_param[SAFE_CRK_PARAM_EXP]);
                   1915:        WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
                   1916:        safe_kload_reg(sc, b_off, b_off - a_off,
                   1917:            &krp->krp_param[SAFE_CRK_PARAM_MOD]);
                   1918:        WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
                   1919:        safe_kload_reg(sc, c_off, b_off - a_off,
                   1920:            &krp->krp_param[SAFE_CRK_PARAM_BASE]);
                   1921:        WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
                   1922:        WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
                   1923:
                   1924:        WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
                   1925:
                   1926:        return (0);
                   1927:
                   1928: too_big:
                   1929:        krp->krp_status = E2BIG;
                   1930:        return (1);
                   1931: too_small:
                   1932:        krp->krp_status = ERANGE;
                   1933:        return (1);
                   1934: bad_domain:
                   1935:        krp->krp_status = EDOM;
                   1936:        return (1);
                   1937: }
                   1938:
                   1939: int
                   1940: safe_ksigbits(struct crparam *cr)
                   1941: {
                   1942:        u_int plen = (cr->crp_nbits + 7) / 8;
                   1943:        int i, sig = plen * 8;
                   1944:        u_int8_t c, *p = cr->crp_p;
                   1945:
                   1946:        for (i = plen - 1; i >= 0; i--) {
                   1947:                c = p[i];
                   1948:                if (c != 0) {
                   1949:                        while ((c & 0x80) == 0) {
                   1950:                                sig--;
                   1951:                                c <<= 1;
                   1952:                        }
                   1953:                        break;
                   1954:                }
                   1955:                sig -= 8;
                   1956:        }
                   1957:        return (sig);
                   1958: }
                   1959:
                   1960: void
                   1961: safe_kfeed(struct safe_softc *sc)
                   1962: {
                   1963:        if (SIMPLEQ_EMPTY(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
                   1964:                return;
                   1965:        if (sc->sc_pkq_cur != NULL)
                   1966:                return;
                   1967:        while (!SIMPLEQ_EMPTY(&sc->sc_pkq)) {
                   1968:                struct safe_pkq *q = SIMPLEQ_FIRST(&sc->sc_pkq);
                   1969:
                   1970:                sc->sc_pkq_cur = q;
                   1971:                SIMPLEQ_REMOVE_HEAD(&sc->sc_pkq, pkq_next);
                   1972:                if (safe_kstart(sc) != 0) {
                   1973:                        crypto_kdone(q->pkq_krp);
                   1974:                        free(q, M_DEVBUF);
                   1975:                        sc->sc_pkq_cur = NULL;
                   1976:                } else {
                   1977:                        /* op started, start polling */
                   1978:                        timeout_add(&sc->sc_pkto, 1);
                   1979:                        break;
                   1980:                }
                   1981:        }
                   1982: }
                   1983:
                   1984: void
                   1985: safe_kpoll(void *vsc)
                   1986: {
                   1987:        struct safe_softc *sc = vsc;
                   1988:        struct safe_pkq *q;
                   1989:        struct crparam *res;
                   1990:        int s, i;
                   1991:        u_int32_t buf[64];
                   1992:
                   1993:        s = splnet();
                   1994:        if (sc->sc_pkq_cur == NULL)
                   1995:                goto out;
                   1996:        if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
                   1997:                /* still running, check back later */
                   1998:                timeout_add(&sc->sc_pkto, 1);
                   1999:                goto out;
                   2000:        }
                   2001:
                   2002:        q = sc->sc_pkq_cur;
                   2003:        res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
                   2004:        bzero(buf, sizeof(buf));
                   2005:        bzero(res->crp_p, (res->crp_nbits + 7) / 8);
                   2006:        for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
                   2007:                buf[i] = letoh32(READ_REG(sc, SAFE_PK_RAM_START +
                   2008:                    sc->sc_pk_resoff + (i << 2)));
                   2009:        bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
                   2010:        res->crp_nbits = sc->sc_pk_reslen * 8;
                   2011:        res->crp_nbits = safe_ksigbits(res);
                   2012:
                   2013:        for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
                   2014:                WRITE_REG(sc, i, 0);
                   2015:
                   2016:        crypto_kdone(q->pkq_krp);
                   2017:        free(q, M_DEVBUF);
                   2018:        sc->sc_pkq_cur = NULL;
                   2019:
                   2020:        safe_kfeed(sc);
                   2021: out:
                   2022:        splx(s);
                   2023: }
                   2024:
                   2025: void
                   2026: safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
                   2027:     struct crparam *n)
                   2028: {
                   2029:        u_int32_t buf[64], i;
                   2030:
                   2031:        bzero(buf, sizeof(buf));
                   2032:        bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
                   2033:
                   2034:        for (i = 0; i < len >> 2; i++)
                   2035:                WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
                   2036:                    htole32(buf[i]));
                   2037: }
                   2038:
                   2039: #ifdef SAFE_DEBUG
                   2040:
                   2041: void
                   2042: safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
                   2043: {
                   2044:        printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n", tag,
                   2045:            READ_REG(sc, SAFE_DMA_ENDIAN), READ_REG(sc, SAFE_DMA_SRCADDR),
                   2046:            READ_REG(sc, SAFE_DMA_DSTADDR), READ_REG(sc, SAFE_DMA_STAT));
                   2047: }
                   2048:
                   2049: void
                   2050: safe_dump_intrstate(struct safe_softc *sc, const char *tag)
                   2051: {
                   2052:        printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n",
                   2053:            tag, READ_REG(sc, SAFE_HI_CFG), READ_REG(sc, SAFE_HI_MASK),
                   2054:            READ_REG(sc, SAFE_HI_DESC_CNT), READ_REG(sc, SAFE_HU_STAT),
                   2055:            READ_REG(sc, SAFE_HM_STAT));
                   2056: }
                   2057:
                   2058: void
                   2059: safe_dump_ringstate(struct safe_softc *sc, const char *tag)
                   2060: {
                   2061:        u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
                   2062:
                   2063:        /* NB: assume caller has lock on ring */
                   2064:        printf("%s: ERNGSTAT %x (next %u) back %u front %u\n",
                   2065:            tag, estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
                   2066:            sc->sc_back - sc->sc_ring, sc->sc_front - sc->sc_ring);
                   2067: }
                   2068:
                   2069: void
                   2070: safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
                   2071: {
                   2072:        int ix, nsegs;
                   2073:
                   2074:        ix = re - sc->sc_ring;
                   2075:        printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n", tag,
                   2076:            re, ix, re->re_desc.d_csr, re->re_desc.d_src, re->re_desc.d_dst,
                   2077:            re->re_desc.d_sa, re->re_desc.d_len);
                   2078:        if (re->re_src_nsegs > 1) {
                   2079:                ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
                   2080:                    sizeof(struct safe_pdesc);
                   2081:                for (nsegs = re->re_src_nsegs; nsegs; nsegs--) {
                   2082:                        printf(" spd[%u] %p: %p", ix,
                   2083:                            &sc->sc_spring[ix],
                   2084:                            (caddr_t)sc->sc_spring[ix].pd_addr);
                   2085:                        printf("\n");
                   2086:                        if (++ix == SAFE_TOTAL_SPART)
                   2087:                                ix = 0;
                   2088:                }
                   2089:        }
                   2090:        if (re->re_dst_nsegs > 1) {
                   2091:                ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
                   2092:                    sizeof(struct safe_pdesc);
                   2093:                for (nsegs = re->re_dst_nsegs; nsegs; nsegs--) {
                   2094:                        printf(" dpd[%u] %p: %p\n", ix,
                   2095:                            &sc->sc_dpring[ix],
                   2096:                            (caddr_t) sc->sc_dpring[ix].pd_addr);
                   2097:                        if (++ix == SAFE_TOTAL_DPART)
                   2098:                                ix = 0;
                   2099:                }
                   2100:        }
                   2101:        printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
                   2102:            re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
                   2103:        printf("sa: key %x %x %x %x %x %x %x %x\n", re->re_sa.sa_key[0],
                   2104:            re->re_sa.sa_key[1], re->re_sa.sa_key[2], re->re_sa.sa_key[3],
                   2105:            re->re_sa.sa_key[4], re->re_sa.sa_key[5], re->re_sa.sa_key[6],
                   2106:            re->re_sa.sa_key[7]);
                   2107:        printf("sa: indigest %x %x %x %x %x\n", re->re_sa.sa_indigest[0],
                   2108:            re->re_sa.sa_indigest[1], re->re_sa.sa_indigest[2],
                   2109:            re->re_sa.sa_indigest[3], re->re_sa.sa_indigest[4]);
                   2110:        printf("sa: outdigest %x %x %x %x %x\n", re->re_sa.sa_outdigest[0],
                   2111:            re->re_sa.sa_outdigest[1], re->re_sa.sa_outdigest[2],
                   2112:            re->re_sa.sa_outdigest[3], re->re_sa.sa_outdigest[4]);
                   2113:        printf("sr: iv %x %x %x %x\n",
                   2114:            re->re_sastate.sa_saved_iv[0], re->re_sastate.sa_saved_iv[1],
                   2115:            re->re_sastate.sa_saved_iv[2], re->re_sastate.sa_saved_iv[3]);
                   2116:        printf("sr: hashbc %u indigest %x %x %x %x %x\n",
                   2117:            re->re_sastate.sa_saved_hashbc,
                   2118:            re->re_sastate.sa_saved_indigest[0],
                   2119:            re->re_sastate.sa_saved_indigest[1],
                   2120:            re->re_sastate.sa_saved_indigest[2],
                   2121:            re->re_sastate.sa_saved_indigest[3],
                   2122:            re->re_sastate.sa_saved_indigest[4]);
                   2123: }
                   2124:
                   2125: void
                   2126: safe_dump_ring(struct safe_softc *sc, const char *tag)
                   2127: {
                   2128:        printf("\nSafeNet Ring State:\n");
                   2129:        safe_dump_intrstate(sc, tag);
                   2130:        safe_dump_dmastatus(sc, tag);
                   2131:        safe_dump_ringstate(sc, tag);
                   2132:        if (sc->sc_nqchip) {
                   2133:                struct safe_ringentry *re = sc->sc_back;
                   2134:                do {
                   2135:                        safe_dump_request(sc, tag, re);
                   2136:                        if (++re == sc->sc_ringtop)
                   2137:                                re = sc->sc_ring;
                   2138:                } while (re != sc->sc_front);
                   2139:        }
                   2140: }
                   2141:
                   2142: #endif /* SAFE_DEBUG */

CVSweb