summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/bsp.h4
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in2
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/sonic/dmvsonic.c114
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in2
-rw-r--r--c/src/lib/libchip/Makefile.in6
-rw-r--r--c/src/lib/libchip/network/Makefile.in57
-rw-r--r--c/src/lib/libchip/network/README16
-rw-r--r--c/src/lib/libchip/network/README.sonic21
-rw-r--r--c/src/lib/libchip/network/sonic.c1629
-rw-r--r--c/src/lib/libchip/network/sonic.h416
-rw-r--r--c/src/lib/wrapup/Makefile.in1
-rw-r--r--c/src/libchip/network/Makefile.in57
-rw-r--r--c/src/libchip/network/README16
-rw-r--r--c/src/libchip/network/README.sonic21
-rw-r--r--c/src/libchip/network/sonic.c (renamed from c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c)192
-rw-r--r--c/src/libchip/network/sonic.h (renamed from c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h)71
-rw-r--r--c/src/wrapup/Makefile.in1
17 files changed, 2445 insertions, 181 deletions
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h b/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h
index 34d15e59df..d0c5574348 100644
--- a/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h
@@ -48,9 +48,9 @@ extern "C" {
* Network driver configuration
*/
struct rtems_bsdnet_ifconfig;
-extern int rtems_sonic_driver_attach (struct rtems_bsdnet_ifconfig *config);
+int rtems_dmv177_sonic_driver_attach(struct rtems_bsdnet_ifconfig *config);
#define RTEMS_BSP_NETWORK_DRIVER_NAME "sonic1"
-#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_sonic_driver_attach
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dmv177_sonic_driver_attach
/*
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in
index b6c1bed0c4..bad013f7a2 100644
--- a/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in
+++ b/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in
@@ -8,7 +8,7 @@ VPATH = @srcdir@
RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
-PGM=${ARCH}/sonic.rel
+PGM=${ARCH}/dmvsonic.rel
# C source names, if any, go here -- minus the .c
C_PIECES=sonic
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/dmvsonic.c b/c/src/lib/libbsp/powerpc/dmv177/sonic/dmvsonic.c
new file mode 100644
index 0000000000..a068c74f31
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/sonic/dmvsonic.c
@@ -0,0 +1,114 @@
+/*
+ * DMV177 SONIC Configuration Information
+ *
+ * References:
+ *
+ * 1) SVME/DMV-171 Single Board Computer Documentation Package, #805905,
+ * DY 4 Systems Inc., Kanata, Ontario, September, 1996.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/rtems_bsdnet.h>
+#include <libchip/sonic.h>
+
+void dmv177_sonic_write_register(
+ void *base,
+ unsigned32 regno,
+ unsigned32 value
+)
+{
+ volatile unsigned32 *p = base;
+
+#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
+ printf( "%p Write 0x%04x to %s (0x%02x)\n",
+ &p[regno], value, SONIC_Reg_name[regno], regno );
+ fflush( stdout );
+#endif
+ p[regno] = value;
+}
+
+unsigned32 dmv177_sonic_read_register(
+ void *base,
+ unsigned32 regno
+)
+{
+ volatile unsigned32 *p = base;
+ unsigned32 value;
+
+ value = p[regno];
+#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
+ printf( "%p Read 0x%04x from %s (0x%02x)\n",
+ &p[regno], value, SONIC_Reg_name[regno], regno );
+ fflush( stdout );
+#endif
+ return value;
+}
+
+/*
+ * Default sizes of transmit and receive descriptor areas
+ */
+#define RDA_COUNT 20 /* 20 */
+#define TDA_COUNT 20 /* 10 */
+
+/*
+ * Default device configuration register values
+ * Conservative, generic values.
+ * DCR:
+ * No extended bus mode
+ * Unlatched bus retry
+ * Programmable outputs unused
+ * Asynchronous bus mode
+ * User definable pins unused
+ * No wait states (access time controlled by DTACK*)
+ * 32-bit DMA
+ * Empty/Fill DMA mode
+ * Maximum Transmit/Receive FIFO
+ * DC2:
+ * Extended programmable outputs unused
+ * Normal HOLD request
+ * Packet compress output unused
+ * No reject on CAM match
+ */
+#define SONIC_DCR \
+ (DCR_DW32 | DCR_WAIT0 | DCR_PO0 | DCR_PO1 | DCR_RFT24 | DCR_TFT28)
+#ifndef SONIC_DCR
+# define SONIC_DCR (DCR_DW32 | DCR_TFT28)
+#endif
+#ifndef SONIC_DC2
+# define SONIC_DC2 (0)
+#endif
+
+/*
+ * Default location of device registers
+ */
+#ifndef SONIC_BASE_ADDRESS
+# define SONIC_BASE_ADDRESS 0xF3000000
+# warning "Using default SONIC_BASE_ADDRESS."
+#endif
+
+/*
+ * Default interrupt vector
+ */
+#ifndef SONIC_VECTOR
+# define SONIC_VECTOR 1
+# warning "Using default SONIC_VECTOR."
+#endif
+
+sonic_configuration_t dmv177_sonic_configuration = {
+ SONIC_BASE_ADDRESS, /* base address */
+ SONIC_VECTOR, /* vector number */
+ SONIC_DCR, /* DCR register value */
+ SONIC_DC2, /* DC2 register value */
+ TDA_COUNT, /* number of transmit descriptors */
+ RDA_COUNT, /* number of receive descriptors */
+ dmv177_sonic_write_register,
+ dmv177_sonic_read_register
+};
+
+int rtems_dmv177_sonic_driver_attach(struct rtems_bsdnet_ifconfig *config)
+{
+ return rtems_sonic_driver_attach( config, &dmv177_sonic_configuration );
+
+}
diff --git a/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in
index 7119536c6a..c5f0464a06 100644
--- a/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in
+++ b/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in
@@ -9,7 +9,7 @@ RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
# We only build the networking device driver if HAS_NETWORKING was defined
-NETWORKING_DRIVER_yes_V = sonic
+NETWORKING_DRIVER_yes_V = dmvsonic
NETWORKING_DRIVER = $(NETWORKING_DRIVER_$(HAS_NETWORKING)_V)
# pieces specific to this BSP
diff --git a/c/src/lib/libchip/Makefile.in b/c/src/lib/libchip/Makefile.in
index a5144ec02d..c1d0ffb462 100644
--- a/c/src/lib/libchip/Makefile.in
+++ b/c/src/lib/libchip/Makefile.in
@@ -11,4 +11,8 @@ PROJECT_ROOT = @PROJECT_ROOT@
include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
include $(RTEMS_ROOT)/make/directory.cfg
-SUB_DIRS=rtc serial
+# We only build the networking chip drivers if HAS_NETWORKING was defined
+LIBNETWORKING_yes_V = network
+LIBNETWORKING = $(LIBNETWORKING_$(HAS_NETWORKING)_V)
+
+SUB_DIRS=rtc serial $(LIBNETWORKING)
diff --git a/c/src/lib/libchip/network/Makefile.in b/c/src/lib/libchip/network/Makefile.in
new file mode 100644
index 0000000000..aaaf460aa1
--- /dev/null
+++ b/c/src/lib/libchip/network/Makefile.in
@@ -0,0 +1,57 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+LIBNAME=libnetchip.a
+LIB=${ARCH}/${LIBNAME}
+
+C_PIECES=\
+ sonic
+
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+INSTALLED_H_FILES=$(srcdir)/sonic.h
+SRCS=$(C_FILES) $(H_FILES) $(SYS_H_FILES) $(RTEMS_H_FILES) $(PRIVATE_H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/lib.cfg
+
+#
+# Add local stuff here using +=
+#
+
+DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
+ -DDIAGNOSTIC -DBOOTP_COMPAT
+CPPFLAGS +=
+CFLAGS += $(LIBC_DEFINES)
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS += $(LIB)
+CLOBBER_ADDITIONS +=
+
+all: ${ARCH} preinstall $(LIB)
+ $(INSTALL_VARIANT) -m 644 ${LIB} ${PROJECT_RELEASE}/lib
+
+$(LIB): $(SRCS) ${OBJS}
+ $(make-library)
+
+# Install the library, appending _g or _p as appropriate.
+# for include files, just use $(INSTALL)
+preinstall:
+ $(INSTALL) -m 444 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/libchip
+
+
diff --git a/c/src/lib/libchip/network/README b/c/src/lib/libchip/network/README
new file mode 100644
index 0000000000..fd5853ef16
--- /dev/null
+++ b/c/src/lib/libchip/network/README
@@ -0,0 +1,16 @@
+#
+# $Id$
+#
+
+This is the network interface controller portion of the libchip library.
+This directory contains the source code for reusable TCP/IP network driver
+support code. Each driver has its own configuration table and its
+chip specific attach routine must be called by a board specific
+attach routine. The board specific chip routine passes the chip
+configuration and network configuration to the resuable device driver.
+
+The reusable chip drivers do not directly access the controller.
+They access the registers on the controller via a set of
+functions which are provided by the BSP. These functions set and get
+general registers and data buffers.
+
diff --git a/c/src/lib/libchip/network/README.sonic b/c/src/lib/libchip/network/README.sonic
new file mode 100644
index 0000000000..ef9641d6a2
--- /dev/null
+++ b/c/src/lib/libchip/network/README.sonic
@@ -0,0 +1,21 @@
+#
+# $Id$
+#
+
+This SONIC driver does not make any attempt to support the SONIC chip
+in any of the following modes:
+
+ + 16-bit
+ + little endian
+
+It does not attempt to handle SONIC's older than Revision C. There is
+a bug in chips before that revision that must be handled in the driver.
+
+The configuration table should be discussed here but if you look in the
+include file for the sonic, it is reasonably obvious. :)
+
+The performance impact of transforming this driver into libchip format
+was minimal.
+
+The powerpc/dmv177 BSP uses this driver and can serve as an example
+configuration table.
diff --git a/c/src/lib/libchip/network/sonic.c b/c/src/lib/libchip/network/sonic.c
new file mode 100644
index 0000000000..2dd8e32e79
--- /dev/null
+++ b/c/src/lib/libchip/network/sonic.c
@@ -0,0 +1,1629 @@
+/*
+ * RTEMS NETWORK DRIVER FOR NATIONAL DP83932 `SONIC'
+ * SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER
+ *
+ * REUSABLE CHIP DRIVER
+ *
+ * References:
+ *
+ * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
+ * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
+ * 1995.
+ *
+ * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
+ * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
+ * RRD-B30M75, National Semiconductor, March, 1991.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <libchip/sonic.h>
+
+#include <stdio.h>
+
+#include <errno.h>
+#include <rtems/error.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+/*
+ * XXX fix this
+ */
+
+void *set_vector(void *, unsigned32, unsigned32);
+
+/*
+ * Debug levels
+ *
+ */
+
+#define SONIC_DEBUG_NONE 0x0000
+#define SONIC_DEBUG_ALL 0xFFFF
+#define SONIC_DEBUG_PRINT_REGISTERS 0x0001
+#define SONIC_DEBUG_MEMORY 0x0002
+#define SONIC_DEBUG_MEMORY_ALLOCATE 0x0004
+#define SONIC_DEBUG_MEMORY_DESCRIPTORS 0x0008
+#define SONIC_DEBUG_FRAGMENTS 0x0008
+#define SONIC_DEBUG_CAM 0x0010
+#define SONIC_DEBUG_DESCRIPTORS 0x0020
+#define SONIC_DEBUG_ERRORS 0x0040
+#define SONIC_DEBUG_DUMP_TX_MBUFS 0x0080
+#define SONIC_DEBUG_DUMP_RX_MBUFS 0x0100
+
+#define SONIC_DEBUG_DUMP_MBUFS \
+ (SONIC_DEBUG_DUMP_TX_MBUFS|SONIC_DEBUG_DUMP_RX_MBUFS)
+
+#define SONIC_DEBUG (SONIC_DEBUG_ERRORS)
+
+/*
+ ((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_PRINT_REGISTERS|SONIC_DEBUG_DUMP_MBUFS))
+ ((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_DUMP_MBUFS))
+*/
+
+
+#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_MBUFS)
+#include <rtems/dumpbuf.h>
+#endif
+
+/*
+ * Use the top line if you want more symbols.
+ */
+
+#define SONIC_STATIC
+/* #define SONIC_STATIC static */
+
+/*
+ * Number of devices supported by this driver
+ */
+#ifndef NSONIC
+# define NSONIC 1
+#endif
+
+/*
+ *
+ * As suggested by National Application Note 746, make the
+ * receive resource area bigger than the receive descriptor area.
+ *
+ * NOTE: Changing this may break this driver since it currently
+ * assumes a 1<->1 mapping.
+ */
+#define RRA_EXTRA_COUNT 0
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * RTEMS event used to start transmit daemon.
+ * This must not be the same as INTERRUPT_EVENT.
+ */
+#define START_TRANSMIT_EVENT RTEMS_EVENT_2
+
+/*
+ * Largest Ethernet frame.
+ */
+#define MAXIMUM_FRAME_SIZE 1518
+
+/*
+ * Receive buffer size.
+ * Allow for a pointer, plus a full ethernet frame (including Frame
+ * Check Sequence) rounded up to a 4-byte boundary.
+ */
+#define RBUF_SIZE ((sizeof (void *) + (MAXIMUM_FRAME_SIZE) + 3) & ~3)
+/* #define RBUF_WC ((((MAXIMUM_FRAME_SIZE) + 3) & ~3) / 2) */
+#define RBUF_WC (RBUF_SIZE / 2)
+
+/*
+ * Macros for manipulating 32-bit pointers as 16-bit fragments
+ */
+#define LSW(p) ((rtems_unsigned16)((rtems_unsigned32)(p)))
+#define MSW(p) ((rtems_unsigned16)((rtems_unsigned32)(p) >> 16))
+#define PTR(m,l) ((void*)(((rtems_unsigned16)(m)<<16)|(rtems_unsigned16)(l)))
+
+/*
+ * Hardware-specific storage
+ */
+struct sonic_softc {
+ /*
+ * Connection to networking code
+ * This entry *must* be the first in the sonic_softc structure.
+ */
+ struct arpcom arpcom;
+
+ /*
+ * Default location of device registers
+ * ===CACHE===
+ * This area must be non-cacheable, guarded.
+ */
+ void *sonic;
+
+ /*
+ * Register access routines
+ */
+ sonic_write_register_t write_register;
+ sonic_read_register_t read_register;
+
+ /*
+ * Interrupt vector
+ */
+ rtems_vector_number vector;
+
+ /*
+ * Data Configuration Register values
+ */
+ rtems_unsigned32 dcr_value;
+ rtems_unsigned32 dc2_value;
+
+ /*
+ * Indicates configuration
+ */
+ int acceptBroadcast;
+
+ /*
+ * Task waiting for interrupts
+ */
+ rtems_id rxDaemonTid;
+ rtems_id txDaemonTid;
+
+ /*
+ * Receive resource area
+ */
+ int rdaCount;
+ ReceiveResourcePointer_t rsa;
+ ReceiveResourcePointer_t rea;
+ CamDescriptorPointer_t cdp;
+ ReceiveDescriptorPointer_t rda;
+ ReceiveDescriptorPointer_t rdp_last;
+
+ /*
+ * Transmit descriptors
+ */
+ int tdaCount;
+ TransmitDescriptorPointer_t tdaHead; /* Last filled */
+ TransmitDescriptorPointer_t tdaTail; /* Next to retire */
+ int tdaActiveCount;
+
+ /*
+ * Statistics
+ */
+ unsigned long Interrupts;
+ unsigned long rxInterrupts;
+ unsigned long rxMissed;
+ unsigned long rxGiant;
+ unsigned long rxNonOctet;
+ unsigned long rxBadCRC;
+ unsigned long rxCollision;
+
+ unsigned long txInterrupts;
+ unsigned long txSingleCollision;
+ unsigned long txMultipleCollision;
+ unsigned long txCollision;
+ unsigned long txDeferred;
+ unsigned long txUnderrun;
+ unsigned long txLateCollision;
+ unsigned long txExcessiveCollision;
+ unsigned long txExcessiveDeferral;
+ unsigned long txLostCarrier;
+ unsigned long txRawWait;
+};
+SONIC_STATIC struct sonic_softc sonic_softc[NSONIC];
+
+
+/*
+ ******************************************************************
+ * *
+ * Debug Routines *
+ * *
+ ******************************************************************
+ */
+
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
+void sonic_print_tx_descriptor(
+ TransmitDescriptorPointer_t tdp
+)
+{
+ printf( "TXD ==> %p", tdp );
+ printf( " pkt_config = 0x%04x", tdp->pkt_config & 0xffff);
+ printf( " pkt_size = 0x%04x\n", tdp->pkt_size & 0xffff );
+ printf( " frag_count = %d", tdp->frag_count & 0xffff );
+ /* could print all the fragments */
+ printf( " next = %p", tdp->next );
+ printf( " linkp = %p\n", tdp->linkp );
+ printf( " mbufp = %p", tdp->mbufp );
+ if ( tdp->mbufp )
+ printf( " mbufp->data = %p", mtod ( tdp->mbufp, void *) );
+ puts("");
+}
+
+void sonic_print_rx_descriptor(
+ ReceiveDescriptorPointer_t rdp
+)
+{
+ printf( "RXD ==> %p\n", rdp );
+ printf( " status = 0x%04x", rdp->status & 0xffff );
+ printf( " byte_count = 0x%04x\n", rdp->byte_count & 0xffff );
+ printf( " pkt = 0x%04x%04x", rdp->pkt_msw, rdp->pkt_lsw );
+ printf( " seq_no = %d", rdp->seq_no );
+ printf( " link = %d\n", rdp->link );
+ printf( " in_use = %d", rdp->in_use );
+ printf( " next = %p", rdp->next );
+ printf( " mbufp = %p", rdp->mbufp );
+ if ( rdp->mbufp )
+ printf( " mbufp->data = %p", mtod ( rdp->mbufp, void *) );
+ puts("");
+}
+#endif
+
+/*
+ ******************************************************************
+ * *
+ * Support Routines *
+ * *
+ ******************************************************************
+ */
+
+void sonic_enable_interrupts(
+ struct sonic_softc *sc,
+ unsigned32 mask
+)
+{
+ void *rp = sc->sonic;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level );
+ (*sc->write_register)(
+ rp,
+ SONIC_REG_IMR,
+ (*sc->read_register)(rp, SONIC_REG_IMR) | mask
+ );
+ rtems_interrupt_enable( level );
+}
+
+/*
+ * Allocate non-cacheable memory on a single 64k page.
+ * Very simple minded -- just keeps trying till the memory is on a single page.
+ */
+SONIC_STATIC void * sonic_allocate(unsigned int nbytes)
+{
+ void *p;
+ unsigned long a1, a2;
+
+ for (;;) {
+ /*
+ * ===CACHE===
+ * Change malloc to malloc_noncacheable_guarded.
+ */
+ p = malloc( nbytes, M_MBUF, M_NOWAIT );
+ if (p == NULL)
+ rtems_panic ("No memory!");
+ memset (p, '\0', nbytes);
+ a1 = (unsigned long)p;
+ a2 = a1 + nbytes - 1;
+ if ((a1 >> 16) == (a2 >> 16))
+ break;
+ }
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_ALLOCATE)
+ printf( "sonic_allocate %d bytes at %p\n", nbytes, p );
+#endif
+ return p;
+}
+
+/*
+ * Shut down the interface.
+ */
+
+SONIC_STATIC void sonic_stop (struct sonic_softc *sc)
+{
+ void *rp = sc->sonic;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ ifp->if_flags &= ~IFF_RUNNING;
+
+ /*
+ * Stop the transmitter and receiver.
+ */
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_HTX | CR_RXDIS );
+}
+
+/*
+ * Show interface statistics
+ */
+SONIC_STATIC void sonic_stats (struct sonic_softc *sc)
+{
+ printf (" Total Interrupts:%-8lu", sc->Interrupts);
+ printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
+ printf (" Giant:%-8lu", sc->rxGiant);
+ printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
+ printf (" Bad CRC:%-8lu", sc->rxBadCRC);
+ printf (" Collision:%-8lu", sc->rxCollision);
+ printf (" Missed:%-8lu\n", sc->rxMissed);
+
+ printf ( " Tx Interrupts:%-8lu", sc->txInterrupts);
+ printf ( " Deferred:%-8lu", sc->txDeferred);
+ printf (" Lost Carrier:%-8lu\n", sc->txLostCarrier);
+ printf ( "Single Collisions:%-8lu", sc->txSingleCollision);
+ printf ( "Multiple Collisions:%-8lu", sc->txMultipleCollision);
+ printf ("Excessive Collisions:%-8lu\n", sc->txExcessiveCollision);
+ printf ( " Total Collisions:%-8lu", sc->txCollision);
+ printf ( " Late Collision:%-8lu", sc->txLateCollision);
+ printf (" Underrun:%-8lu\n", sc->txUnderrun);
+ printf ( " Raw output wait:%-8lu\n", sc->txRawWait);
+}
+
+/*
+ ******************************************************************
+ * *
+ * Interrupt Handler *
+ * *
+ ******************************************************************
+ */
+
+SONIC_STATIC rtems_isr sonic_interrupt_handler (rtems_vector_number v)
+{
+ struct sonic_softc *sc = sonic_softc;
+ unsigned32 isr, imr;
+ void *rp;
+
+#if (NSONIC > 1)
+ /*
+ * Find the device which requires service
+ */
+ for (;;) {
+ if (sc->vector == v)
+ break;
+ if (++sc == &sonic[NSONIC])
+ return; /* Spurious interrupt? */
+ }
+#endif /* NSONIC > 1 */
+
+ /*
+ * Get pointer to SONIC registers
+ */
+ rp = sc->sonic;
+
+ sc->Interrupts++;
+
+ isr = (*sc->read_register)( rp, SONIC_REG_ISR );
+ imr = (*sc->read_register)( rp, SONIC_REG_IMR );
+
+ /*
+ * Packet received or receive buffer area exceeded?
+ */
+ if ((imr & (IMR_PRXEN | IMR_RBAEEN)) &&
+ (isr & (ISR_PKTRX | ISR_RBAE))) {
+ imr &= ~(IMR_PRXEN | IMR_RBAEEN);
+ sc->rxInterrupts++;
+ rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
+ }
+
+ /*
+ * Packet started, transmitter done or transmitter error?
+ */
+ if ((imr & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN)) &&
+ (isr & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
+ imr &= ~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN);
+ sc->txInterrupts++;
+ rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
+ }
+
+ (*sc->write_register)( rp, SONIC_REG_IMR, imr );
+}
+
+/*
+ ******************************************************************
+ * *
+ * Transmitter Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Soak up transmit descriptors that have been sent.
+ */
+
+SONIC_STATIC void sonic_retire_tda (struct sonic_softc *sc)
+{
+ rtems_unsigned16 status;
+ unsigned int collisions;
+ struct mbuf *m, *n;
+
+ /*
+ * Repeat for all completed transmit descriptors.
+ */
+ while ((sc->tdaActiveCount != 0)
+ && ((status = sc->tdaTail->status) != 0)) {
+
+#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
+ printf( "retire TDA %p (0x%04x)\n", sc->tdaTail, status );
+#endif
+
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ /*
+ * If there is an error that was not a collision,
+ * then someone may want to see it.
+ */
+
+ if ( (status & ~(TDA_STATUS_COLLISION_MASK|TDA_STATUS_DEF)) != 0x0001 )
+ printf( "ERROR: retire TDA %p (0x%08x)\n",
+ sc->tdaTail, sc->tdaTail->status );
+#endif
+
+ /*
+ * Check for errors which stop the transmitter.
+ */
+ if (status & (TDA_STATUS_EXD |
+ TDA_STATUS_EXC |
+ TDA_STATUS_FU |
+ TDA_STATUS_BCM)) {
+ /*
+ * Restart the transmitter if there are
+ * packets waiting to go.
+ */
+ rtems_unsigned16 link;
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ printf("restarting sonic after error\n");
+#endif
+
+ link = *(sc->tdaTail->linkp);
+
+ if ((link & TDA_LINK_EOL) == 0) {
+ void *rp = sc->sonic;
+
+ (*sc->write_register)( rp, SONIC_REG_CTDA, link );
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_TXP );
+ }
+ }
+
+ /*
+ * Update network statistics
+ */
+ collisions = (status & TDA_STATUS_COLLISION_MASK) >> TDA_STATUS_COLLISION_SHIFT;
+ if (collisions) {
+ if (collisions == 1)
+ sc->txSingleCollision++;
+ else
+ sc->txMultipleCollision++;
+ sc->txCollision += collisions;
+ }
+ if (status & TDA_STATUS_EXC)
+ sc->txExcessiveCollision++;
+ if (status & TDA_STATUS_OWC)
+ sc->txLateCollision++;
+ if (status & TDA_STATUS_EXD)
+ sc->txExcessiveDeferral++;
+ if (status & TDA_STATUS_DEF)
+ sc->txDeferred++;
+ if (status & TDA_STATUS_FU)
+ sc->txUnderrun++;
+ if (status & TDA_STATUS_CRSL)
+ sc->txLostCarrier++;
+
+ /*
+ * Free the packet and reset a couple of fields
+ */
+ sc->tdaActiveCount--;
+ m = sc->tdaTail->mbufp;
+ while ( m ) {
+ MFREE(m, n);
+ m = n;
+ }
+
+ sc->tdaTail->frag[0].frag_link = LSW(sc->tdaTail->link_pad);
+ sc->tdaTail->frag_count = 0;
+
+ /*
+ * Move to the next transmit descriptor
+ */
+ sc->tdaTail = sc->tdaTail->next;
+#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
+ printf( "next TDA %p\n", sc->tdaTail );
+#endif
+ }
+}
+
+/*
+ * Send packet
+ */
+SONIC_STATIC void sonic_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+ struct sonic_softc *sc = ifp->if_softc;
+ void *rp = sc->sonic;
+ struct mbuf *l = NULL;
+ TransmitDescriptorPointer_t tdp;
+ volatile struct TransmitDescriptorFragLink *fp;
+ unsigned int packetSize;
+ int i;
+ static char padBuf[64];
+
+ /* printf( "sonic_sendpacket %p\n", m ); */
+ /*
+ * Free up transmit descriptors.
+ */
+ sonic_retire_tda (sc);
+
+ /*
+ * Wait for transmit descriptor to become available.
+ */
+ if (sc->tdaActiveCount == sc->tdaCount) {
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ puts( "Wait for more TDAs" );
+#endif
+
+ /*
+ * Clear old events.
+ */
+ (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
+
+ /*
+ * Wait for transmit descriptor to become available.
+ * Note that the transmit descriptors are checked
+ * *before* * entering the wait loop -- this catches
+ * the possibility that a transmit descriptor became
+ * available between the `if' the started this block,
+ * and the clearing of the interrupt status register.
+ */
+ sonic_retire_tda (sc);
+ while (sc->tdaActiveCount == sc->tdaCount) {
+ rtems_event_set events;
+
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ printf("blocking until TDAs are available\n");
+#endif
+ /*
+ * Enable transmitter interrupts.
+ */
+ sonic_enable_interrupts( sc, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
+
+ /*
+ * Wait for interrupt
+ */
+ rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events);
+ (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
+ sonic_retire_tda (sc);
+ }
+ }
+
+ /*
+ * Fill in the transmit descriptor fragment descriptors.
+ * ===CACHE===
+ * If data cache is operating in write-back mode, flush cached
+ * data to memory.
+ */
+ tdp = sc->tdaHead->next;
+ tdp->mbufp = m;
+ packetSize = 0;
+ fp = tdp->frag;
+ for (i = 0 ; i < MAXIMUM_FRAGS_PER_DESCRIPTOR ; i++, fp++) {
+ /*
+ * Throw away empty mbufs
+ */
+ if (m->m_len) {
+ void *p = mtod (m, void *);
+ fp->frag_lsw = LSW(p);
+ fp->frag_msw = MSW(p);
+ fp->frag_size = m->m_len;
+ packetSize += m->m_len;
+#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
+ printf( "fp %p 0x%04x%04x %d=%d .. %d\n",
+ fp, fp->frag_msw, fp->frag_lsw, fp->frag_size, m->m_len, packetSize );
+#endif
+#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_TX_MBUFS)
+ Dump_Buffer(
+ p,
+ (fp->frag_size > MAXIMUM_FRAME_SIZE) ? MAXIMUM_FRAME_SIZE : fp->frag_size
+ );
+#endif
+ l = m;
+ m = m->m_next;
+ }
+ else {
+ struct mbuf *n;
+ MFREE (m, n);
+ m = n;
+ if (l != NULL)
+ l->m_next = m;
+ }
+ /*
+ * Break out of the loop if this mbuf is the last in the frame.
+ */
+ if (m == NULL)
+ break;
+ }
+
+ /*
+ * Pad short packets.
+ */
+ if ((packetSize < 64) && (i < MAXIMUM_FRAGS_PER_DESCRIPTOR)) {
+ int padSize = 64 - packetSize;
+ fp++;
+ fp->frag_lsw = LSW(padBuf);
+ fp->frag_msw = MSW(padBuf);
+ fp->frag_size = padSize;
+#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
+ printf( "PAD fp %p 0x%04x%04x %d\n",
+ fp, fp->frag_msw, fp->frag_lsw, fp->frag_size );
+#endif
+ packetSize += padSize;
+ i++;
+ }
+
+ /*
+ * Fill Transmit Descriptor
+ */
+ tdp->pkt_size = packetSize;
+ tdp->frag_count = i + 1;
+ tdp->status = 0;
+
+ /*
+ * Chain onto list and start transmission.
+ */
+
+ tdp->linkp = &(fp+1)->frag_link;
+ *tdp->linkp = LSW(tdp->next) | TDA_LINK_EOL;
+ if ( sc->tdaHead->frag_count )
+ *sc->tdaHead->linkp &= ~TDA_LINK_EOL;
+ sc->tdaActiveCount++;
+ sc->tdaHead = tdp;
+
+/* XXX not in KA9Q */
+ sonic_enable_interrupts( sc, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_TXP );
+}
+
+/*
+ * Driver transmit daemon
+ */
+SONIC_STATIC void sonic_txDaemon (void *arg)
+{
+ struct sonic_softc *sc = (struct sonic_softc *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ rtems_event_set events;
+
+ for (;;) {
+ /*
+ * Wait for packet
+ */
+ rtems_bsdnet_event_receive (
+ START_TRANSMIT_EVENT,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+
+ /*
+ * Send packets till queue is empty
+ */
+ for (;;) {
+ /*
+ * Get the next mbuf chain to transmit.
+ */
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (!m)
+ break;
+ sonic_sendpacket (ifp, m);
+ }
+ ifp->if_flags &= ~IFF_OACTIVE;
+ }
+}
+
+/*
+ ******************************************************************
+ * *
+ * Receiver Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Wait for SONIC to hand over a Receive Descriptor.
+ */
+
+SONIC_STATIC void sonic_rda_wait(
+ struct sonic_softc *sc,
+ ReceiveDescriptorPointer_t rdp
+)
+{
+ int i;
+ void *rp = sc->sonic;
+ rtems_event_set events;
+
+ /*
+ * Wait for Receive Descriptor.
+ * The order of the tests is very important.
+ * The RDA is checked after RBAE is detected. This ensures that
+ * the driver processes all RDA entries before reusing the RRA
+ * entry holding the giant packet.
+ * The event wait is done after the RDA and RBAE checks. This
+ * catches the possibility that a Receive Descriptor became ready
+ * between the call to this function and the clearing of the
+ * interrupt status register bit.
+ */
+ for (;;) {
+ /*
+ * Has a giant packet arrived?
+ * The National DP83932C data sheet is very vague on what
+ * happens under this condition. The description of the
+ * Interrupt Status Register (Section 4.3.6) states,
+ * ``Reception is aborted and the SONIC fetches the next
+ * available resource descriptors in the RRA. The buffer
+ * space is not re-used and an RDA is not setup for the
+ * truncated packet.''
+ * I take ``Reception is aborted'' to mean that the RXEN
+ * bit in the Command Register is cleared and must be set
+ * by the driver to begin reception again.
+ * Unfortunately, an alternative interpretation could be
+ * that only reception of the current packet is aborted.
+ * This would be more difficult to recover from....
+ */
+ if ((*sc->read_register)( rp, SONIC_REG_ISR ) & ISR_RBAE) {
+
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ printf( "ERROR: looks like a giant packet -- RBAE\n" );
+#endif
+
+ /*
+ * One more check to soak up any Receive Descriptors
+ * that may already have been handed back to the driver.
+ */
+ if (rdp->in_use == RDA_IN_USE) {
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ printf( "ERROR: nope just an RBAE\n" );
+#endif
+ break;
+ }
+
+ /*
+ * Check my interpretation of the SONIC manual.
+ */
+ if ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_RXEN)
+ rtems_panic ("SONIC RBAE/RXEN");
+
+ /*
+ * Update statistics
+ */
+ sc->rxGiant++;
+
+ /*
+ * Reuse receive buffer.
+ * Again, the manual is subject to interpretation. The
+ * RRP register is described as, `the lower address of
+ * the next descriptor the SONIC will read.''
+ * Since, acording to the ISR/RBAE notes, the SONIC has
+ * ``fetched the next available resource descriptor in
+ * the RRA'', I interpret this to mean that that the
+ * driver has to move the RRP back *two* entries to
+ * reuse the receive buffer holding the giant packet.
+ */
+ for (i = 0 ; i < 2 ; i++) {
+ if ((*sc->read_register)( rp, SONIC_REG_RRP ) ==
+ (*sc->read_register)( rp, SONIC_REG_RSA ))
+ (*sc->write_register)(
+ rp,
+ SONIC_REG_RRP,
+ (*sc->read_register)( rp, SONIC_REG_REA )
+ );
+ (*sc->write_register)(
+ rp,
+ SONIC_REG_RRP,
+ (*sc->read_register)(rp, SONIC_REG_RRP) - sizeof(ReceiveResource_t)
+ );
+ }
+
+ /*
+ * Restart reception
+ */
+ (*sc->write_register)( rp, SONIC_REG_ISR, ISR_RBAE );
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_RXEN );
+ }
+
+ /*
+ * Clear old packet-received events.
+ */
+ (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PKTRX );
+
+ /*
+ * Has Receive Descriptor become available?
+ */
+ if (rdp->in_use == RDA_IN_USE)
+ break;
+
+ /*
+ * Enable interrupts.
+ */
+ sonic_enable_interrupts( sc, (IMR_PRXEN | IMR_RBAEEN) );
+
+ /*
+ * Wait for interrupt.
+ */
+ rtems_bsdnet_event_receive(
+ INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ }
+#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
+ printf( "RDA %p\n", rdp );
+#endif
+
+#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
+ if (rdp->status & 0x000E)
+ printf( "ERROR: RDA %p (0x%04x)\n", rdp, rdp->status );
+#endif
+
+}
+
+/*
+ * SONIC reader task
+ */
+SONIC_STATIC void sonic_rxDaemon (void *arg)
+{
+ struct sonic_softc *sc = (struct sonic_softc *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ void *rp = sc->sonic;
+ struct mbuf *m;
+ rtems_unsigned16 status;
+ ReceiveDescriptorPointer_t rdp;
+ ReceiveResourcePointer_t rwp, rea;
+ rtems_unsigned16 newMissedTally, oldMissedTally;
+
+ rwp = sc->rsa;
+ rea = sc->rea;
+ rdp = sc->rda;
+
+ /*
+ * Start the receiver
+ */
+ oldMissedTally = (*sc->read_register)( rp, SONIC_REG_MPT );
+
+ /*
+ * Input packet handling loop
+ */
+ for (;;) {
+ /*
+ * Wait till SONIC supplies a Receive Descriptor.
+ */
+ if (rdp->in_use == RDA_FREE) {
+ sonic_rda_wait (sc, rdp);
+ }
+
+#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
+ printf( "Incoming packet %p status=0x%04x\n", rdp, rdp->status );
+#endif
+
+ /*
+ * Check that packet is valid
+ */
+ status = rdp->status;
+ if (status & RDA_STATUS_PRX) {
+ struct ether_header *eh;
+ void *p;
+
+ /*
+ * Pass the packet up the chain.
+ * The mbuf count is reduced to remove
+ * the frame check sequence at the end
+ * of the packet.
+ * ===CACHE===
+ * Invalidate cache entries for this memory.
+ */
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
+ sonic_print_rx_descriptor( rdp );
+#endif
+ m = rdp->mbufp;
+ m->m_len = m->m_pkthdr.len = rdp->byte_count -
+ sizeof(rtems_unsigned32) -
+ sizeof(struct ether_header);
+ eh = mtod (m, struct ether_header *);
+ m->m_data += sizeof(struct ether_header);
+
+#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_RX_MBUFS)
+ Dump_Buffer( (void *) eh, sizeof(struct ether_header) );
+ Dump_Buffer( (void *) m, 96 /* m->m_len*/ );
+#endif
+
+ /* printf( "ether_input %p\n", m ); */
+ ether_input (ifp, eh, m);
+
+ /*
+ * Sanity check that Receive Resource Area is
+ * still in sync with Receive Descriptor Area
+ * The buffer reported in the Receive Descriptor
+ * should be the same as the buffer in the Receive
+ * Resource we are about to reuse.
+ */
+/* XXX figure out whether this is valid or not */
+#if 0
+ if ((LSW(p) != rwp->buff_ptr_lsw)
+ || (MSW(p) != rwp->buff_ptr_msw))
+ rtems_panic ("SONIC RDA/RRA");
+#endif
+
+ /*
+ * Allocate a new mbuf.
+ */
+
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = ifp;
+ rdp->mbufp = m;
+ p = mtod (m, void *);
+
+ /*
+ * Reuse Receive Resource.
+ */
+
+ rwp->buff_ptr_lsw = LSW(p);
+ rwp->buff_ptr_msw = MSW(p);
+ rwp->buff_wc_lsw = RBUF_WC;
+ rwp->buff_wc_msw = 0;
+ rwp++;
+
+ if (rwp == rea) {
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
+ printf( "Wrapping RWP from %p to %p\n", rwp, sc->rsa );
+#endif
+ rwp = sc->rsa;
+ }
+ (*sc->write_register)( rp, SONIC_REG_RWP , LSW(rwp) );
+
+ /*
+ * Tell the SONIC to reread the RRA.
+ */
+ if ((*sc->read_register)( rp, SONIC_REG_ISR ) & ISR_RBE)
+ (*sc->write_register)( rp, SONIC_REG_ISR, ISR_RBE );
+ }
+ else {
+ if (status & RDA_STATUS_COL)
+ sc->rxCollision++;
+ if (status & RDA_STATUS_FAER)
+ sc->rxNonOctet++;
+ else if (status & RDA_STATUS_CRCR)
+ sc->rxBadCRC++;
+ }
+
+ /*
+ * Count missed packets
+ */
+ newMissedTally = (*sc->read_register)( rp, SONIC_REG_MPT );
+ if (newMissedTally != oldMissedTally) {
+ sc->rxMissed += (newMissedTally - oldMissedTally) & 0xFFFF;
+ newMissedTally = oldMissedTally;
+ }
+
+ /*
+ * Move to next receive descriptor
+ */
+
+ rdp->in_use = RDA_FREE;
+ rdp = rdp->next;
+ rdp->link &= ~RDA_LINK_EOL;
+
+ }
+}
+
+/*
+ ******************************************************************
+ * *
+ * Initialization Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Initialize the SONIC hardware
+ */
+SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
+{
+ void *rp = sc->sonic;
+ int i;
+ unsigned char *hwaddr;
+ rtems_isr_entry old_handler;
+ TransmitDescriptorPointer_t tdp;
+ ReceiveDescriptorPointer_t ordp, rdp;
+ ReceiveResourcePointer_t rwp;
+ struct mbuf *m;
+ void *p;
+ CamDescriptorPointer_t cdp;
+
+ /*
+ * The Revision B SONIC has a horrible bug known as the "Zero
+ * Length Packet bug". The initial board used to develop this
+ * driver had a newer revision of the SONIC so there was no reason
+ * to check for this. If you have the Revision B SONIC chip, then
+ * you need to add some code to the RX path to handle this weirdness.
+ */
+
+ if ( (*sc->read_register)( rp, SONIC_REG_SR ) < SONIC_REVISION_C ) {
+ rtems_fatal_error_occurred( 0x0BADF00D ); /* don't eat this part :) */
+ }
+
+ /*
+ * Set up circular linked list in Transmit Descriptor Area.
+ * Use the PINT bit in the transmit configuration field to
+ * request an interrupt on every other transmitted packet.
+ *
+ * NOTE: sonic_allocate() zeroes all of the memory allocated.
+ */
+
+ sc->tdaActiveCount = 0;
+ sc->tdaTail = sonic_allocate(sc->tdaCount * sizeof *tdp);
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
+ printf( "tdaTail = %p\n", sc->tdaTail );
+#endif
+ tdp = sc->tdaTail;
+ for (i = 0 ; i < sc->tdaCount ; i++) {
+ /*
+ * Start off with the table of outstanding mbuf's
+ */
+
+ /*
+ * status, pkt_config, pkt_size, and all fragment fields
+ * are set to zero by sonic_allocate.
+ */
+
+/* XXX not used by the BSD drivers
+*/
+ if (i & 1)
+ tdp->pkt_config = TDA_CONFIG_PINT;
+
+ tdp->frag_count = 0;
+ tdp->frag[0].frag_link = LSW(tdp + 1);
+ tdp->link_pad = LSW(tdp + 1) | TDA_LINK_EOL;
+ tdp->linkp = &((tdp + 1)->frag[0].frag_link);
+ tdp->next = (TransmitDescriptor_t *)(tdp + 1);
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
+ sonic_print_tx_descriptor( tdp );
+#endif
+ tdp++;
+ }
+ tdp--;
+ sc->tdaHead = tdp;
+ tdp->link_pad = LSW(sc->tdaTail) | TDA_LINK_EOL;
+ tdp->next = (TransmitDescriptor_t *)sc->tdaTail;
+ tdp->linkp = &sc->tdaTail->frag[0].frag_link;
+
+ /*
+ * Set up circular linked list in Receive Descriptor Area.
+ * Leaves sc->rda pointing at the `beginning' of the list.
+ *
+ * NOTE: The RDA and CDP must have the same MSW for their addresses.
+ */
+
+ sc->rda = sonic_allocate(
+ (sc->rdaCount * sizeof(ReceiveDescriptor_t)) +
+ sizeof(CamDescriptor_t) );
+ sc->cdp = (CamDescriptorPointer_t) ((unsigned char *)sc->rda +
+ (sc->rdaCount * sizeof(ReceiveDescriptor_t)));
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
+ printf( "rda area = %p\n", sc->rda );
+ printf( "cdp area = %p\n", sc->cdp );
+#endif
+
+ ordp = rdp = sc->rda;
+ for (i = 0 ; i < sc->rdaCount ; i++) {
+ /*
+ * status, byte_count, pkt_ptr0, pkt_ptr1, and seq_no are set
+ * to zero by sonic_allocate.
+ */
+ rdp->link = LSW(rdp + 1);
+ rdp->in_use = RDA_FREE;
+ rdp->next = (ReceiveDescriptor_t *)(rdp + 1);
+ ordp = rdp;
+ rdp++;
+ }
+ /*
+ * Link the last desriptor to the 1st one and mark it as the end
+ * of the list.
+ */
+ ordp->next = sc->rda;
+ ordp->link = LSW(sc->rda) | RDA_LINK_EOL;
+ sc->rdp_last = rdp;
+
+ /*
+ * Allocate the receive resource area.
+ * In accordance with National Application Note 746, make the
+ * receive resource area bigger than the receive descriptor area.
+ * This has the useful side effect of making the receive resource
+ * area big enough to hold the CAM descriptor area.
+ */
+
+ sc->rsa = sonic_allocate((sc->rdaCount + RRA_EXTRA_COUNT) * sizeof *sc->rsa);
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
+ printf( "rsa area = %p\n", sc->rsa );
+#endif
+
+ /*
+ * Set up list in Receive Resource Area.
+ * Allocate space for incoming packets.
+ */
+
+ rwp = sc->rsa;
+ for (i = 0 ; i < (sc->rdaCount + RRA_EXTRA_COUNT) ; i++, rwp++) {
+
+ /*
+ * Allocate memory for buffer.
+ * Place a pointer to the mbuf at the beginning of the buffer
+ * so we can find the mbuf when the SONIC returns the buffer
+ * to the driver.
+ */
+
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
+ sc->rda[i].mbufp = m;
+
+ p = mtod (m, void *);
+
+ /*
+ * Set up RRA entry
+ */
+ rwp->buff_ptr_lsw = LSW(p);
+ rwp->buff_ptr_msw = MSW(p);
+ rwp->buff_wc_lsw = RBUF_WC;
+ rwp->buff_wc_msw = 0;
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
+ sonic_print_rx_descriptor( &sc->rda[i] );
+#endif
+ }
+ sc->rea = rwp;
+#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
+ printf( "rea area = %p\n", sc->rea );
+#endif
+
+
+ /*
+ * Issue a software reset.
+ */
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );
+
+ /*
+ * Set up data configuration registers.
+ */
+ (*sc->write_register)( rp, SONIC_REG_DCR, sc->dcr_value );
+ (*sc->write_register)( rp, SONIC_REG_DCR2, sc->dc2_value );
+
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_STP | CR_RXDIS | CR_HTX );
+
+ /*
+ * Mask all interrupts
+ */
+ (*sc->write_register)( rp, SONIC_REG_IMR, 0x0 ); /* XXX was backwards */
+
+ /*
+ * Clear outstanding interrupts.
+ */
+ (*sc->write_register)( rp, SONIC_REG_ISR, 0x7FFF );
+
+ /*
+ * Clear the tally counters
+ */
+
+ (*sc->write_register)( rp, SONIC_REG_CRCT, 0xFFFF );
+ (*sc->write_register)( rp, SONIC_REG_FAET, 0xFFFF );
+ (*sc->write_register)( rp, SONIC_REG_MPT, 0xFFFF );
+ (*sc->write_register)( rp, SONIC_REG_RSC, 0 );
+
+ /*
+ * Set the Receiver mode
+ *
+ * Enable/disable reception of broadcast packets
+ */
+
+ if (sc->acceptBroadcast)
+ (*sc->write_register)( rp, SONIC_REG_RCR, RCR_BRD );
+ else
+ (*sc->write_register)( rp, SONIC_REG_RCR, 0 );
+
+ /*
+ * Set up Resource Area pointers
+ */
+
+ (*sc->write_register)( rp, SONIC_REG_URRA, MSW(sc->rsa) );
+ (*sc->write_register)( rp, SONIC_REG_RSA, LSW(sc->rsa) );
+
+ (*sc->write_register)( rp, SONIC_REG_REA, LSW(sc->rea) );
+
+ (*sc->write_register)( rp, SONIC_REG_RRP, LSW(sc->rsa) );
+ (*sc->write_register)( rp, SONIC_REG_RWP, LSW(sc->rsa) ); /* XXX was rea */
+
+ (*sc->write_register)( rp, SONIC_REG_URDA, MSW(sc->rda) );
+ (*sc->write_register)( rp, SONIC_REG_CRDA, LSW(sc->rda) );
+
+ (*sc->write_register)( rp, SONIC_REG_UTDA, MSW(sc->tdaTail) );
+ (*sc->write_register)( rp, SONIC_REG_CTDA, LSW(sc->tdaTail) );
+
+ /*
+ * Set End Of Buffer Count register to the value recommended
+ * in Note 1 of Section 3.4.4.4 of the SONIC data sheet.
+ */
+
+ (*sc->write_register)( rp, SONIC_REG_EOBC, RBUF_WC - 2 );
+
+ /*
+ * Issue the load RRA command
+ */
+
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_RRRA );
+ while ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_RRRA)
+ continue;
+
+ /*
+ * Remove device reset
+ */
+
+ (*sc->write_register)( rp, SONIC_REG_CR, 0 );
+
+ /*
+ * Set up the SONIC CAM with our hardware address.
+ */
+
+ hwaddr = sc->arpcom.ac_enaddr;
+ cdp = sc->cdp;
+
+#if (SONIC_DEBUG & SONIC_DEBUG_CAM)
+ printf( "hwaddr: %2x:%2x:%2x:%2x:%2x:%2x\n",
+ hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5] );
+#endif
+
+ cdp->cep = 0; /* Fill first and only entry in CAM */
+ cdp->cap0 = hwaddr[1] << 8 | hwaddr[0];
+ cdp->cap1 = hwaddr[3] << 8 | hwaddr[2];
+ cdp->cap2 = hwaddr[5] << 8 | hwaddr[4];
+ cdp->ce = 0x0001; /* Enable first entry in CAM */
+
+ (*sc->write_register)( rp, SONIC_REG_CDC, 1 ); /* 1 entry in CDA */
+ (*sc->write_register)( rp, SONIC_REG_CDP, LSW(cdp) );
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_LCAM ); /* Load the CAM */
+
+ while ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_LCAM)
+ continue;
+
+ /*
+ * Verify that CAM was properly loaded.
+ */
+
+ (*sc->write_register)( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );
+
+#if (SONIC_DEBUG & SONIC_DEBUG_CAM)
+ (*sc->write_register)( rp, SONIC_REG_CEP, 0 ); /* Select first entry in CAM */
+ printf ("Loaded Ethernet address into SONIC CAM.\n"
+ " Wrote %04x%04x%04x - %#x\n"
+ " Read %04x%04x%04x - %#x\n",
+ cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
+ (*sc->read_register)( rp, SONIC_REG_CAP2 ),
+ (*sc->read_register)( rp, SONIC_REG_CAP1 ),
+ (*sc->read_register)( rp, SONIC_REG_CAP0 ),
+ (*sc->read_register)( rp, SONIC_REG_CE ));
+#endif
+
+ (*sc->write_register)( rp, SONIC_REG_CEP, 0 ); /* Select first entry in CAM */
+ if (((*sc->read_register)( rp, SONIC_REG_CAP2 ) != cdp->cap2)
+ || ((*sc->read_register)( rp, SONIC_REG_CAP1 ) != cdp->cap1)
+ || ((*sc->read_register)( rp, SONIC_REG_CAP0 ) != cdp->cap0)
+ || ((*sc->read_register)( rp, SONIC_REG_CE ) != cdp->ce)) {
+ printf ("Failed to load Ethernet address into SONIC CAM.\n"
+ " Wrote %04x%04x%04x - %#x\n"
+ " Read %04x%04x%04x - %#x\n",
+ cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
+ (*sc->read_register)( rp, SONIC_REG_CAP2 ),
+ (*sc->read_register)( rp, SONIC_REG_CAP1 ),
+ (*sc->read_register)( rp, SONIC_REG_CAP0 ),
+ (*sc->read_register)( rp, SONIC_REG_CE ));
+ rtems_panic ("SONIC LCAM");
+ }
+
+ (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */CR_RXEN | CR_STP);
+
+ /*
+ * Attach SONIC interrupt handler
+ */
+/* XXX
+ (*sc->write_register)( rp, SONIC_REG_IMR, 0 );
+*/
+ old_handler = set_vector(sonic_interrupt_handler, sc->vector, 0);
+
+ /*
+ * Remainder of hardware initialization is
+ * done by the receive and transmit daemons.
+ */
+}
+
+/*
+ * Send packet (caller provides header).
+ */
+
+SONIC_STATIC void sonic_start(struct ifnet *ifp)
+{
+ struct sonic_softc *sc = ifp->if_softc;
+
+ rtems_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
+ ifp->if_flags |= IFF_OACTIVE;
+}
+
+/*
+ * Initialize and start the device
+ */
+
+SONIC_STATIC void sonic_init (void *arg)
+{
+ struct sonic_softc *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ void *rp = sc->sonic;
+ int rcr;
+
+ if (sc->txDaemonTid == 0) {
+
+ /*
+ * Set up SONIC hardware
+ */
+ sonic_initialize_hardware (sc);
+
+ /*
+ * Start driver tasks
+ */
+ sc->txDaemonTid = rtems_bsdnet_newproc ("SNtx", 4096, sonic_txDaemon, sc);
+ sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);
+ }
+
+ /*
+ * Set flags appropriately
+ */
+ rcr = (*sc->read_register)( rp, SONIC_REG_RCR );
+ if (ifp->if_flags & IFF_PROMISC)
+ rcr |= RCR_PRO;
+ else
+ rcr &= ~RCR_PRO;
+ (*sc->write_register)( rp, SONIC_REG_RCR, rcr);
+
+ /*
+ * Tell the world that we're running.
+ */
+ ifp->if_flags |= IFF_RUNNING;
+
+ /*
+ * Enable receiver and transmitter
+ */
+ /* (*sc->write_register)( rp, SONIC_REG_IMR, 0 ); */
+ sonic_enable_interrupts( sc,
+ (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) | (IMR_PRXEN | IMR_RBAEEN) );
+
+ (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */ CR_RXEN);
+}
+
+/*
+ * Driver ioctl handler
+ */
+static int
+sonic_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+ struct sonic_softc *sc = ifp->if_softc;
+ int error = 0;
+
+ switch (command) {
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ ether_ioctl (ifp, command, data);
+ break;
+
+ case SIOCSIFFLAGS:
+ switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+ case IFF_RUNNING:
+ sonic_stop (sc);
+ break;
+
+ case IFF_UP:
+ sonic_init (sc);
+ break;
+
+ case IFF_UP | IFF_RUNNING:
+ sonic_stop (sc);
+ sonic_init (sc);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SIO_RTEMS_SHOW_STATS:
+ sonic_stats (sc);
+ break;
+
+ /*
+ * FIXME: All sorts of multicast commands need to be added here!
+ */
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+
+/*
+ * Attach an SONIC driver to the system
+ * This is the only `extern' function in the driver.
+ */
+
+int
+rtems_sonic_driver_attach (
+ struct rtems_bsdnet_ifconfig *config,
+ sonic_configuration_t *chip
+)
+{
+ struct sonic_softc *sc;
+ struct ifnet *ifp;
+ int mtu;
+ int i;
+
+ /*
+ * Find an unused entry
+ */
+ i = 0;
+ sc = sonic_softc;
+ for (;;) {
+ if (sc == &sonic_softc[NSONIC]) {
+ printf ("No more SONIC devices.\n");
+ return 0;
+ }
+ ifp = &sc->arpcom.ac_if;
+ if (ifp->if_softc == NULL)
+ break;
+ sc++;
+ i++;
+ }
+
+ /*
+ * zero out the control structure
+ */
+
+ memset( sc, 0, sizeof(*sc) );
+
+
+ /*
+ * Process options
+ */
+ if (config->hardware_address) {
+ memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+ }
+ else {
+ memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
+ }
+ if (config->mtu)
+ mtu = config->mtu;
+ else
+ mtu = ETHERMTU;
+ if (config->rbuf_count)
+ sc->rdaCount = config->rbuf_count;
+ else
+ sc->rdaCount = chip->rda_count;
+ if (config->xbuf_count)
+ sc->tdaCount = config->xbuf_count;
+ else
+ sc->tdaCount = chip->tda_count;
+ sc->acceptBroadcast = !config->ignore_broadcast;
+
+ sc->sonic = (void *) chip->base_address;
+ sc->vector = chip->vector;
+ sc->dcr_value = chip->dcr_value;
+ sc->dc2_value = chip->dc2_value;
+ sc->write_register = chip->write_register;
+ sc->read_register = chip->read_register;
+
+ /*
+ * Set up network interface values
+ */
+ ifp->if_softc = sc;
+ ifp->if_unit = i + 1;
+ ifp->if_name = "sonic";
+ ifp->if_mtu = mtu;
+ ifp->if_init = sonic_init;
+ ifp->if_ioctl = sonic_ioctl;
+ ifp->if_start = sonic_start;
+ ifp->if_output = ether_output;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+ if (ifp->if_snd.ifq_maxlen == 0)
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+ /*
+ * Attach the interface
+ */
+ if_attach (ifp);
+ ether_ifattach (ifp);
+ return 1;
+}
+
+#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
+#include <stdio.h>
+
+char SONIC_Reg_name[64][6]= {
+ "CR", /* 0x00 */
+ "DCR", /* 0x01 */
+ "RCR", /* 0x02 */
+ "TCR", /* 0x03 */
+ "IMR", /* 0x04 */
+ "ISR", /* 0x05 */
+ "UTDA", /* 0x06 */
+ "CTDA", /* 0x07 */
+ "0x08", /* 0x08 */
+ "0x09", /* 0x09 */
+ "0x0A", /* 0x0A */
+ "0x0B", /* 0x0B */
+ "0x0C", /* 0x0C */
+ "URDA", /* 0x0D */
+ "CRDA", /* 0x0E */
+ "0x0F", /* 0x0F */
+ "0x10", /* 0x10 */
+ "0x11", /* 0x11 */
+ "0x12", /* 0x12 */
+ "EOBC", /* 0x13 */
+ "URRA", /* 0x14 */
+ "RSA", /* 0x15 */
+ "REA", /* 0x16 */
+ "RRP", /* 0x17 */
+ "RWP", /* 0x18 */
+ "0x19", /* 0x19 */
+ "0x1A", /* 0x1A */
+ "0x1B", /* 0x1B */
+ "0x1C", /* 0x1C */
+ "0x0D", /* 0x1D */
+ "0x1E", /* 0x1E */
+ "0x1F", /* 0x1F */
+ "0x20", /* 0x20 */
+ "CEP", /* 0x21 */
+ "CAP2", /* 0x22 */
+ "CAP1", /* 0x23 */
+ "CAP0", /* 0x24 */
+ "CE", /* 0x25 */
+ "CDP", /* 0x26 */
+ "CDC", /* 0x27 */
+ "SR", /* 0x28 */
+ "WT0", /* 0x29 */
+ "WT1", /* 0x2A */
+ "RSC", /* 0x2B */
+ "CRCT", /* 0x2C */
+ "FAET", /* 0x2D */
+ "MPT", /* 0x2E */
+ "MDT", /* 0x2F */
+ "0x30", /* 0x30 */
+ "0x31", /* 0x31 */
+ "0x32", /* 0x32 */
+ "0x33", /* 0x33 */
+ "0x34", /* 0x34 */
+ "0x35", /* 0x35 */
+ "0x36", /* 0x36 */
+ "0x37", /* 0x37 */
+ "0x38", /* 0x38 */
+ "0x39", /* 0x39 */
+ "0x3A", /* 0x3A */
+ "0x3B", /* 0x3B */
+ "0x3C", /* 0x3C */
+ "0x3D", /* 0x3D */
+ "0x3E", /* 0x3E */
+ "DCR2" /* 0x3F */
+};
+#endif
diff --git a/c/src/lib/libchip/network/sonic.h b/c/src/lib/libchip/network/sonic.h
new file mode 100644
index 0000000000..47f50d3356
--- /dev/null
+++ b/c/src/lib/libchip/network/sonic.h
@@ -0,0 +1,416 @@
+/*
+ * RTEMS NETWORK DRIVER FOR NATIONAL DP83932 `SONIC'
+ * SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER
+ *
+ * REUSABLE CHIP DRIVER CONFIGURATION
+ *
+ * References:
+ *
+ * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
+ * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
+ * 1995.
+ *
+ * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
+ * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
+ * RRD-B30M75, National Semiconductor, March, 1991.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef _SONIC_DP83932_
+#define _SONIC_DP83932_
+
+/*
+ * Configuration Information
+ */
+
+typedef void (*sonic_write_register_t)(
+ void *base,
+ unsigned32 regno,
+ unsigned32 value
+);
+
+typedef unsigned32 (*sonic_read_register_t)(
+ void *base,
+ unsigned32 regno
+);
+
+typedef struct {
+ unsigned32 base_address;
+ unsigned32 vector;
+ unsigned32 dcr_value;
+ unsigned32 dc2_value;
+ unsigned32 tda_count;
+ unsigned32 rda_count;
+ sonic_write_register_t write_register;
+ sonic_read_register_t read_register;
+} sonic_configuration_t;
+
+/*
+ ******************************************************************
+ * *
+ * Device Registers *
+ * *
+ ******************************************************************
+ */
+#define SONIC_REG_CR 0x00 /* Command */
+#define SONIC_REG_DCR 0x01 /* Data configuration */
+#define SONIC_REG_RCR 0x02 /* Receive control */
+#define SONIC_REG_TCR 0x03 /* Transmit control */
+#define SONIC_REG_IMR 0x04 /* Interrupt mask */
+#define SONIC_REG_ISR 0x05 /* Interrupt status */
+#define SONIC_REG_UTDA 0x06 /* Upper transmit descriptor address */
+#define SONIC_REG_CTDA 0x07 /* Current transmit descriptor address */
+#define SONIC_REG_URDA 0x0D /* Upper receive descriptor address */
+#define SONIC_REG_CRDA 0x0E /* Current receive descriptor address */
+#define SONIC_REG_EOBC 0x13 /* End of buffer word count */
+#define SONIC_REG_URRA 0x14 /* Upper receive resource */
+#define SONIC_REG_RSA 0x15 /* Resource start address */
+#define SONIC_REG_REA 0x16 /* Resource end address */
+#define SONIC_REG_RRP 0x17 /* Resouce read pointer */
+#define SONIC_REG_RWP 0x18 /* Resouce write pointer */
+#define SONIC_REG_CEP 0x21 /* CAM entry pointer */
+#define SONIC_REG_CAP2 0x22 /* CAM address port 2 */
+#define SONIC_REG_CAP1 0x23 /* CAM address port 1 */
+#define SONIC_REG_CAP0 0x24 /* CAM address port 0 */
+#define SONIC_REG_CE 0x25 /* CAM enable */
+#define SONIC_REG_CDP 0x26 /* CAM descriptor pointer */
+#define SONIC_REG_CDC 0x27 /* CAM descriptor count */
+#define SONIC_REG_SR 0x28 /* Silicon revision */
+#define SONIC_REG_WT0 0x29 /* Watchdog timer 0 */
+#define SONIC_REG_WT1 0x2A /* Watchdog timer 1 */
+#define SONIC_REG_RSC 0x2B /* Receive sequence counter */
+#define SONIC_REG_CRCT 0x2C /* CRC error tally */
+#define SONIC_REG_FAET 0x2D /* FAE tally */
+#define SONIC_REG_MPT 0x2E /* Missed packet tally */
+#define SONIC_REG_MDT 0x2F /* TX Maximum Deferral */
+#define SONIC_REG_DCR2 0x3F /* Data configuration 2 */
+
+/*
+ * Command register
+ */
+#define CR_LCAM 0x0200
+#define CR_RRRA 0x0100
+#define CR_RST 0x0080
+#define CR_ST 0x0020
+#define CR_STP 0x0010
+#define CR_RXEN 0x0008
+#define CR_RXDIS 0x0004
+#define CR_TXP 0x0002
+#define CR_HTX 0x0001
+
+/*
+ * Data configuration register
+ */
+#define DCR_EXBUS 0x8000
+#define DCR_LBR 0x2000
+#define DCR_PO1 0x1000
+#define DCR_PO0 0x0800
+#define DCR_SBUS 0x0400
+#define DCR_USR1 0x0200
+#define DCR_USR0 0x0100
+#define DCR_WC1 0x0080
+#define DCR_WC0 0x0040
+#define DCR_DW 0x0020
+#define DCR_BMS 0x0010
+#define DCR_RFT1 0x0008
+#define DCR_RFT0 0x0004
+#define DCR_TFT1 0x0002
+#define DCR_TFT0 0x0001
+
+/* data configuration register aliases */
+#define DCR_SYNC DCR_SBUS /* synchronous (memory cycle 2 clocks) */
+#define DCR_ASYNC 0 /* asynchronous (memory cycle 3 clocks) */
+
+#define DCR_WAIT0 0 /* 0 wait states added */
+#define DCR_WAIT1 DCR_WC0 /* 1 wait state added */
+#define DCR_WAIT2 DCR_WC1 /* 2 wait states added */
+#define DCR_WAIT3 (DCR_WC1|DCR_WC0) /* 3 wait states added */
+
+#define DCR_DW16 0 /* use 16-bit DMA accesses */
+#define DCR_DW32 DCR_DW /* use 32-bit DMA accesses */
+
+#define DCR_DMAEF 0 /* DMA until TX/RX FIFO has emptied/filled */
+#define DCR_DMABLOCK DCR_BMS /* DMA until RX/TX threshold crossed */
+
+#define DCR_RFT4 0 /* receive threshold 4 bytes */
+#define DCR_RFT8 DCR_RFT0 /* receive threshold 8 bytes */
+#define DCR_RFT16 DCR_RFT1 /* receive threshold 16 bytes */
+#define DCR_RFT24 (DCR_RFT1|DCR_RFT0) /* receive threshold 24 bytes */
+
+#define DCR_TFT8 0 /* transmit threshold 8 bytes */
+#define DCR_TFT16 DCR_TFT0 /* transmit threshold 16 bytes */
+#define DCR_TFT24 DCR_TFT1 /* transmit threshold 24 bytes */
+#define DCR_TFT28 (DCR_TFT1|DCR_TFT0) /* transmit threshold 28 bytes */
+
+/*
+ * Receive control register
+ */
+#define RCR_ERR 0x8000
+#define RCR_RNT 0x4000
+#define RCR_BRD 0x2000
+#define RCR_PRO 0x1000
+#define RCR_AMC 0x0800
+#define RCR_LB1 0x0400
+#define RCR_LB0 0x0200
+#define RCR_MC 0x0100
+#define RCR_BC 0x0080
+#define RCR_LPKT 0x0040
+#define RCR_CRS 0x0020
+#define RCR_COL 0x0010
+#define RCR_CRCR 0x0008
+#define RCR_FAER 0x0004
+#define RCR_LBK 0x0002
+#define RCR_PRX 0x0001
+
+/*
+ * Transmit control register
+ */
+#define TCR_PINT 0x8000
+#define TCR_POWC 0x4000
+#define TCR_CRCI 0x2000
+#define TCR_EXDIS 0x1000
+#define TCR_EXD 0x0400
+#define TCR_DEF 0x0200
+#define TCR_NCRS 0x0100
+#define TCR_CRSL 0x0080
+#define TCR_EXC 0x0040
+#define TCR_OWC 0x0020
+#define TCR_PMB 0x0008
+#define TCR_FU 0x0004
+#define TCR_BCM 0x0002
+#define TCR_PTX 0x0001
+
+/*
+ * Interrupt mask register
+ */
+#define IMR_BREN 0x4000
+#define IMR_HBLEN 0x2000
+#define IMR_LCDEN 0x1000
+#define IMR_PINTEN 0x0800
+#define IMR_PRXEN 0x0400
+#define IMR_PTXEN 0x0200
+#define IMR_TXEREN 0x0100
+#define IMR_TCEN 0x0080
+#define IMR_RDEEN 0x0040
+#define IMR_RBEEN 0x0020
+#define IMR_RBAEEN 0x0010
+#define IMR_CRCEN 0x0008
+#define IMR_FAEEN 0x0004
+#define IMR_MPEN 0x0002
+#define IMR_RFOEN 0x0001
+
+/*
+ * Interrupt status register
+ */
+#define ISR_BR 0x4000
+#define ISR_HBL 0x2000
+#define ISR_LCD 0x1000
+#define ISR_PINT 0x0800
+#define ISR_PKTRX 0x0400
+#define ISR_TXDN 0x0200
+#define ISR_TXER 0x0100
+#define ISR_TC 0x0080
+#define ISR_RDE 0x0040
+#define ISR_RBE 0x0020
+#define ISR_RBAE 0x0010
+#define ISR_CRC 0x0008
+#define ISR_FAE 0x0004
+#define ISR_MP 0x0002
+#define ISR_RFO 0x0001
+
+/*
+ * Data configuration register 2
+ */
+#define DCR2_EXPO3 0x8000
+#define DCR2_EXPO2 0x4000
+#define DCR2_EXPO1 0x2000
+#define DCR2_EXPO0 0x1000
+#define DCR2_PH 0x0010
+#define DCR2_PCM 0x0004
+#define DCR2_PCNM 0x0002
+#define DCR2_RJCM 0x0001
+
+/*
+ * Known values for the Silicon Revision Register
+ */
+
+#define SONIC_REVISION_B 4
+#define SONIC_REVISION_C 6
+
+/*
+ ******************************************************************
+ * *
+ * Transmit Buffer Management *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Transmit descriptor area entry.
+ * There is one transmit descriptor for each packet to be transmitted.
+ * Statically reserve space for up to MAXIMUM_FRAGS_PER_PACKET fragments
+ * per descriptor.
+ */
+#define MAXIMUM_FRAGS_PER_DESCRIPTOR 6
+struct TransmitDescriptor {
+ rtems_unsigned32 status;
+ rtems_unsigned32 pkt_config;
+ rtems_unsigned32 pkt_size;
+ rtems_unsigned32 frag_count;
+
+ /*
+ * Packet fragment pointers
+ */
+ struct TransmitDescriptorFragLink {
+ rtems_unsigned32 frag_lsw; /* LSW of fragment address */
+#define frag_link frag_lsw
+ rtems_unsigned32 frag_msw; /* MSW of fragment address */
+ rtems_unsigned32 frag_size;
+ } frag[MAXIMUM_FRAGS_PER_DESCRIPTOR];
+
+ /*
+ * Space for link if all fragment pointers are used.
+ */
+ rtems_unsigned32 link_pad;
+
+ /*
+ * Extra RTEMS stuff
+ */
+ struct TransmitDescriptor *next; /* Circularly-linked list */
+ struct mbuf *mbufp; /* First mbuf in packet */
+ volatile rtems_unsigned32 *linkp; /* Pointer to un[xxx].link */
+};
+typedef struct TransmitDescriptor TransmitDescriptor_t;
+typedef volatile TransmitDescriptor_t *TransmitDescriptorPointer_t;
+
+/*
+ * Transmit Configuration.
+ * For standard Ethernet transmission, all bits in the transmit
+ * configuration field are set to 0.
+ */
+#define TDA_CONFIG_PINT 0x8000
+#define TDA_CONFIG_POWC 0x4000
+#define TDA_CONFIG_CRCI 0x2000
+#define TDA_CONFIG_EXDIS 0x1000
+
+/*
+ * Transmit status
+ */
+#define TDA_STATUS_COLLISION_MASK 0xF800
+#define TDA_STATUS_COLLISION_SHIFT 11
+#define TDA_STATUS_EXD 0x0400
+#define TDA_STATUS_DEF 0x0200
+#define TDA_STATUS_NCRS 0x0100
+#define TDA_STATUS_CRSL 0x0080
+#define TDA_STATUS_EXC 0x0040
+#define TDA_STATUS_OWC 0x0020
+#define TDA_STATUS_PMB 0x0008
+#define TDA_STATUS_FU 0x0004
+#define TDA_STATUS_BCM 0x0002
+#define TDA_STATUS_PTX 0x0001
+
+#define TDA_LINK_EOL 0x0001
+#define TDA_LINK_EOL_MASK 0xFFFE
+
+
+
+/*
+ ******************************************************************
+ * *
+ * Receive Buffer Management *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Receive resource area entry.
+ * There is one receive resource entry for each receive buffer area (RBA).
+ * This driver allows only one packet per receive buffer area, so one
+ * receive resource entry corresponds to one correctly-received packet.
+ */
+struct ReceiveResource {
+ rtems_unsigned32 buff_ptr_lsw; /* LSW of RBA address */
+ rtems_unsigned32 buff_ptr_msw; /* MSW of RBA address */
+ rtems_unsigned32 buff_wc_lsw; /* LSW of RBA size (16-bit words) */
+ rtems_unsigned32 buff_wc_msw; /* MSW of RBA size (16-bit words) */
+};
+typedef struct ReceiveResource ReceiveResource_t;
+typedef volatile ReceiveResource_t *ReceiveResourcePointer_t;
+
+/*
+ * Receive descriptor area entry.
+ * There is one receive descriptor for each packet received.
+ */
+struct ReceiveDescriptor {
+ rtems_unsigned32 status;
+ rtems_unsigned32 byte_count;
+ rtems_unsigned32 pkt_lsw; /* LSW of packet address */
+ rtems_unsigned32 pkt_msw; /* MSW of packet address */
+ rtems_unsigned32 seq_no;
+ rtems_unsigned32 link;
+ rtems_unsigned32 in_use;
+
+ /*
+ * Extra RTEMS stuff
+ */
+ volatile struct ReceiveDescriptor *next; /* Circularly-linked list */
+ struct mbuf *mbufp; /* First mbuf in packet */
+};
+typedef struct ReceiveDescriptor ReceiveDescriptor_t;
+typedef volatile ReceiveDescriptor_t *ReceiveDescriptorPointer_t;
+
+typedef struct {
+ rtems_unsigned32 cep; /* CAM Entry Pointer */
+ rtems_unsigned32 cap0; /* CAM Address Port 0 xx-xx-xx-xx-YY-YY */
+ rtems_unsigned32 cap1; /* CAM Address Port 1 xx-xx-YY-YY-xxxx */
+ rtems_unsigned32 cap2; /* CAM Address Port 2 YY-YY-xx-xx-xx-xx */
+ rtems_unsigned32 ce;
+} CamDescriptor_t;
+
+typedef volatile CamDescriptor_t *CamDescriptorPointer_t;
+
+/*
+ * Receive status
+ */
+#define RDA_STATUS_ERR 0x8800
+#define RDA_STATUS_RNT 0x4000
+#define RDA_STATUS_BRD 0x2000
+#define RDA_STATUS_PRO 0x1000
+#define RDA_STATUS_AMC 0x0800
+#define RDA_STATUS_LB1 0x0400
+#define RDA_STATUS_LB0 0x0200
+#define RDA_STATUS_MC 0x0100
+#define RDA_STATUS_BC 0x0080
+#define RDA_STATUS_LPKT 0x0040
+#define RDA_STATUS_CRS 0x0020
+#define RDA_STATUS_COL 0x0010
+#define RDA_STATUS_CRCR 0x0008
+#define RDA_STATUS_FAER 0x0004
+#define RDA_STATUS_LBK 0x0002
+#define RDA_STATUS_PRX 0x0001
+
+#define RDA_LINK_EOL 0x0001
+#define RDA_LINK_EOL_MASK 0xFFFE
+#define RDA_IN_USE 0x0000 /* SONIC has finished with the packet */
+ /* and the driver can process it */
+#define RDA_FREE 0xFFFF /* SONIC can use it */
+
+/*
+ * Attatch routine
+ */
+
+int rtems_sonic_driver_attach (
+ struct rtems_bsdnet_ifconfig *config,
+ sonic_configuration_t *chip
+);
+
+#endif /* _SONIC_DP83932_ */
diff --git a/c/src/lib/wrapup/Makefile.in b/c/src/lib/wrapup/Makefile.in
index 5e73848490..d3e0f76ac9 100644
--- a/c/src/lib/wrapup/Makefile.in
+++ b/c/src/lib/wrapup/Makefile.in
@@ -24,6 +24,7 @@ SRCS=$(wildcard $(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a) \
$(wildcard $(PROJECT_RELEASE)/lib/libcpu$(LIB_VARIANT).a) \
$(wildcard $(PROJECT_RELEASE)/lib/librtcio$(LIB_VARIANT).a) \
$(wildcard $(PROJECT_RELEASE)/lib/libserialio$(LIB_VARIANT).a) \
+ $(wildcard $(PROJECT_RELEASE)/lib/libnetchip$(LIB_VARIANT).a) \
$(PROJECT_RELEASE)/lib/libcsupport$(LIB_VARIANT).a \
$(PROJECT_RELEASE)/lib/libmisc$(LIB_VARIANT).a \
$(wildcard $(PROJECT_RELEASE)/lib/rtems-ctor$(LIB_VARIANT).o) \
diff --git a/c/src/libchip/network/Makefile.in b/c/src/libchip/network/Makefile.in
new file mode 100644
index 0000000000..aaaf460aa1
--- /dev/null
+++ b/c/src/libchip/network/Makefile.in
@@ -0,0 +1,57 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+LIBNAME=libnetchip.a
+LIB=${ARCH}/${LIBNAME}
+
+C_PIECES=\
+ sonic
+
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+INSTALLED_H_FILES=$(srcdir)/sonic.h
+SRCS=$(C_FILES) $(H_FILES) $(SYS_H_FILES) $(RTEMS_H_FILES) $(PRIVATE_H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/lib.cfg
+
+#
+# Add local stuff here using +=
+#
+
+DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
+ -DDIAGNOSTIC -DBOOTP_COMPAT
+CPPFLAGS +=
+CFLAGS += $(LIBC_DEFINES)
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS += $(LIB)
+CLOBBER_ADDITIONS +=
+
+all: ${ARCH} preinstall $(LIB)
+ $(INSTALL_VARIANT) -m 644 ${LIB} ${PROJECT_RELEASE}/lib
+
+$(LIB): $(SRCS) ${OBJS}
+ $(make-library)
+
+# Install the library, appending _g or _p as appropriate.
+# for include files, just use $(INSTALL)
+preinstall:
+ $(INSTALL) -m 444 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/libchip
+
+
diff --git a/c/src/libchip/network/README b/c/src/libchip/network/README
new file mode 100644
index 0000000000..fd5853ef16
--- /dev/null
+++ b/c/src/libchip/network/README
@@ -0,0 +1,16 @@
+#
+# $Id$
+#
+
+This is the network interface controller portion of the libchip library.
+This directory contains the source code for reusable TCP/IP network driver
+support code. Each driver has its own configuration table and its
+chip specific attach routine must be called by a board specific
+attach routine. The board specific chip routine passes the chip
+configuration and network configuration to the resuable device driver.
+
+The reusable chip drivers do not directly access the controller.
+They access the registers on the controller via a set of
+functions which are provided by the BSP. These functions set and get
+general registers and data buffers.
+
diff --git a/c/src/libchip/network/README.sonic b/c/src/libchip/network/README.sonic
new file mode 100644
index 0000000000..ef9641d6a2
--- /dev/null
+++ b/c/src/libchip/network/README.sonic
@@ -0,0 +1,21 @@
+#
+# $Id$
+#
+
+This SONIC driver does not make any attempt to support the SONIC chip
+in any of the following modes:
+
+ + 16-bit
+ + little endian
+
+It does not attempt to handle SONIC's older than Revision C. There is
+a bug in chips before that revision that must be handled in the driver.
+
+The configuration table should be discussed here but if you look in the
+include file for the sonic, it is reasonably obvious. :)
+
+The performance impact of transforming this driver into libchip format
+was minimal.
+
+The powerpc/dmv177 BSP uses this driver and can serve as an example
+configuration table.
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c b/c/src/libchip/network/sonic.c
index dd7cefe030..2dd8e32e79 100644
--- a/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c
+++ b/c/src/libchip/network/sonic.c
@@ -1,62 +1,33 @@
/*
- *******************************************************************
- *******************************************************************
- ** **
- ** RTEMS NETWORK DRIVER FOR NATIONAL DP83932 `SONIC' **
- ** SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER **
- ** **
- *******************************************************************
- *******************************************************************
- */
-
-/*
- * $Revision$ $Date$ $Author$
- * $State$
- * $Id$
- */
-
-/*
+ * RTEMS NETWORK DRIVER FOR NATIONAL DP83932 `SONIC'
+ * SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER
+ *
+ * REUSABLE CHIP DRIVER
+ *
* References:
- * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
- * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
- * 1995.
*
- * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
- * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
- * RRD-B30M75, National Semiconductor, March, 1991.
+ * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
+ * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
+ * 1995.
*
- * 3) SVME/DMV-171 Single Board Computer Documentation Package, #805905,
- * DY 4 Systems Inc., Kanata, Ontario, September, 1996.
+ * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
+ * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
+ * RRD-B30M75, National Semiconductor, March, 1991.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
*/
-#include <bsp.h> /* XXX JRS changed order */
-#include "sonic.h"
+#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
-
-/***** CONFIGURATION ****/
-typedef void (*sonic_write_register_t)(
- void *base,
- unsigned32 regno,
- unsigned32 value
-);
-
-typedef unsigned32 (*sonic_read_register_t)(
- void *base,
- unsigned32 regno
-);
-
-typedef struct {
- unsigned32 base_address;
- unsigned32 vector;
- unsigned32 dcr_value;
- unsigned32 dc2_value;
- unsigned32 tda_count;
- unsigned32 rda_count;
- sonic_write_register_t write_register;
- sonic_read_register_t read_register;
-} sonic_configuration_t;
-
-/***** CONFIGURATION ****/
+#include <libchip/sonic.h>
#include <stdio.h>
@@ -75,6 +46,12 @@ typedef struct {
#include <netinet/if_ether.h>
/*
+ * XXX fix this
+ */
+
+void *set_vector(void *, unsigned32, unsigned32);
+
+/*
* Debug levels
*
*/
@@ -108,12 +85,6 @@ typedef struct {
#endif
/*
- * XXX
- */
-
-#include <dmv170.h>
-
-/*
* Use the top line if you want more symbols.
*/
@@ -1499,7 +1470,7 @@ sonic_ioctl (struct ifnet *ifp, int command, caddr_t data)
*/
int
-rtems_sonic_driver_attach_chip (
+rtems_sonic_driver_attach (
struct rtems_bsdnet_ifconfig *config,
sonic_configuration_t *chip
)
@@ -1656,106 +1627,3 @@ char SONIC_Reg_name[64][6]= {
"DCR2" /* 0x3F */
};
#endif
-
-void dmv177_sonic_write_register(
- void *base,
- unsigned32 regno,
- unsigned32 value
-)
-{
- volatile unsigned32 *p = base;
-
-#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
- printf( "%p Write 0x%04x to %s (0x%02x)\n",
- &p[regno], value, SONIC_Reg_name[regno], regno );
- fflush( stdout );
-#endif
- p[regno] = value;
-}
-
-unsigned32 dmv177_sonic_read_register(
- void *base,
- unsigned32 regno
-)
-{
- volatile unsigned32 *p = base;
- unsigned32 value;
-
- value = p[regno];
-#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
- printf( "%p Read 0x%04x from %s (0x%02x)\n",
- &p[regno], value, SONIC_Reg_name[regno], regno );
- fflush( stdout );
-#endif
- return value;
-}
-/******** DMV177 SPECIFIC INFORMATION ***********/
-/*
- * Default sizes of transmit and receive descriptor areas
- */
-#define RDA_COUNT 20 /* 20 */
-#define TDA_COUNT 20 /* 10 */
-
-/*
- * Default device configuration register values
- * Conservative, generic values.
- * DCR:
- * No extended bus mode
- * Unlatched bus retry
- * Programmable outputs unused
- * Asynchronous bus mode
- * User definable pins unused
- * No wait states (access time controlled by DTACK*)
- * 32-bit DMA
- * Empty/Fill DMA mode
- * Maximum Transmit/Receive FIFO
- * DC2:
- * Extended programmable outputs unused
- * Normal HOLD request
- * Packet compress output unused
- * No reject on CAM match
- */
-#define SONIC_DCR \
- (DCR_DW32 | DCR_WAIT0 | DCR_PO0 | DCR_PO1 | DCR_RFT24 | DCR_TFT28)
-#ifndef SONIC_DCR
-# define SONIC_DCR (DCR_DW32 | DCR_TFT28)
-#endif
-#ifndef SONIC_DC2
-# define SONIC_DC2 (0)
-#endif
-
-/*
- * Default location of device registers
- */
-#ifndef SONIC_BASE_ADDRESS
-# define SONIC_BASE_ADDRESS 0xF3000000
-# warning "Using default SONIC_BASE_ADDRESS."
-#endif
-
-/*
- * Default interrupt vector
- */
-#ifndef SONIC_VECTOR
-# define SONIC_VECTOR 1
-# warning "Using default SONIC_VECTOR."
-#endif
-
-sonic_configuration_t dmv177_sonic_configuration = {
- SONIC_BASE_ADDRESS, /* base address */
- SONIC_VECTOR, /* vector number */
- SONIC_DCR, /* DCR register value */
- SONIC_DC2, /* DC2 register value */
- TDA_COUNT, /* number of transmit descriptors */
- RDA_COUNT, /* number of receive descriptors */
- dmv177_sonic_write_register,
- dmv177_sonic_read_register
-};
-
-int rtems_sonic_driver_attach (struct rtems_bsdnet_ifconfig *config)
-{
- return rtems_sonic_driver_attach_chip ( config, &dmv177_sonic_configuration );
-
-}
-
-/******** DMV177 SPECIFIC INFORMATION ***********/
-
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h b/c/src/libchip/network/sonic.h
index 7ce0eccebb..47f50d3356 100644
--- a/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h
+++ b/c/src/libchip/network/sonic.h
@@ -1,24 +1,58 @@
/*
- ******************************************************************.
- *******************************************************************
- ** **
- ** DECLARATIONS FOR NATIONAL DP83932 `SONIC' **
- ** SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER **
- ** **
- *******************************************************************
- *******************************************************************
+ * RTEMS NETWORK DRIVER FOR NATIONAL DP83932 `SONIC'
+ * SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER
+ *
+ * REUSABLE CHIP DRIVER CONFIGURATION
+ *
+ * References:
+ *
+ * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
+ * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
+ * 1995.
+ *
+ * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
+ * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
+ * RRD-B30M75, National Semiconductor, March, 1991.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
*/
+#ifndef _SONIC_DP83932_
+#define _SONIC_DP83932_
+
/*
- * $Revision$ $Date$ $Author$
- * $State$
- * $Id$
+ * Configuration Information
*/
-#ifndef _SONIC_DP83932_
-#define _SONIC_DP83932_
+typedef void (*sonic_write_register_t)(
+ void *base,
+ unsigned32 regno,
+ unsigned32 value
+);
-#include <bsp.h>
+typedef unsigned32 (*sonic_read_register_t)(
+ void *base,
+ unsigned32 regno
+);
+
+typedef struct {
+ unsigned32 base_address;
+ unsigned32 vector;
+ unsigned32 dcr_value;
+ unsigned32 dc2_value;
+ unsigned32 tda_count;
+ unsigned32 rda_count;
+ sonic_write_register_t write_register;
+ sonic_read_register_t read_register;
+} sonic_configuration_t;
/*
******************************************************************
@@ -370,4 +404,13 @@ typedef volatile CamDescriptor_t *CamDescriptorPointer_t;
/* and the driver can process it */
#define RDA_FREE 0xFFFF /* SONIC can use it */
+/*
+ * Attatch routine
+ */
+
+int rtems_sonic_driver_attach (
+ struct rtems_bsdnet_ifconfig *config,
+ sonic_configuration_t *chip
+);
+
#endif /* _SONIC_DP83932_ */
diff --git a/c/src/wrapup/Makefile.in b/c/src/wrapup/Makefile.in
index 5e73848490..d3e0f76ac9 100644
--- a/c/src/wrapup/Makefile.in
+++ b/c/src/wrapup/Makefile.in
@@ -24,6 +24,7 @@ SRCS=$(wildcard $(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a) \
$(wildcard $(PROJECT_RELEASE)/lib/libcpu$(LIB_VARIANT).a) \
$(wildcard $(PROJECT_RELEASE)/lib/librtcio$(LIB_VARIANT).a) \
$(wildcard $(PROJECT_RELEASE)/lib/libserialio$(LIB_VARIANT).a) \
+ $(wildcard $(PROJECT_RELEASE)/lib/libnetchip$(LIB_VARIANT).a) \
$(PROJECT_RELEASE)/lib/libcsupport$(LIB_VARIANT).a \
$(PROJECT_RELEASE)/lib/libmisc$(LIB_VARIANT).a \
$(wildcard $(PROJECT_RELEASE)/lib/rtems-ctor$(LIB_VARIANT).o) \