Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Enormous pile of changes from mark's (uncommitted...



details:   https://anonhg.NetBSD.org/src/rev/bee003268a9d
branches:  trunk
changeset: 507537:bee003268a9d
user:      bjh21 <bjh21%NetBSD.org@localhost>
date:      Sat Mar 24 20:38:41 2001 +0000

description:
Enormous pile of changes from mark's (uncommitted) work on this driver.
About the only bit of his code not here is the transmit routines, which I'll
merge in separately.

Also a few bug-fixes, so (for instance) multicast on an 8005 doesn't
immediately fall back to IFF_ALLMULTI.

diffstat:

 sys/dev/ic/seeq8005.c    |  503 ++++++++++++++++++++++++++++++++--------------
 sys/dev/ic/seeq8005var.h |   35 ++-
 2 files changed, 374 insertions(+), 164 deletions(-)

diffs (truncated from 939 to 300 lines):

diff -r 10e4563f2ef5 -r bee003268a9d sys/dev/ic/seeq8005.c
--- a/sys/dev/ic/seeq8005.c     Sat Mar 24 19:40:51 2001 +0000
+++ b/sys/dev/ic/seeq8005.c     Sat Mar 24 20:38:41 2001 +0000
@@ -1,8 +1,8 @@
-/* $NetBSD: seeq8005.c,v 1.10 2001/03/24 13:40:41 bjh21 Exp $ */
+/* $NetBSD: seeq8005.c,v 1.11 2001/03/24 20:38:41 bjh21 Exp $ */
 
 /*
  * Copyright (c) 2000 Ben Harris
- * Copyright (c) 1995 Mark Brinicombe
+ * Copyright (c) 1995-1998 Mark Brinicombe
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -15,7 +15,8 @@
  *    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 Mark Brinicombe.
+ *     This product includes software developed by Mark Brinicombe
+ *     for the NetBSD Project.
  * 4. The name of the company nor the name of the author may be used to
  *    endorse or promote products derived from this software without specific
  *    prior written permission.
@@ -40,15 +41,20 @@
  * SEEQ 8005 Advanced Ethernet Data Link Controller
  */
 /*
+ * More information on the 8004 and 8005 AEDLC controllers can be found in
+ * the SEEQ Technology Inc 1992 Data Comm Devices data book.
+ *
+ * This data book may no longer be available as these are rather old chips
+ * (1991 - 1993)
+ */
+/*
  * This driver is based on the arm32 ea(4) driver, hence the names of many
  * of the functions.
  */
 /*
  * Bugs/possible improvements:
  *     - Does not currently support DMA
- *     - Does not currently support multicasts
  *     - Does not transmit multiple packets in one go
- *     - Does not support big-endian hosts
  *     - Does not support 8-bit busses
  */
 
@@ -58,7 +64,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 
-__RCSID("$NetBSD: seeq8005.c,v 1.10 2001/03/24 13:40:41 bjh21 Exp $");
+__RCSID("$NetBSD: seeq8005.c,v 1.11 2001/03/24 20:38:41 bjh21 Exp $");
 
 #include <sys/systm.h>
 #include <sys/endian.h>
@@ -73,6 +79,7 @@
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/if_ether.h>
+#include <net/if_media.h>
 
 #ifdef INET
 #include <netinet/in.h>
@@ -99,24 +106,24 @@
 #include <dev/ic/seeq8005reg.h>
 #include <dev/ic/seeq8005var.h>
 
-#ifndef SEEQ_TIMEOUT
-#define SEEQ_TIMEOUT   60
-#endif
-
-#define SEEQ_TX_BUFFER_SIZE    0x4000
-#define SEEQ_RX_BUFFER_SIZE    0xC000
-
-/*#define SEEQ_TX_DEBUG*/
-/*#define SEEQ_RX_DEBUG*/
 /*#define SEEQ_DEBUG*/
-/*#define SEEQ_PACKET_DEBUG*/
 
 /* for debugging convenience */
 #ifdef SEEQ_DEBUG
-#define dprintf(x) printf x
+#define SEEQ_DEBUG_MISC                1
+#define SEEQ_DEBUG_TX          2
+#define SEEQ_DEBUG_RX          4
+#define SEEQ_DEBUG_PKT         8
+#define SEEQ_DEBUG_TXINT       16
+#define SEEQ_DEBUG_RXINT       32
+int seeq_debug = 0;
+#define DPRINTF(f, x) { if (seeq_debug & (f)) printf x; }
 #else
-#define dprintf(x)
+#define DPRINTF(f, x)
 #endif
+#define dprintf(x) DPRINTF(SEEQ_DEBUG_MISC, x)
+
+#define        SEEQ_TX_BUFFER_SIZE             0x600           /* (> MAX_ETHER_LEN) */
 
 /*
  * prototypes
@@ -133,74 +140,33 @@
 static void ea_stop(struct ifnet *, int);
 static void ea_await_fifo_empty(struct seeq8005_softc *);
 static void ea_await_fifo_full(struct seeq8005_softc *);
-static void ea_writebuf(struct seeq8005_softc *, u_char *, u_int, size_t);
-static void ea_readbuf(struct seeq8005_softc *, u_char *, u_int, size_t);
+static void ea_writebuf(struct seeq8005_softc *, u_char *, int, size_t);
+static void ea_readbuf(struct seeq8005_softc *, u_char *, int, size_t);
 static void ea_select_buffer(struct seeq8005_softc *, int);
 static void ea_set_address(struct seeq8005_softc *, int, const u_int8_t *);
-static void earead(struct seeq8005_softc *, int, int);
-static struct mbuf *eaget(struct seeq8005_softc *, int, int, struct ifnet *);
-static void eagetpackets(struct seeq8005_softc *);
+static void ea_read(struct seeq8005_softc *, int, int);
+static struct mbuf *ea_get(struct seeq8005_softc *, int, int, struct ifnet *);
+static void ea_getpackets(struct seeq8005_softc *);
 static void eatxpacket(struct seeq8005_softc *);
 static void ea_mc_reset(struct seeq8005_softc *);
-
-
-#ifdef SEEQ_PACKET_DEBUG
-void ea_dump_buffer(struct seeq8005_softc *, int);
-#endif
-
-
-#ifdef SEEQ_PACKET_DEBUG
-/*
- * Dump the interface buffer
- */
-
-void
-ea_dump_buffer(struct seeq8005_softc *sc, u_int offset)
-{
-       bus_space_tag_t iot = sc->sc_iot;
-       bus_space_handle_t ioh = sc->sc_ioh;
-       u_int addr;
-       int loop, ctrl, ptr;
-       size_t size;
-       
-       addr = offset;
+static void ea_mc_reset_8004(struct seeq8005_softc *);
+static void ea_mc_reset_8005(struct seeq8005_softc *);
+static int ea_mediachange(struct ifnet *);
+static void ea_mediastatus(struct ifnet *, struct ifmediareq *);
 
-       do {
-               bus_space_write_2(iot, ioh, SEEQ_COMMAND,
-                                sc->sc_command | SEEQ_CMD_FIFO_READ);
-               bus_space_write_2(iot, ioh, SEEQ_CONFIG1,
-                                 sc->sc_config1 | SEEQ_BUFCODE_LOCAL_MEM);
-               bus_space_write_2(iot, ioh, SEEQ_DMA_ADDR, addr);
-
-               ptr = bus_space_read_2(iot, ioh, SEEQ_BUFWIN);
-               ctrl = bus_space_read_2(iot, ioh, SEEQ_BUFWIN);
-               ptr = ((ptr & 0xff) << 8) | ((ptr >> 8) & 0xff);
-
-               if (ptr == 0) break;
-               size = ptr - addr;
-
-               printf("addr=%04x size=%04x ", addr, size);
-               printf("cmd=%02x st=%02x\n", ctrl & 0xff, ctrl >> 8);
-
-               for (loop = 0; loop < size - 4; loop += 2)
-                       printf("%04x ",
-                              bus_space_read_2(iot, ioh, SEEQ_BUFWIN));
-               printf("\n");
-               addr = ptr;
-       } while (size != 0);
-}
-#endif
 
 /*
  * Attach chip.
  */
 
 void
-seeq8005_attach(struct seeq8005_softc *sc, const u_int8_t *myaddr)
+seeq8005_attach(struct seeq8005_softc *sc, const u_int8_t *myaddr, int *media,
+    int nmedia, int defmedia)
 {
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
        u_int id;
 
+       KASSERT(myaddr != NULL);
        printf(" address %s", ether_sprintf(myaddr));
 
        /* Stop the board. */
@@ -212,11 +178,51 @@
        ea_select_buffer(sc, SEEQ_BUFCODE_PRODUCTID);
        id = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SEEQ_BUFWIN);
 
-       if ((id & 0xf0) == 0xa0) {
-               sc->sc_flags |= SEEQ8005_80C04;
-               printf(", SEEQ 80C04 rev %02x", id);
-       } else
-               printf(", SEEQ 8005");
+       switch (id & SEEQ_PRODUCTID_MASK) {
+       case SEEQ_PRODUCTID_8004:
+               sc->sc_variant = SEEQ_8004;
+               break;
+       default:        /* XXX */
+               sc->sc_variant = SEEQ_8005;
+               break;
+       }
+
+       switch (sc->sc_variant) {
+       case SEEQ_8004:
+               printf(", SEEQ80C04 rev %x\n",
+                   id & SEEQ_PRODUCTID_REV_MASK);
+               break;
+       case SEEQ_8005:
+               if (id != 0xff)
+                       printf(", SEEQ8005 rev %x\n", id);
+               else
+                       printf(", SEEQ8005\n");
+               break;
+       default:
+               printf(", Unknown ethernet controller\n");
+               return;
+       }
+
+       /* Both the 8004 and 8005 are designed for 64K Buffer memory */
+       sc->sc_buffersize = SEEQ_MAX_BUFFER_SIZE;
+
+       /*
+        * Set up tx and rx buffers.
+        *
+        * We use approximately a third of the packet memory for TX
+        * buffers and the rest for RX buffers
+        */
+       sc->sc_tx_bufs = sc->sc_buffersize / SEEQ_TX_BUFFER_SIZE / 3;   
+       sc->sc_tx_bufsize = sc->sc_tx_bufs * SEEQ_TX_BUFFER_SIZE;
+       sc->sc_rx_bufsize = sc->sc_buffersize - sc->sc_tx_bufsize;
+       sc->sc_enabled = 0;
+
+       /* Test the RAM */
+       ea_ramtest(sc);
+
+       printf("%s: %dKB packet memory, txbuf=%dKB (%d buffers), rxbuf=%dKB",
+           sc->sc_dev.dv_xname, sc->sc_buffersize >> 10,
+           sc->sc_tx_bufsize >> 10, sc->sc_tx_bufs, sc->sc_rx_bufsize >> 10); 
 
        /* Initialise ifnet structure. */
 
@@ -228,19 +234,61 @@
        ifp->if_stop = ea_stop;
        ifp->if_watchdog = ea_watchdog;
        ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
+       if (sc->sc_variant == SEEQ_8004)
+               ifp->if_flags |= IFF_SIMPLEX;
        IFQ_SET_READY(&ifp->if_snd);
 
+       /* Initialize media goo. */
+       ifmedia_init(&sc->sc_media, 0, ea_mediachange, ea_mediastatus);
+       if (media != NULL) {
+               int i;
+
+               for (i = 0; i < nmedia; i++)
+                       ifmedia_add(&sc->sc_media, media[i], 0, NULL);
+               ifmedia_set(&sc->sc_media, defmedia);
+       } else {
+               ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
+               ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
+       }
+
        /* Now we can attach the interface. */
 
        if_attach(ifp);
        ether_ifattach(ifp, myaddr);
 
-       /* Test the RAM */
-       ea_ramtest(sc);
-
        printf("\n");
 }
 
+/*
+ * Media change callback.
+ */
+static int
+ea_mediachange(struct ifnet *ifp)
+{
+       struct seeq8005_softc *sc = ifp->if_softc;
+
+       if (sc->sc_mediachange)
+               return ((*sc->sc_mediachange)(sc));
+       return (EINVAL);
+}
+
+/*
+ * Media status callback.
+ */
+static void
+ea_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+       struct seeq8005_softc *sc = ifp->if_softc;
+
+       if (sc->sc_enabled == 0) {
+               ifmr->ifm_active = IFM_ETHER | IFM_NONE;



Home | Main Index | Thread Index | Old Index