Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Preliminary port of merged OpenBSD/FreeBSD ubsec...



details:   https://anonhg.NetBSD.org/src/rev/409e6a6a4d05
branches:  trunk
changeset: 550172:409e6a6a4d05
user:      jonathan <jonathan%NetBSD.org@localhost>
date:      Fri Aug 01 00:08:55 2003 +0000

description:
Preliminary port of merged OpenBSD/FreeBSD ubsec driver for Bluesteel
Networks/Broadcom line of cryptographic accelerators.

diffstat:

 sys/dev/pci/ubsec.c    |  2822 ++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/pci/ubsecreg.h |   194 +++
 sys/dev/pci/ubsecvar.h |   222 +++
 3 files changed, 3238 insertions(+), 0 deletions(-)

diffs (truncated from 3250 to 300 lines):

diff -r 9bb06600bdf9 -r 409e6a6a4d05 sys/dev/pci/ubsec.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/ubsec.c       Fri Aug 01 00:08:55 2003 +0000
@@ -0,0 +1,2822 @@
+/*     $NetBSD: ubsec.c,v 1.1 2003/08/01 00:08:55 jonathan Exp $       */
+/* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */
+/*     $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $       */
+
+/*
+ * Copyright (c) 2000 Jason L. Wright (jason%thought.net@localhost)
+ * Copyright (c) 2000 Theo de Raadt (deraadt%openbsd.org@localhost)
+ * Copyright (c) 2001 Patrik Lindergren (patrik%ipunplugged.com@localhost)
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ */
+
+#undef UBSEC_DEBUG
+
+/*
+ * uBsec 5[56]01, bcm580xx, bcm582x hardware crypto accelerator
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/endian.h>
+#ifdef __NetBSD__
+  #define letoh16 htole16
+  #define letoh32 htole32
+#define UBSEC_NO_RNG           /* until statistically tested */
+#endif
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/cryptosoft.h>
+#ifdef __OpenBSD__
+ #include <dev/rndvar.h>
+ #include <sys/md5k.h>
+#else
+ #include <sys/rnd.h>
+ #include <sys/md5.h>
+#endif
+#include <sys/sha1.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/pci/ubsecreg.h>
+#include <dev/pci/ubsecvar.h>
+
+/*
+ * Prototypes and count for the pci_device structure
+ */
+static int ubsec_probe(struct device *, struct cfdata *, void *);
+static void ubsec_attach(struct device *, struct device *, void *);
+static void ubsec_reset_board(struct ubsec_softc *);
+static void ubsec_init_board(struct ubsec_softc *);
+static void ubsec_init_pciregs(struct pci_attach_args *pa);
+static void ubsec_cleanchip(struct ubsec_softc *);
+static void ubsec_totalreset(struct ubsec_softc *);
+static int  ubsec_free_q(struct ubsec_softc*, struct ubsec_q *);
+
+#ifdef __OpenBSD__
+struct cfattach ubsec_ca = {
+       sizeof(struct ubsec_softc), ubsec_probe, ubsec_attach,
+};
+
+struct cfdriver ubsec_cd = {
+       0, "ubsec", DV_DULL
+};
+#else
+CFATTACH_DECL(ubsec, sizeof(struct ubsec_softc), ubsec_probe, ubsec_attach,
+             NULL, NULL);
+extern struct cfdriver ubsec_cd;
+#endif
+
+/* patchable */
+#ifdef UBSEC_DEBUG
+extern int ubsec_debug;
+int ubsec_debug=1;
+#endif
+
+static int     ubsec_intr(void *);
+static int     ubsec_newsession(void*, u_int32_t *, struct cryptoini *);
+static int     ubsec_freesession(void*, u_int64_t);
+static int     ubsec_process(void*, struct cryptop *, int hint);
+static void    ubsec_callback(struct ubsec_softc *, struct ubsec_q *);
+static void    ubsec_feed(struct ubsec_softc *);
+static void    ubsec_mcopy(struct mbuf *, struct mbuf *, int, int);
+static void    ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *);
+static void    ubsec_feed2(struct ubsec_softc *);
+#ifndef UBSEC_NO_RNG
+static void    ubsec_rng(void *);
+#endif /* UBSEC_NO_RNG */
+static int     ubsec_dma_malloc(struct ubsec_softc *, bus_size_t,
+                                struct ubsec_dma_alloc *, int);
+static void    ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *);
+static int     ubsec_dmamap_aligned(bus_dmamap_t);
+
+#ifdef __OpenBSD__
+struct ubsec_softc *ubsec_kfind(struct cryptkop *);
+#endif
+
+static int     ubsec_kprocess(void*, struct cryptkop *, int);
+static int     ubsec_kprocess_modexp_sw(struct ubsec_softc *,
+                                        struct cryptkop *, int);
+static int     ubsec_kprocess_modexp_hw(struct ubsec_softc *,
+                                        struct cryptkop *, int);
+static int     ubsec_kprocess_rsapriv(struct ubsec_softc *,
+                                      struct cryptkop *, int);
+static void    ubsec_kfree(struct ubsec_softc *, struct ubsec_q2 *);
+static int     ubsec_ksigbits(struct crparam *);
+static void    ubsec_kshift_r(u_int, u_int8_t *, u_int, u_int8_t *, u_int);
+static void    ubsec_kshift_l(u_int, u_int8_t *, u_int, u_int8_t *, u_int);
+
+#ifdef UBSEC_DEBUG
+static void    ubsec_dump_pb(volatile struct ubsec_pktbuf *);
+static void    ubsec_dump_mcr(struct ubsec_mcr *);
+static void    ubsec_dump_ctx2(volatile struct ubsec_ctx_keyop *);
+#endif
+
+#define        READ_REG(sc,r) \
+       bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r))
+
+#define WRITE_REG(sc,reg,val) \
+       bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val)
+
+#define        SWAP32(x) (x) = htole32(ntohl((x)))
+#ifndef HTOLE32
+ #define       HTOLE32(x) (x) = htole32(x)
+#endif
+
+struct ubsec_stats ubsecstats;
+
+/*
+ * ubsec_maxbatch controls the number of crypto ops to voluntarily 
+ * collect into one submission to the hardware.  This batching happens
+ * when ops are dispatched from the crypto subsystem with a hint that
+ * more are to follow immediately.  These ops must also not be marked
+ * with a ``no delay'' flag.
+ */
+static int ubsec_maxbatch = 1;
+#ifdef SYSCTL_INT
+SYSCTL_INT(_kern, OID_AUTO, ubsec_maxbatch, CTLFLAG_RW, &ubsec_maxbatch,
+           0, "Broadcom driver: max ops to batch w/o interrupt");
+#endif
+
+/*
+ * ubsec_maxaggr controls the number of crypto ops to submit to the
+ * hardware as a unit.  This aggregation reduces the number of interrupts
+ * to the host at the expense of increased latency (for all but the last
+ * operation).  For network traffic setting this to one yields the highest
+ * performance but at the expense of more interrupt processing.
+ */
+static int ubsec_maxaggr = 1;
+#ifdef SYSCTL_INT
+SYSCTL_INT(_kern, OID_AUTO, ubsec_maxaggr, CTLFLAG_RW, &ubsec_maxaggr,
+           0, "Broadcom driver: max ops to aggregate under one interrupt");
+#endif
+
+static int
+ubsec_probe(parent, match, aux)
+       struct device *parent;
+       struct cfdata *match;
+       void *aux;
+{
+       struct pci_attach_args *pa = (struct pci_attach_args *)aux;
+
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL &&
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5501 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5601))
+               return (1);
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5801 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5802 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5805 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5820 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5821 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5823))
+               return (1);
+
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN && 
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SCA1K ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_5821))
+               return (1);
+
+       return (0);
+}
+
+void
+ubsec_attach(parent, self, aux)
+       struct device *parent, *self;
+       void *aux;
+{
+       struct ubsec_softc *sc = (struct ubsec_softc *)self;
+       struct pci_attach_args *pa = aux;
+       pci_chipset_tag_t pc = pa->pa_pc;
+       pci_intr_handle_t ih;
+       const char *intrstr = NULL;
+       struct ubsec_dma *dmap;
+       bus_size_t iosize;
+       int mapreg;
+       u_int32_t cmd, i;
+
+       SIMPLEQ_INIT(&sc->sc_queue);
+       SIMPLEQ_INIT(&sc->sc_qchip);
+       SIMPLEQ_INIT(&sc->sc_queue2);
+       SIMPLEQ_INIT(&sc->sc_qchip2);
+       SIMPLEQ_INIT(&sc->sc_q2free);
+
+       sc->sc_statmask = BS_STAT_MCR1_DONE | BS_STAT_DMAERR;
+
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL &&
+           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5601)
+               sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG;
+
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5802 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5805))
+               sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG;
+
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5820 ||
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822))
+               sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG |
+                   UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY;
+
+       if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
+            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5821 ||
+             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822 ||
+             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5823)) ||
+           (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN &&
+            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SCA1K ||
+             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_5821))) {
+               /* NB: the 5821/5822 defines some additional status bits */
+               sc->sc_statmask |= BS_STAT_MCR1_ALLEMPTY |
+                   BS_STAT_MCR2_ALLEMPTY;
+               sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG |
+                   UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY;
+       }
+
+       cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+       cmd |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
+       pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, cmd);
+       cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+
+       if (!(cmd & PCI_COMMAND_MEM_ENABLE)) {
+               printf(": failed to enable memory mapping\n");
+               return;
+       }
+
+       if (!(cmd & PCI_COMMAND_MASTER_ENABLE)) {
+               printf(": failed to enable bus mastering\n");
+               return;
+       }
+
+#ifdef __OpenBSD__
+       mapreg= pci_mapreg_map(pa, BS_BAR, PCI_MAPREG_TYPE_MEM, 0,
+           &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0);
+#else
+       mapreg= pci_mapreg_map(pa, BS_BAR, PCI_MAPREG_TYPE_MEM, 0,
+           &sc->sc_st, &sc->sc_sh, &iosize, 0);
+#endif
+
+       if (mapreg) {
+               printf(": can't find mem space\n");
+               return;



Home | Main Index | Thread Index | Old Index