root/dev/pci/safe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. safe_probe
  2. safe_attach
  3. safe_process
  4. safe_reset_board
  5. safe_init_board
  6. safe_init_pciregs
  7. safe_dma_malloc
  8. safe_dma_free
  9. safe_rng_init
  10. safe_rng_read
  11. safe_rng
  12. safe_newsession
  13. safe_freesession
  14. safe_dmamap_aligned
  15. safe_cleanchip
  16. safe_free_entry
  17. safe_feed
  18. safe_dmamap_uniform
  19. safe_mcopy
  20. safe_callback
  21. safe_intr
  22. safe_kfind
  23. safe_kprocess
  24. safe_kstart
  25. safe_ksigbits
  26. safe_kfeed
  27. safe_kpoll
  28. safe_kload_reg
  29. safe_dump_dmastatus
  30. safe_dump_intrstate
  31. safe_dump_ringstate
  32. safe_dump_request
  33. safe_dump_ring

    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 */

/* [<][>][^][v][top][bottom][index][help] */