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