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