summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.in3
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/Makefile.in2
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/wd80x3.h123
-rw-r--r--c/src/lib/libbsp/i386/pc386/network/Makefile.in54
-rw-r--r--c/src/lib/libbsp/i386/pc386/network/network.c554
-rw-r--r--c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in5
6 files changed, 738 insertions, 3 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.in b/c/src/lib/libbsp/i386/pc386/Makefile.in
index 763c759d26..426b5a6dbe 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.in
@@ -13,4 +13,5 @@ include $(RTEMS_ROOT)/make/directory.cfg
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
-SUB_DIRS=include tools start startup clock console timer pc386dev wrapup
+SUB_DIRS=include tools start startup clock console timer pc386dev network \
+ wrapup
diff --git a/c/src/lib/libbsp/i386/pc386/include/Makefile.in b/c/src/lib/libbsp/i386/pc386/include/Makefile.in
index 10cf41f1a3..653bab5067 100644
--- a/c/src/lib/libbsp/i386/pc386/include/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/include/Makefile.in
@@ -9,7 +9,7 @@ RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(srcdir)/crt.h \
- $(srcdir)/pc386uart.h $(srcdir)/pcibios.h
+ $(srcdir)/pc386uart.h $(srcdir)/pcibios.h $(srcdir)/wd80x3.h
#
# Equate files are for including from assembly preprocessed by
diff --git a/c/src/lib/libbsp/i386/pc386/include/wd80x3.h b/c/src/lib/libbsp/i386/pc386/include/wd80x3.h
new file mode 100644
index 0000000000..4bad00993c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/include/wd80x3.h
@@ -0,0 +1,123 @@
+
+/* Register descriptions */
+/* Controller DP8390. */
+
+#define DATAPORT 0x10 /* Port Window. */
+#define RESET 0x1f /* Issue a read for reset */
+#define W83CREG 0x00 /* I/O port definition */
+#define ADDROM 0x08
+
+/* page 0 read or read/write registers */
+
+#define CMDR 0x00+RO
+#define CLDA0 0x01+RO /* current local dma addr 0 for read */
+#define CLDA1 0x02+RO /* current local dma addr 1 for read */
+#define BNRY 0x03+RO /* boundary reg for rd and wr */
+#define TSR 0x04+RO /* tx status reg for rd */
+#define NCR 0x05+RO /* number of collision reg for rd */
+#define FIFO 0x06+RO /* FIFO for rd */
+#define ISR 0x07+RO /* interrupt status reg for rd and wr */
+#define CRDA0 0x08+RO /* current remote dma address 0 for rd */
+#define CRDA1 0x09+RO /* current remote dma address 1 for rd */
+#define RSR 0x0C+RO /* rx status reg for rd */
+#define CNTR0 0x0D+RO /* tally cnt 0 for frm alg err for rd */
+#define CNTR1 RO+0x0E /* tally cnt 1 for crc err for rd */
+#define CNTR2 0x0F+RO /* tally cnt 2 for missed pkt for rd */
+
+/* page 0 write registers */
+
+#define PSTART 0x01+RO /* page start register */
+#define PSTOP 0x02+RO /* page stop register */
+#define TPSR 0x04+RO /* tx start page start reg */
+#define TBCR0 0x05+RO /* tx byte count 0 reg */
+#define TBCR1 0x06+RO /* tx byte count 1 reg */
+#define RSAR0 0x08+RO /* remote start address reg 0 */
+#define RSAR1 0x09+RO /* remote start address reg 1 */
+#define RBCR0 0x0A+RO /* remote byte count reg 0 */
+#define RBCR1 0x0B+RO /* remote byte count reg 1 */
+#define RCR 0x0C+RO /* rx configuration reg */
+#define TCR 0x0D+RO /* tx configuration reg */
+#define DCR RO+0x0E /* data configuration reg */
+#define IMR 0x0F+RO /* interrupt mask reg */
+
+/* page 1 registers */
+
+#define PAR 0x01+RO /* physical addr reg base for rd and wr */
+#define CURR 0x07+RO /* current page reg for rd and wr */
+#define MAR 0x08+RO /* multicast addr reg base fro rd and WR */
+#define MARsize 8 /* size of multicast addr space */
+
+/*-----W83CREG command bits-----*/
+#define MSK_RESET 0x80 /* W83CREG masks */
+#define MSK_ENASH 0x40
+#define MSK_DECOD 0x3F /* memory decode bits, corresponding */
+ /* to SA 18-13. SA 19 assumed to be 1 */
+
+/*-----CMDR command bits-----*/
+#define MSK_STP 0x01 /* stop the chip */
+#define MSK_STA 0x02 /* start the chip */
+#define MSK_TXP 0x04 /* initial txing of a frm */
+#define MSK_RRE 0x08 /* remote read */
+#define MSK_RWR 0x10 /* remote write */
+#define MSK_RD2 0x20 /* no DMA used */
+#define MSK_PG0 0x00 /* select register page 0 */
+#define MSK_PG1 0x40 /* select register page 1 */
+#define MSK_PG2 0x80 /* select register page 2 */
+
+/*-----ISR and TSR status bits-----*/
+#define MSK_PRX 0x01 /* rx with no error */
+#define MSK_PTX 0x02 /* tx with no error */
+#define MSK_RXE 0x04 /* rx with error */
+#define MSK_TXE 0x08 /* tx with error */
+#define MSK_OVW 0x10 /* overwrite warning */
+#define MSK_CNT 0x20 /* MSB of one of the tally counters is set */
+#define MSK_RDC 0x40 /* remote dma completed */
+#define MSK_RST 0x80 /* reset state indicator */
+
+/*-----DCR command bits-----*/
+#define MSK_WTS 0x01 /* word transfer mode selection */
+#define MSK_BOS 0x02 /* byte order selection */
+#define MSK_LAS 0x04 /* long addr selection */
+#define MSK_BMS 0x08 /* burst mode selection */
+#define MSK_ARM 0x10 /* autoinitialize remote */
+#define MSK_FT00 0x00 /* burst lrngth selection */
+#define MSK_FT01 0x20 /* burst lrngth selection */
+#define MSK_FT10 0x40 /* burst lrngth selection */
+#define MSK_FT11 0x60 /* burst lrngth selection */
+
+/*-----RCR command bits-----*/
+#define MSK_SEP 0x01 /* save error pkts */
+#define MSK_AR 0x02 /* accept runt pkt */
+#define MSK_AB 0x04 /* 8390 RCR */
+#define MSK_AM 0x08 /* accept multicast */
+#define MSK_PRO 0x10 /* accept all pkt with physical adr */
+#define MSK_MON 0x20 /* monitor mode */
+
+/*-----TCR command bits-----*/
+#define MSK_CRC 0x01 /* inhibit CRC, do not append crc */
+#define MSK_LOOP 0x02 /* set loopback mode */
+#define MSK_BCST 0x04 /* Accept broadcasts */
+#define MSK_LB01 0x06 /* encoded loopback control */
+#define MSK_ATD 0x08 /* auto tx disable */
+#define MSK_OFST 0x10 /* collision offset enable */
+
+/*-----receive status bits-----*/
+#define SMK_PRX 0x01 /* rx without error */
+#define SMK_CRC 0x02 /* CRC error */
+#define SMK_FAE 0x04 /* frame alignment error */
+#define SMK_FO 0x08 /* FIFO overrun */
+#define SMK_MPA 0x10 /* missed pkt */
+#define SMK_PHY 0x20 /* physical/multicase address */
+#define SMK_DIS 0x40 /* receiver disable. set in monitor mode */
+#define SMK_DEF 0x80 /* deferring */
+
+/*-----transmit status bits-----*/
+#define SMK_PTX 0x01 /* tx without error */
+#define SMK_DFR 0x02 /* non deferred tx */
+#define SMK_COL 0x04 /* tx collided */
+#define SMK_ABT 0x08 /* tx abort because of excessive collisions */
+#define SMK_CRS 0x10 /* carrier sense lost */
+#define SMK_FU 0x20 /* FIFO underrun */
+#define SMK_CDH 0x40 /* collision detect heartbeat */
+#define SMK_OWC 0x80 /* out of window collision */
+
diff --git a/c/src/lib/libbsp/i386/pc386/network/Makefile.in b/c/src/lib/libbsp/i386/pc386/network/Makefile.in
new file mode 100644
index 0000000000..262e5be2b2
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/network/Makefile.in
@@ -0,0 +1,54 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/network.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=network
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# 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 +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/i386/pc386/network/network.c b/c/src/lib/libbsp/i386/pc386/network/network.c
new file mode 100644
index 0000000000..a37b9cf88c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/network/network.c
@@ -0,0 +1,554 @@
+/*
+ * RTEMS/KA9Q driver for WD8003 Ethernet Controller
+ *
+ *
+ * $Id$
+ */
+#include <bsp.h>
+#include <wd80x3.h>
+#include <rtems/error.h>
+#include <ka9q/rtems_ka9q.h>
+#include <ka9q/global.h>
+#include <ka9q/enet.h>
+#include <ka9q/iface.h>
+#include <ka9q/netuser.h>
+#include <ka9q/trace.h>
+#include <ka9q/commands.h>
+#include <ka9q/domain.h>
+#include "irq.h"
+
+#define ET_MINLEN 60 /* minimum message length */
+
+/*
+ * Number of SCCs supported by this driver
+ */
+#define NSCCDRIVER 1
+
+/*
+ * Default number of buffer descriptors set aside for this driver.
+ * The number of transmit buffer descriptors has to be quite large
+ * since a single frame often uses four or more buffer descriptors.
+ */
+
+#define RX_BUF_COUNT 15
+#define TX_BUF_COUNT 4
+#define TX_BD_PER_BUF 4
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ * This must *not* be the same event used by the KA9Q task synchronization.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * Receive buffer size -- Allow for a full ethernet packet plus a pointer
+ */
+#define RBUF_SIZE (1520 + sizeof (struct iface *))
+
+/*
+ * Hardware-specific storage
+ */
+typedef struct {
+ struct mbuf **rxMbuf;
+ struct mbuf **txMbuf;
+ unsigned int port;
+ char *base;
+ unsigned long bpar;
+ unsigned int irno;
+ int rxBdCount;
+ int txBdCount;
+ int txBdHead;
+ int txBdTail;
+ int txBdActiveCount;
+ struct iface *iface;
+ rtems_id txWaitTid;
+
+ /*
+ * Statistics
+ */
+ unsigned long rxInterrupts;
+ unsigned long rxNotFirst;
+ unsigned long rxNotLast;
+ unsigned long rxGiant;
+ unsigned long rxNonOctet;
+ unsigned long rxRunt;
+ unsigned long rxBadCRC;
+ unsigned long rxOverrun;
+ unsigned long rxCollision;
+
+ unsigned long txInterrupts;
+ unsigned long txDeferred;
+ unsigned long txHeartbeat;
+ unsigned long txLateCollision;
+ unsigned long txRetryLimit;
+ unsigned long txUnderrun;
+ unsigned long txLostCarrier;
+ unsigned long txRawWait;
+}wd80x3EnetDriver;
+
+#define RO 0x10
+
+#define SHATOT (8*1024) /* size of shared memory */
+#define SHAPAGE 256 /* shared memory information */
+#define MAXSIZ 1536 /*(MAXBUF - MESSH_SZ)*/
+#define OUTPAGE ((SHATOT-(MAXSIZ+SHAPAGE-1))/SHAPAGE)
+
+static unsigned long loopc;
+
+static wd80x3EnetDriver wd8003EnetDriver[NSCCDRIVER];
+
+/*
+ * WD8003 interrupt handler
+ */
+static rtems_isr
+wd8003Enet_interrupt_handler (rtems_vector_number v)
+{
+ unsigned int tport, nowTicks, bootTicks;
+ unsigned char status, status2;
+
+ struct iface *iface = (struct iface *)(wd8003EnetDriver[0].iface);
+ wd80x3EnetDriver *dp = (wd80x3EnetDriver *)&wd8003EnetDriver[0];
+ struct mbuf *bp;
+ unsigned int i2;
+ unsigned int len;
+ unsigned char start, next, current;
+ char *shp, *temp;
+
+ tport = wd8003EnetDriver[0].port ;
+
+ PC386_disableIrq(wd8003EnetDriver[0].irno);
+ PC386_ackIrq(wd8003EnetDriver[0].irno);
+ asm volatile("sti");
+
+ /*
+ * Drop chips interrupt
+ */
+ outport_byte(tport+IMR, 0x00);
+
+ /*
+ * Read status
+ */
+ inport_byte(tport+ISR, status);
+
+ /*
+ * Ring overwrite
+ */
+
+ if (status & MSK_OVW){
+ outport_byte(tport+CMDR, MSK_STP + MSK_RD2); /* stop 8390 */
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &bootTicks );
+ while(nowTicks < bootTicks+loopc) /* 2ms delay */
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &nowTicks );
+ outport_byte(tport+RBCR0, 0); /* clear byte count */
+ outport_byte(tport+RBCR1, 0);
+ inport_byte(tport+ISR, status2);
+ status |= (status2 & (MSK_PTX+MSK_TXE)) ; /* TX status */
+ outport_byte(tport+TCR, MSK_LOOP); /* loopback mode */
+ outport_byte(tport+CMDR, MSK_STA + MSK_RD2); /* start */
+ }
+
+ /*
+ * Frame received?
+ */
+ while (status & (MSK_PRX+MSK_RXE)) {
+ outport_byte(tport+ISR, status & (MSK_PRX+MSK_RXE));
+ inport_byte(tport+BNRY, start);
+ start += 1;
+ shp = dp->base + 1 + (SHAPAGE * start);
+ next = *shp++;
+ len = *((short *)shp)++ - 4;
+ if (start >= OUTPAGE || next >= OUTPAGE)
+ break;
+ bp = ambufw (RBUF_SIZE);
+ bp->data += sizeof (struct iface *);
+ temp = bp->data;
+ bp->cnt = len;
+
+ if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){
+ memcpy(temp, shp, i2);
+ len -= i2;
+ temp += i2;
+ shp = dp->base;
+ }
+ memcpy(temp, shp, len);
+
+ net_route (iface, &bp);
+ outport_byte(tport+BNRY, next-1);
+ outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
+ inport_byte(tport+CURR, current);
+ outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
+ if (current == next)
+ break;
+ }
+
+ /*
+ * Ring overwrite
+ */
+ if (status & MSK_OVW) {
+ outport_byte(tport+ISR, MSK_OVW); /* reset IR */
+ outport_byte(tport+TCR, 0); /* out of loopback */
+ if ((status & (MSK_PTX+MSK_TXE)) == 0)
+ outport_byte(tport+CMDR, MSK_TXP + MSK_RD2); /* resend */
+ }
+
+ /*
+ * Enable chip interrupts
+ */
+ outport_byte(tport+IMR, 0x15);
+ asm volatile("cli");
+ PC386_enableIrq(wd8003EnetDriver[0].irno);
+
+}
+
+/*
+ * Initialize the ethernet hardware
+ */
+static void
+wd8003Enet_initialize_hardware (wd80x3EnetDriver *dp, int broadcastFlag)
+{
+ int i1, ultra;
+ char cc1, cc2;
+ unsigned char temp;
+ rtems_status_code sc;
+ unsigned int tport;
+
+ tport = dp->port;
+
+ /* address from board ROM */
+ inport_byte(tport+0x04, temp);
+ outport_byte(tport+0x04, temp & 0x7f);
+
+ for (i1=cc2=0; i1<8; i1++) {
+ inport_byte(tport + ADDROM + i1, cc1);
+ cc2 += cc1;
+ if (i1 < 6)
+ dp->iface->hwaddr[i1] = cc1;
+ }
+
+ inport_byte(tport+0x04, temp);
+ outport_byte(tport+0x04, temp | 0x80); /* alternate registers */
+ outport_byte(tport+W83CREG, MSK_RESET); /* reset board, set buffer */
+ outport_byte(tport+W83CREG, 0);
+ outport_byte(tport+W83CREG, MSK_ENASH + (int)((dp->bpar>>13)&0x3f));
+
+ outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
+ cc1 = MSK_BMS + MSK_FT10; /* configure 8 or 16 bits */
+
+ inport_byte(tport+0x07, temp) ;
+
+ ultra = ((temp & 0xf0) == 0x20 || (temp & 0xf0) == 0x40);
+ if (ultra)
+ cc1 = MSK_WTS + MSK_BMS + MSK_FT10;
+ outport_byte(tport+DCR, cc1);
+ outport_byte(tport+RBCR0, 0);
+ outport_byte(tport+RBCR1, 0);
+ outport_byte(tport+RCR, MSK_MON); /* disable the rxer */
+ outport_byte(tport+TCR, 0); /* normal operation */
+ outport_byte(tport+PSTOP, OUTPAGE); /* init PSTOP */
+ outport_byte(tport+PSTART, 0); /* init PSTART */
+ outport_byte(tport+BNRY, -1); /* init BNRY */
+ outport_byte(tport+ISR, -1); /* clear IR's */
+ outport_byte(tport+IMR, 0x15); /* 0x17 enable interrupt */
+
+ outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
+
+ for (i1=0; i1<6; i1++) /* initial physical addr */
+ outport_byte(tport+PAR+i1, dp->iface->hwaddr[i1]);
+
+ for (i1=0; i1<MARsize; i1++) /* clear multicast */
+ outport_byte(tport+MAR+i1, 0);
+ outport_byte(tport+CURR, 0); /* init current packet */
+
+ outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
+ outport_byte(tport+CMDR, MSK_STA + MSK_RD2); /* put 8390 on line */
+ outport_byte(tport+RCR, MSK_AB); /* MSK_AB accept broadcast */
+
+ if (ultra) {
+ inport_byte(tport+0x0c, temp);
+ outport_byte(tport+0x0c, temp | 0x80);
+ outport_byte(tport+0x05, 0x80);
+ outport_byte(tport+0x06, 0x01);
+ }
+
+ /*
+ * Set up interrupts
+ */
+ sc = PC386_installRtemsIrqHandler(dp->irno, wd8003Enet_interrupt_handler);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't attach interrupt handler: %s\n",
+ rtems_status_text (sc));
+}
+
+
+/*
+ * Send raw packet (caller provides header).
+ * This code runs in the context of the interface transmit
+ * task or in the context of the network task.
+ */
+static int
+wd8003Enet_raw (struct iface *iface, struct mbuf **bpp)
+{
+ wd80x3EnetDriver *dp = &wd8003EnetDriver[iface->dev];
+ struct mbuf *bp;
+ unsigned int len, tport;
+ char *shp;
+
+ tport = dp->port;
+
+ /*
+ * Fill in some logging data
+ */
+ iface->rawsndcnt++;
+ iface->lastsent = secclock ();
+ dump (iface, IF_TRACE_OUT, *bpp);
+
+ /*
+ * It would not do to have two tasks active in the transmit
+ * loop at the same time.
+ * The blocking is simple-minded since the odds of two tasks
+ * simultaneously attempting to use this code are low. The only
+ * way that two tasks can try to run here is:
+ * 1) Task A enters this code and ends up having to
+ * wait for a transmit buffer descriptor.
+ * 2) Task B gains control and tries to transmit a packet.
+ * The RTEMS/KA9Q scheduling semaphore ensures that there
+ * are no race conditions associated with manipulating the
+ * txWaitTid variable.
+ */
+
+ if (dp->txWaitTid) {
+ dp->txRawWait++;
+ while (dp->txWaitTid)
+ rtems_ka9q_ppause (10);
+ }
+
+ if (dp->txWaitTid == 0)
+ rtems_task_ident (0, 0, &dp->txWaitTid);
+
+ bp = *bpp;
+ len = 0;
+ shp = dp->base + (SHAPAGE * OUTPAGE);
+
+ /*rtems_interrupt_disable(level);*/
+
+ for (;;){
+ len += bp->cnt;
+ memcpy(shp, (char *)bp->data, bp->cnt);
+ shp += bp->cnt ;
+ if ((bp = bp->next) == NULL)
+ break;
+ }
+
+ free_p(bpp);
+
+ if (len < ET_MINLEN) len = ET_MINLEN;
+ outport_byte(tport+TBCR0, len);
+ outport_byte(tport+TBCR1, (len >> 8) );
+ outport_byte(tport+TPSR, OUTPAGE);
+ outport_byte(tport+CMDR, MSK_TXP + MSK_RD2);
+
+ /*
+ * Show that we've finished with the packet
+ */
+ dp->txWaitTid = 0;
+ return 0;
+
+}
+
+
+/*
+ * Shut down the interface
+ * FIXME: This is a pretty simple-minded routine. It doesn't worry
+ * about cleaning up mbufs, shutting down daemons, etc.
+ */
+static int
+wd8003Enet_stop (struct iface *iface)
+{
+ unsigned int tport;
+ unsigned char temp;
+ /*
+ * Stop the transmitter
+ */
+ tport=wd8003EnetDriver[0].port ;
+ inport_byte(tport+0x04,temp);
+ outport_byte(tport+0x04, temp & 0x7f);
+ outport_byte(tport + CMDR, MSK_STP + MSK_RD2);
+ return 0;
+}
+
+/*
+ * Show interface statistics
+ */
+static void
+wd8003Enet_show (struct iface *iface)
+{
+ printf (" Rx Interrupts:%-8lu", wd8003EnetDriver[0].rxInterrupts);
+ printf (" Not First:%-8lu", wd8003EnetDriver[0].rxNotFirst);
+ printf (" Not Last:%-8lu\n", wd8003EnetDriver[0].rxNotLast);
+ printf (" Giant:%-8lu", wd8003EnetDriver[0].rxGiant);
+ printf (" Runt:%-8lu", wd8003EnetDriver[0].rxRunt);
+ printf (" Non-octet:%-8lu\n", wd8003EnetDriver[0].rxNonOctet);
+ printf (" Bad CRC:%-8lu", wd8003EnetDriver[0].rxBadCRC);
+ printf (" Overrun:%-8lu", wd8003EnetDriver[0].rxOverrun);
+ printf (" Collision:%-8lu\n", wd8003EnetDriver[0].rxCollision);
+ printf (" Tx Interrupts:%-8lu", wd8003EnetDriver[0].txInterrupts);
+ printf (" Deferred:%-8lu", wd8003EnetDriver[0].txDeferred);
+ printf (" Missed Hearbeat:%-8lu\n", wd8003EnetDriver[0].txHeartbeat);
+ printf (" No Carrier:%-8lu", wd8003EnetDriver[0].txLostCarrier);
+ printf ("Retransmit Limit:%-8lu", wd8003EnetDriver[0].txRetryLimit);
+ printf (" Late Collision:%-8lu\n", wd8003EnetDriver[0].txLateCollision);
+ printf (" Underrun:%-8lu", wd8003EnetDriver[0].txUnderrun);
+ printf (" Raw output wait:%-8lu\n", wd8003EnetDriver[0].txRawWait);
+}
+
+/*
+ * Attach an WD8003 driver to the system
+ * This is the only `extern' function in the driver.
+ *
+ * argv[0]: interface label, e.g., "rtems"
+ * The remainder of the arguemnts are key/value pairs:
+ * mtu ## -- maximum transmission unit, default 1500
+ * broadcast y/n -- accept or ignore broadcast packets, default yes
+ * rbuf ## -- Set number of receive buffer descriptors
+ * rbuf ## -- Set number of transmit buffer descriptors
+ * ip ###.###.###.### -- IP address
+ * ether ##:##:##:##:##:## -- Ethernet address
+ * irno -- Set controller irq
+ * port -- Set io port
+ * bpar -- Set RAM address
+ */
+int
+rtems_ka9q_driver_attach (int argc, char *argv[], void *p)
+{
+ struct iface *iface;
+ wd80x3EnetDriver *dp;
+ char *cp;
+ int i;
+ int argIndex;
+ int broadcastFlag;
+ char cbuf[30];
+
+ /*
+ * Find a free driver
+ */
+ for (i = 0 ; i < NSCCDRIVER ; i++) {
+ if (wd8003EnetDriver[i].iface == NULL)
+ break;
+ }
+ if (i >= NSCCDRIVER) {
+ printf ("Too many SCC drivers.\n");
+ return -1;
+ }
+ if (if_lookup (argv[0]) != NULL) {
+ printf ("Interface %s already exists\n", argv[0]);
+ return -1;
+ }
+ dp = &wd8003EnetDriver[i];
+
+ /*
+ * Create an inteface descriptor
+ */
+ iface = callocw (1, sizeof *iface);
+ iface->name = strdup (argv[0]);
+
+ /*
+ * Set default values
+ */
+ broadcastFlag = 1;
+ dp->txWaitTid = 0;
+ dp->rxBdCount = RX_BUF_COUNT;
+ dp->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+ dp->irno = 5;
+ dp->port = 0x240;
+ dp->base = 0xD0000;
+ dp->bpar = 0xD0000;
+ iface->mtu = 1500;
+ iface->addr = Ip_addr;
+ iface->hwaddr = mallocw (EADDR_LEN);
+ memset (iface->hwaddr, 0x08, EADDR_LEN);
+
+ /*
+ * Parse arguments
+ */
+ for (argIndex = 1 ; argIndex < (argc - 1) ; argIndex++) {
+ if (strcmp ("mtu", argv[argIndex]) == 0) {
+ iface->mtu = atoi (argv[++argIndex]);
+ }
+ else if (strcmp ("broadcast", argv[argIndex]) == 0) {
+ if (*argv[++argIndex] == 'n')
+ broadcastFlag = 0;
+ }
+ else if (strcmp ("rbuf", argv[argIndex]) == 0) {
+ dp->rxBdCount = atoi (argv[++argIndex]);
+ }
+ else if (strcmp ("tbuf", argv[argIndex]) == 0) {
+ dp->txBdCount = atoi (argv[++argIndex]) * TX_BD_PER_BUF;
+ }
+ else if (strcmp ("ip", argv[argIndex]) == 0) {
+ iface->addr = resolve (argv[++argIndex]);
+ }
+ else if (strcmp ("ether", argv[argIndex]) == 0) {
+ argIndex++;
+ gether (iface->hwaddr, argv[argIndex]);
+ }
+ else if (strcmp ("irno", argv[argIndex]) == 0) {
+ dp->irno = atoi (argv[++argIndex]);
+ }
+ else if (strcmp ("port", argv[argIndex]) == 0) {
+ sscanf(argv[++argIndex], "%x", &(dp->port));
+ }
+ else if (strcmp ("bpar", argv[argIndex]) == 0) {
+ sscanf(argv[++argIndex], "%x", &(dp->bpar));
+ dp->base = (char *)(dp->bpar);
+ }
+ else {
+ printf ("Argument %d (%s) is invalid.\n", argIndex, argv[argIndex]);
+ return -1;
+ }
+ }
+ printf ("Ethernet address: %s\n", pether (cbuf, iface->hwaddr));
+ printf ("Internet address: %s\n", inet_ntoa(iface->addr));
+ printf ("Irno: %X, port: %X, bpar: %X, base: %X\n",dp->irno, dp->port,
+ dp->bpar, dp->base);
+ fflush(stdout);
+ /*
+ * Fill in remainder of interface configuration
+ */
+ iface->dev = i;
+ iface->raw = wd8003Enet_raw;
+ iface->stop = wd8003Enet_stop;
+ iface->show = wd8003Enet_show;
+ dp->iface = iface;
+ setencap (iface, "Ethernet");
+
+ /*
+ * Set up SCC hardware
+ */
+ wd8003Enet_initialize_hardware (dp, broadcastFlag);
+ fflush(stdout);
+
+ /*
+ * Chain onto list of interfaces
+ */
+ iface->next = Ifaces;
+ Ifaces = iface;
+
+ /* calibrate a delay loop for 2 milliseconds */
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &loopc );
+ loopc /= 500;
+
+ /*
+ * Start I/O daemons
+ */
+ cp = if_name (iface, " tx");
+ iface->txproc = newproc (cp, 1024, if_tx, iface->dev, iface, NULL, 0);
+ free (cp);
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
index eea0a83229..db155ca01d 100644
--- a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
@@ -8,7 +8,7 @@ VPATH = @srcdir@
RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
-BSP_PIECES=startup clock console timer pc386dev
+BSP_PIECES=startup clock console timer pc386dev network
GENERIC_PIECES=
# bummer; have to use $foreach since % pattern subst rules only replace 1x
@@ -49,3 +49,6 @@ all: ${ARCH} $(SRCS) $(LIB)
# we create here a directory specific to the PC386 BSP to store the BootImage
# files so they can be easily found
mkdir -p ${PROJECT_RELEASE}/BootImgs
+
+
+