summaryrefslogtreecommitdiffstats
path: root/c/src
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-05 00:34:17 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-05 00:34:17 +0000
commitc9c673905abe15cc3139a9cb2b35de559aa8199c (patch)
tree212d728482342b0460420e9dd12fc13108b71507 /c/src
parentb5e4eb746e2f5f001b430783e4300e40ef4c244a (diff)
downloadrtems-c9c673905abe15cc3139a9cb2b35de559aa8199c.tar.bz2
Split SONIC chip into appropriate files for libchip'ing. The portable
portion is now in the libchip tree and the dmv177 configuration is in the dmv177 bsp. The performance impact of libchip'ing this driver was minimal.
Diffstat (limited to 'c/src')
-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) \