diff options
Diffstat (limited to 'c/src/lib')
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/Makefile.in | 3 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/include/Makefile.in | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/include/wd80x3.h | 123 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/network/Makefile.in | 54 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/network/network.c | 554 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in | 5 |
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 + + + |