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