Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/qbus Rewritten (most of) the DEUNA/DELUA driver. No ...



details:   https://anonhg.NetBSD.org/src/rev/960c90062497
branches:  trunk
changeset: 485520:960c90062497
user:      ragge <ragge%NetBSD.org@localhost>
date:      Sun Apr 30 11:43:26 2000 +0000

description:
Rewritten (most of) the DEUNA/DELUA driver. No more data copy, packet
header fiddling and forget driver support for trailers.

diffstat:

 sys/dev/qbus/if_de.c    |  828 ++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/qbus/if_dereg.h |  227 +++++++++++++
 2 files changed, 1055 insertions(+), 0 deletions(-)

diffs (truncated from 1063 to 300 lines):

diff -r e4f1b51a2c90 -r 960c90062497 sys/dev/qbus/if_de.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/qbus/if_de.c      Sun Apr 30 11:43:26 2000 +0000
@@ -0,0 +1,828 @@
+/*     $NetBSD: if_de.c,v 1.1 2000/04/30 11:43:26 ragge Exp $  */
+
+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *     @(#)if_de.c     7.12 (Berkeley) 12/16/90
+ */
+
+/*
+ * DEC DEUNA interface
+ *
+ *     Lou Salkind
+ *     New York University
+ *
+ *     Rewritten by Ragge 000430 to match new world.
+ *
+ * TODO:
+ *     timeout routine (get statistics)
+ */
+
+#include "opt_inet.h"
+#include "opt_iso.h"
+#include "opt_ns.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/buf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+#include <sys/device.h>
+
+#include <net/if.h>
+#include <net/if_ether.h>
+#include <net/if_dl.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#endif
+
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#ifdef ISO
+#include <netiso/iso.h>
+#include <netiso/iso_var.h>
+extern char all_es_snpa[], all_is_snpa[];
+#endif
+
+#include <machine/bus.h>
+
+#include <dev/qbus/ubavar.h>
+#include <dev/qbus/if_dereg.h>
+
+#include "ioconf.h"
+
+/*
+ * Be careful with transmit/receive buffers, each entry steals 4 map
+ * registers, and there is only 496 on one unibus...
+ */
+#define NRCV   10      /* number of receive buffers (must be > 1) */
+#define NXMT   20      /* number of transmit buffers */
+#define NFRAGS 8       /* Number of frags per transmit buffer */
+
+/*
+ * Structure containing the elements that must be in DMA-safe memory.
+ */
+struct de_cdata {
+       /* the following structures are always mapped in */
+       struct  de_pcbb dc_pcbb;        /* port control block */
+       struct  de_ring dc_xrent[NXMT]; /* transmit ring entrys */
+       struct  de_ring dc_rrent[NRCV]; /* receive ring entrys */
+       struct  de_udbbuf dc_udbbuf;    /* UNIBUS data buffer */
+       /* end mapped area */
+};
+
+/*
+ * Ethernet software status per interface.
+ *
+ * Each interface is referenced by a network interface structure,
+ * ds_if, which the routing code uses to locate the interface.
+ * This structure contains the output queue for the interface, its address, ...
+ * We also have, for each interface, a UBA interface structure, which
+ * contains information about the UNIBUS resources held by the interface:
+ * map registers, buffered data paths, etc.  Information is cached in this
+ * structure for use by the if_uba.c routines in running the interface
+ * efficiently.
+ */
+struct de_softc {
+       struct  device sc_dev;          /* Configuration common part */
+       struct  ethercom sc_ec;         /* Ethernet common part */
+#define sc_if  sc_ec.ec_if             /* network-visible interface */
+       int     sc_flags;
+#define DSF_RUNNING    2               /* board is enabled */
+#define DSF_SETADDR    4               /* physical address is changed */
+       bus_space_tag_t sc_iot;
+       bus_addr_t sc_ioh;
+       bus_dma_tag_t sc_dmat;
+       struct de_cdata *sc_dedata;     /* Control structure */
+       struct de_cdata *sc_pdedata;    /* Bus-mapped control structure */
+       bus_dmamap_t sc_xmtmap[NXMT];   /* unibus receive maps */
+       bus_dmamap_t sc_rcvmap[NRCV];   /* unibus xmt maps */
+       struct mbuf *sc_txmbuf[NXMT];
+       struct mbuf *sc_rxmbuf[NRCV];
+       int sc_nexttx;
+       int sc_nextrx;
+       int sc_inq;
+       int sc_lastack;
+};
+
+static int dematch(struct device *, struct cfdata *, void *);
+static void deattach(struct device *, struct device *, void *);
+static int dewait(struct de_softc *, char *);
+static void deinit(struct de_softc *);
+static int deioctl(struct ifnet *, u_long, caddr_t);
+static void dereset(struct device *);
+static void destart(struct ifnet *);
+static void derecv(struct de_softc *);
+static void dexmit(struct de_softc *);
+static void de_setaddr(u_char *, struct de_softc *);
+static void deintr(void *);
+static int de_add_rxbuf(struct de_softc *, int);
+
+struct cfattach de_ca = {
+       sizeof(struct de_softc), dematch, deattach
+};
+
+#define DE_WCSR(csr, val) \
+       bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
+#define DE_WLOW(val) \
+       bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val)
+#define DE_WHIGH(val) \
+       bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val)
+#define DE_RCSR(csr) \
+       bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)
+
+#define LOWORD(x)      ((int)(x) & 0xffff)
+#define HIWORD(x)      (((int)(x) >> 16) & 0x3)
+/*
+ * Interface exists: make available by filling in network interface
+ * record.  System will initialize the interface when it is ready
+ * to accept packets.  We get the ethernet address here.
+ */
+void
+deattach(struct device *parent, struct device *self, void *aux)
+{
+       struct uba_attach_args *ua = aux;
+       struct de_softc *sc = (struct de_softc *)self;
+       struct ifnet *ifp = &sc->sc_if;
+       u_int8_t myaddr[ETHER_ADDR_LEN];
+       bus_dma_segment_t seg;
+       int csr1, rseg, error, i;
+       char *c;
+
+       sc->sc_iot = ua->ua_iot;
+       sc->sc_ioh = ua->ua_ioh;
+       sc->sc_dmat = ua->ua_dmat;
+
+       /*
+        * What kind of a board is this?
+        * The error bits 4-6 in pcsr1 are a device id as long as
+        * the high byte is zero.
+        */
+       csr1 = DE_RCSR(DE_PCSR1);
+       if (csr1 & 0xff60)
+               c = "broken";
+       else if (csr1 & 0x10)
+               c = "delua";
+       else
+               c = "deuna";
+
+       /*
+        * Reset the board and temporarily map
+        * the pcbb buffer onto the Unibus.
+        */
+       DE_WCSR(DE_PCSR0, 0);           /* reset INTE */
+       DELAY(100);
+       DE_WCSR(DE_PCSR0, PCSR0_RSET);
+       (void)dewait(sc, "reset");
+
+       if ((error = bus_dmamem_alloc(sc->sc_dmat,
+           sizeof(struct de_cdata), NBPG, 0, &seg, 1, &rseg,
+           BUS_DMA_NOWAIT)) != 0) {
+               printf(": unable to allocate control data, error = %d\n",
+                   error);
+               goto fail_0;
+       }
+       if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
+           sizeof(struct de_cdata), (caddr_t *)&sc->sc_dedata,
+           BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
+               printf(": unable to map control data, error = %d\n", error);
+               goto fail_1;
+       }
+
+       /*
+        * Create the transmit descriptor DMA maps.
+        *
+        * XXX - should allocate transmit map pages when needed, not here.
+        */
+       for (i = 0; i < NXMT; i++) {
+               if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, NFRAGS,
+                   MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
+                   &sc->sc_xmtmap[i]))) {
+                       printf(": unable to create tx DMA map %d, error = %d\n",
+                           i, error);
+                       goto fail_4;
+               }
+       }
+
+       /*
+        * Create receive buffer DMA maps.
+        */
+       for (i = 0; i < NRCV; i++) {
+               if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
+                   MCLBYTES, 0, BUS_DMA_NOWAIT,
+                   &sc->sc_rcvmap[i]))) {
+                       printf(": unable to create rx DMA map %d, error = %d\n",
+                           i, error);
+                       goto fail_5;
+               }
+       }
+
+       /*
+        * Pre-allocate the receive buffers.
+        */
+       for (i = 0; i < NRCV; i++) {
+               if ((error = de_add_rxbuf(sc, i)) != 0) {
+                       printf(": unable to allocate or map rx buffer %d\n,"
+                           " error = %d\n", i, error);
+                       goto fail_6;
+               }
+       }
+
+       bzero(sc->sc_dedata, sizeof(struct de_cdata));
+       sc->sc_pdedata = (struct de_cdata *)seg.ds_addr;
+
+       /*
+        * Tell the DEUNA about our PCB
+        */
+       DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata));
+       DE_WCSR(DE_PCSR3, HIWORD(sc->sc_pdedata));
+       DE_WLOW(CMD_GETPCBB);
+       (void)dewait(sc, "pcbb");
+
+       sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD;
+       DE_WLOW(CMD_GETCMD);
+       (void)dewait(sc, "read addr ");
+
+       bcopy((caddr_t)&sc->sc_dedata->dc_pcbb.pcbb2, myaddr, sizeof (myaddr));
+       printf("%s: %s, hardware address %s\n", c, sc->sc_dev.dv_xname,
+               ether_sprintf(myaddr));
+
+       uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc);
+       uba_reset_establish(dereset, &sc->sc_dev);
+
+       strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
+       ifp->if_softc = sc;
+       ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
+       ifp->if_ioctl = deioctl;



Home | Main Index | Thread Index | Old Index