Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic HME ethernet driver.
details: https://anonhg.NetBSD.org/src/rev/ac72f39aace2
branches: trunk
changeset: 474062:ac72f39aace2
user: pk <pk%NetBSD.org@localhost>
date: Sun Jun 27 12:26:32 1999 +0000
description:
HME ethernet driver.
Note: this is work in progress; needs testing and tweaking. mgr has
promised to do that..
diffstat:
sys/dev/ic/hme.c | 1281 +++++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/ic/hmereg.h | 294 +++++++++++
sys/dev/ic/hmevar.h | 106 ++++
3 files changed, 1681 insertions(+), 0 deletions(-)
diffs (truncated from 1693 to 300 lines):
diff -r aa6923f0e10a -r ac72f39aace2 sys/dev/ic/hme.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/hme.c Sun Jun 27 12:26:32 1999 +0000
@@ -0,0 +1,1281 @@
+/* $NetBSD: hme.c,v 1.1 1999/06/27 12:26:32 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * HME Ethernet module driver.
+ */
+
+#define HMEDEBUG
+
+#include "opt_inet.h"
+#include "opt_ccitt.h"
+#include "opt_llc.h"
+#include "opt_ns.h"
+#include "bpfilter.h"
+#include "rnd.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/syslog.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#if NRND > 0
+#include <sys/rnd.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_ether.h>
+#include <net/if_media.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+#endif
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <machine/bus.h>
+
+#include <dev/ic/hmereg.h>
+#include <dev/ic/hmevar.h>
+
+void hme_start __P((struct ifnet *));
+void hme_stop __P((struct hme_softc *));
+int hme_ioctl __P((struct ifnet *, u_long, caddr_t));
+void hme_watchdog __P((struct ifnet *));
+void hme_shutdown __P((void *));
+void hme_init __P((struct hme_softc *));
+void hme_meminit __P((struct hme_softc *));
+void hme_reset __P((struct hme_softc *));
+void hme_setladrf __P((struct hme_softc *));
+
+/* MII methods & callbacks */
+static int hme_mii_readreg __P((struct device *, int, int));
+static void hme_mii_writereg __P((struct device *, int, int, int));
+static void hme_mii_statchg __P((struct device *));
+
+int hme_mediachange __P((struct ifnet *));
+void hme_mediastatus __P((struct ifnet *, struct ifmediareq *));
+
+struct mbuf *hme_get __P((struct hme_softc *, int, int));
+int hme_put __P((struct hme_softc *, int, struct mbuf *));
+void hme_read __P((struct hme_softc *, int, int));
+int hme_eint __P((struct hme_softc *, u_int));
+int hme_rint __P((struct hme_softc *));
+int hme_tint __P((struct hme_softc *));
+
+static int ether_cmp __P((u_char *, u_char *));
+
+/* Default buffer copy routines */
+void hme_copytobuf_contig __P((struct hme_softc *, void *, int, int));
+void hme_copyfrombuf_contig __P((struct hme_softc *, void *, int, int));
+void hme_zerobuf_contig __P((struct hme_softc *, int, int));
+
+
+void
+hme_config(sc)
+ struct hme_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ struct mii_data *mii = &sc->sc_mii;
+ bus_dma_segment_t seg;
+ bus_size_t size;
+ int rseg, error;
+
+ /*
+ * HME common initialization.
+ *
+ * hme_softc fields that must be initialized by the front-end:
+ *
+ * the bus tag:
+ * sc_bustag
+ *
+ * the dma bus tag:
+ * sc_dmatag
+ *
+ * the bus handles:
+ * sc_seb (Shared Ethernet Block registers)
+ * sc_erx (Receiver Unit registers)
+ * sc_etx (Transmitter Unit registers)
+ * sc_mac (MAC registers)
+ * sc_mif (Managment Interface registers)
+ *
+ * the maximum bus burst size:
+ * sc_burst
+ *
+ * (notyet:DMA capable memory for the ring descriptors & packet buffers:
+ * rb_membase, rb_dmabase)
+ *
+ * the local Ethernet address:
+ * sc_enaddr
+ *
+ */
+
+ /* Make sure the chip is stopped. */
+ hme_stop(sc);
+
+
+ /*
+ * Allocate descriptors and buffers
+ * XXX - do all this differently.. and more configurably,
+ * eg. use things as `dma_load_mbuf()' on transmit,
+ * and a pool of `EXTMEM' mbufs (with buffers DMA-mapped
+ * all the time) on the reveiver side.
+ */
+#define _HME_NDESC 32
+#define _HME_BUFSZ 32
+
+ /* Note: the # of descriptors must be a multiple of 16 */
+ sc->sc_rb.rb_ntbuf = _HME_NDESC;
+ sc->sc_rb.rb_nrbuf = _HME_NDESC;
+
+ /*
+ * Allocate DMA capable memory
+ * Buffer descriptors must be aligned on a 2048 byte boundary;
+ * take this into account when calculating the size. Note that
+ * the maximum number of descriptors (256) occupies 2048 bytes,
+ * so we allocate that much regardless of _HME_NDESC.
+ */
+ size = 2048 + /* TX descriptors */
+ 2048 + /* RX descriptors */
+ sc->sc_rb.rb_ntbuf * _HME_BUFSZ + /* TX buffers */
+ sc->sc_rb.rb_nrbuf * _HME_BUFSZ; /* TX buffers */
+ if ((error = bus_dmamem_alloc(sc->sc_dmatag, size,
+ 2048, 0,
+ &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
+ printf("%s: DMA buffer alloc error %d\n",
+ sc->sc_dev.dv_xname, error);
+ }
+ sc->sc_rb.rb_dmabase = seg.ds_addr;
+
+ /* Map DMA memory in CPU adressable space */
+ if ((error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg, size,
+ &sc->sc_rb.rb_membase,
+ BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
+ printf("%s: DMA buffer map error %d\n",
+ sc->sc_dev.dv_xname, error);
+ bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
+ return;
+ }
+
+#if 0
+ /*
+ * Install default copy routines if not supplied.
+ */
+ if (sc->sc_copytobuf == NULL)
+ sc->sc_copytobuf = hme_copytobuf_contig;
+
+ if (sc->sc_copyfrombuf == NULL)
+ sc->sc_copyfrombuf = hme_copyfrombuf_contig;
+#endif
+
+ /* Initialize ifnet structure. */
+ bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
+ ifp->if_softc = sc;
+ ifp->if_start = hme_start;
+ ifp->if_ioctl = hme_ioctl;
+ ifp->if_watchdog = hme_watchdog;
+ ifp->if_flags =
+ IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
+
+ /* Initialize ifmedia structures and MII info */
+ mii->mii_ifp = ifp;
+ mii->mii_readreg = hme_mii_readreg;
+ mii->mii_writereg = hme_mii_writereg;
+ mii->mii_statchg = hme_mii_statchg;
+
+ ifmedia_init(&mii->mii_media, 0, hme_mediachange, hme_mediastatus);
+
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ /* No PHY attached */
+ ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
+ ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
+ } else {
+ /*
+ * XXX - we can really do the following ONLY if the
+ * phy indeed has the auto negotiation capability!!
+ */
+ ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
+ }
+
+ /* Attach the interface. */
+ if_attach(ifp);
+ ether_ifattach(ifp, sc->sc_enaddr);
+
+#if NBPFILTER > 0
+ bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+#endif
+
+ printf(": address %s\n", ether_sprintf(sc->sc_enaddr));
+
+ sc->sc_sh = shutdownhook_establish(hme_shutdown, sc);
+ if (sc->sc_sh == NULL)
+ panic("hme_config: can't establish shutdownhook");
+
+#if 0
+ printf("%s: %d receive buffers, %d transmit buffers\n",
+ sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf);
+ sc->sc_rbufaddr = malloc(sc->sc_nrbuf * sizeof(int), M_DEVBUF,
+ M_WAITOK);
+ sc->sc_tbufaddr = malloc(sc->sc_ntbuf * sizeof(int), M_DEVBUF,
+ M_WAITOK);
+#endif
+
+#if NRND > 0
+ rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
+ RND_TYPE_NET, 0);
+#endif
+}
+
+void
+hme_reset(sc)
+ struct hme_softc *sc;
+{
+ int s;
+
+ s = splnet();
+ hme_init(sc);
+ splx(s);
+}
+
+void
+hme_stop(sc)
Home |
Main Index |
Thread Index |
Old Index