summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-07-23 22:13:10 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-07-23 22:13:10 +0000
commitdbaf51a44b8c465ac2f546d21719c66cd889c91f (patch)
tree1559a3f5a2738745564c44b21b6b8959d67c68e6
parent67a2288991ce3662a588ee83c0bea9c9efae5f1e (diff)
downloadrtems-dbaf51a44b8c465ac2f546d21719c66cd889c91f.tar.bz2
Patch from Emmanuel Raguet <raguet@crf.canon.fr>:
Here is a patch for KA9Q stack. This patch contains an Ethernet Driver for Western Digital, some fixes for the UDP and TCP protocols (for endian conversion) and some little programs which allow the test of UDP and TCP sockets via Ethernet. I have tested that on an Intel machine. If someone can test it on a big-endian machine, ...
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
-rw-r--r--c/src/tests/samples/Makefile.in4
-rw-r--r--make/custom/pc386.cfg2
8 files changed, 742 insertions, 5 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
+
+
+
diff --git a/c/src/tests/samples/Makefile.in b/c/src/tests/samples/Makefile.in
index f5541f2df6..5a3c9a4034 100644
--- a/c/src/tests/samples/Makefile.in
+++ b/c/src/tests/samples/Makefile.in
@@ -25,4 +25,6 @@ MP_TESTS = $(MP_TESTS_$(HAS_MP)_V)
FP_TESTS = paranoia
-SUB_DIRS=hello ticker base_sp $(MP_TESTS) $(CPLUSPLUS_TESTS) $(FP_TESTS)
+# socket socket/pgmHost
+SUB_DIRS=hello ticker base_sp
+ $(MP_TESTS) $(CPLUSPLUS_TESTS) $(FP_TESTS)
diff --git a/make/custom/pc386.cfg b/make/custom/pc386.cfg
index 48ed118efe..50a980a703 100644
--- a/make/custom/pc386.cfg
+++ b/make/custom/pc386.cfg
@@ -26,7 +26,7 @@ HAS_MP=no
# This target does NOT support the KA9Q TCP/IP stack so ignore requests
# to enable it.
-HAS_KA9Q=no
+HAS_KA9Q=yes
# This section makes the target dependent options file.