summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:53:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit031df3914990db0336a0d386fb53558b05de467e (patch)
tree4661e22f0cdb3f9d06879f0194b77c75f62bac79 /c/src/lib/libbsp/i386/pc386
parentbsps: Move interrupt controller support to bsps (diff)
downloadrtems-031df3914990db0336a0d386fb53558b05de467e.tar.bz2
bsps: Move legacy network drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386')
-rw-r--r--c/src/lib/libbsp/i386/pc386/3c509/3c509.c1538
-rw-r--r--c/src/lib/libbsp/i386/pc386/3c509/3c509.h436
-rw-r--r--c/src/lib/libbsp/i386/pc386/3c509/elink.c82
-rw-r--r--c/src/lib/libbsp/i386/pc386/3c509/elink.h49
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.am8
-rw-r--r--c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c1310
-rw-r--r--c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c647
7 files changed, 4 insertions, 4066 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/3c509/3c509.c b/c/src/lib/libbsp/i386/pc386/3c509/3c509.c
deleted file mode 100644
index 3cf7ec5226..0000000000
--- a/c/src/lib/libbsp/i386/pc386/3c509/3c509.c
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*
- * Ported by Rosimildo da Silva.
- * ConnectTel,Inc.
- * e-mail: rdasilva@connecttel.com
- *
- * MODULE DESCRIPTION:
- * RTEMS driver for 3COM 3C509 Ethernet Card.
- * The driver has been tested on PC with a single network card.
- *
- *
- * This driver was based on the FreeBSD implementation( if_ep.c ) of the 3c5x9
- * family and on the network framework of the RTEMS network driver.
- * ( WD80x3 by Eric Norum ).
- * See notes below:
- *
- ******************************************************************************
- * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Herb Peyerl.
- * 4. The name of Herb Peyerl may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *******************************************************************************
- *
- * RTEMS driver for M68360 WD1 Ethernet
- *
- * W. Eric Norum
- * Saskatchewan Accelerator Laboratory
- * University of Saskatchewan
- * Saskatoon, Saskatchewan, CANADA
- * eric@skatter.usask.ca
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <assert.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/libkern.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <bsp/irq.h>
-
-/* Local includes */
-#include "3c509.h"
-#include "elink.h"
-
-/* #define ET_MINLEN 60 */ /* minimum message length */
-
-/*
- * Number of WDs supported by this driver
- */
-#define NWDDRIVER 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 driver tasks.
- * This must not be any of the events used by the network task synchronization.
- */
-#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
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-
-/*
-#define RBUF_SIZE 1520
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-*/
-
-/* network driver name */
-#define NET_DRIVER_NAME "ep"
-
-/*
- * Per device structure.
- *
- * XXX Note: id_conflicts should either become an array of things we're
- * specifically allowed to conflict with or be subsumed into some
- * more powerful mechanism for detecting and dealing with multiple types
- * of non-fatal conflict. -jkh XXX
- */
-struct isa_device
-{
- int id_id; /* device id */
- int id_unit; /* unit number */
- int id_iobase; /* base i/o address */
- u_int id_irq; /* interrupt request */
-};
-
-struct ep_board
-{
- int epb_addr; /* address of this board */
- char epb_used; /* was this entry already used for configuring ? */
- /* data from EEPROM for later use */
- u_short eth_addr[3]; /* Ethernet address */
- u_short prod_id; /* product ID */
- u_short res_cfg; /* resource configuration */
-};
-
-/*
- * Ethernet software status per interface.
- */
-struct ep_softc
-{
- struct arpcom arpcom; /* Ethernet common part */
- int ep_io_addr; /* i/o bus address */
- struct mbuf *top, *mcur;
- short cur_len;
- u_short ep_connectors; /* Connectors on this card. */
- u_char ep_connector; /* Configured connector. */
- int stat; /* some flags */
- struct ep_board *epb;
- int unit;
-
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
- rtems_vector_number name;
-
- int acceptBroadcast;
-
- short tx_underrun;
- short rx_no_first;
- short rx_no_mbuf;
- short rx_bpf_disc;
- short rx_overrunf;
- short rx_overrunl;
-};
-
-/* static unsigned long loopc; */
-static volatile unsigned long overrun;
-static volatile unsigned long resend;
-static struct ep_softc ep_softc[ NWDDRIVER ];
-static struct isa_device isa_dev[ NWDDRIVER ] =
-{
- { 0, /* device id */
- 0, /* unit number */
- -1, /* base i/o address ??? */
- 0 /* interrupt request ??? */
- }
-};
-
-static u_long ep_unit;
-static int ep_boards;
-struct ep_board ep_board[ EP_MAX_BOARDS + 1];
-static int ep_current_tag = EP_LAST_TAG + 1;
-static char *ep_conn_type[] = {"UTP", "AUI", "???", "BNC"};
-
-#define ep_ftst(f) (sc->stat&(f))
-#define ep_fset(f) (sc->stat|=(f))
-#define ep_frst(f) (sc->stat&=~(f))
-
-/* forward declarations for functions */
-static int ep_attach( struct ep_softc *sc );
-static int ep_isa_probe( struct isa_device *is );
-static void epinit( struct ep_softc *sc );
-static void epread( register struct ep_softc *sc );
-static void epstart( struct ifnet *ifp );
-static void epread( register struct ep_softc *sc );
-static int ep_isa_attach( struct isa_device *is );
-static int get_eeprom_data( int id_port, int offset );
-static void ep_intr( struct ep_softc *sc );
-
-/* external functions */
-extern void Wait_X_ms( unsigned int timeToWait ); /* timer.c ??? */
-
-/**********************************************************************************
- *
- * DESCRIPTION: Writes a buffer of data to the I/O port. The data is sent to the
- * port as 32 bits units( 4 bytes ).
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static __inline void outsl( unsigned short io_addr, uint8_t *out_data, int len )
-{
- u_long *pl = ( u_long *)out_data;
- while( len-- )
- {
- outport_long( io_addr, *pl );
- pl++;
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Writes a buffer of data to the I/O port. The data is sent to the
- * port as 16 bits units( 2 bytes ).
- *
- * RETURNS:
- *
- **********************************************************************************/
-static __inline void outsw( unsigned short io_addr, uint8_t *out_data, int len )
-{
- u_short *ps = ( u_short *)out_data;
- while( len-- )
- {
- outport_word( io_addr, *ps );
- ps++;
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Writes a buffer of data to the I/O port. The data is sent to the
- * port as 8 bits units( 1 byte ).
- *
- * RETURNS: nothing
- *
- **********************************************************************************/
-static __inline void outsb( unsigned short io_addr, uint8_t *out_data, int len )
-{
- while( len-- )
- {
- outport_byte( io_addr, *out_data );
- out_data++;
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Read a buffer of data from an I/O port. The data is read as 16 bits
- * units or 2 bytes.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static __inline void insw( unsigned short io_addr, uint8_t *in_data, int len )
-{
- u_short *ps = ( u_short *)in_data;
- while( len-- )
- {
- inport_word( io_addr, *ps );
- ps++;
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Read a buffer of data from an I/O port. The data is read as 32 bits
- * units or 4 bytes.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static __inline void insl( unsigned short io_addr, uint8_t *in_data, int len )
-{
- u_long *pl = ( u_long *)in_data;
- while( len-- )
- {
- inport_long( io_addr, *pl );
- pl++;
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Read a buffer of data from an I/O port. The data is read as 8 bits
- * units or 1 bytes.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static __inline void insb( unsigned short io_addr, uint8_t *in_data, int len )
-{
- while( len-- )
- {
- inport_byte( io_addr, *in_data++ );
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Writes a word to the I/O port.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-/*
- * Routine to output a word as defined in FreeBSD.
- */
-static __inline void outw( unsigned short io_addr, unsigned short out_data )
-{
- outport_word( io_addr, out_data );
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Routine to read a word as defined in FreeBSD.
- *
- * RETURNS: nothing
- *
- **********************************************************************************/
-static __inline unsigned short inw( unsigned short io_addr )
-{
- unsigned short in_data;
- inport_word( io_addr, in_data );
- return in_data;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Routine to output a word as defined in FreeBSD.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static __inline void outb( unsigned short io_addr, uint8_t out_data )
-{
- outport_byte( io_addr, out_data );
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Routine to read a word as defined in FreeBSD.
- *
- * RETURNS: byte read.
- *
- **********************************************************************************/
-static __inline uint8_t inb( unsigned short io_addr )
-{
- uint8_t in_data;
- inport_byte( io_addr, in_data );
- return in_data;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * We get eeprom data from the id_port given an offset into the eeprom.
- * Basically; after the ID_sequence is sent to all of the cards; they enter
- * the ID_CMD state where they will accept command requests. 0x80-0xbf loads
- * the eeprom data. We then read the port 16 times and with every read; the
- * cards check for contention (ie: if one card writes a 0 bit and another
- * writes a 1 bit then the host sees a 0. At the end of the cycle; each card
- * compares the data on the bus; if there is a difference then that card goes
- * into ID_WAIT state again). In the meantime; one bit of data is returned in
- * the AX register which is conveniently returned to us by inb(). Hence; we
- * read 16 times getting one bit of data with each read.
- *
- * RETURNS: 16 bit word from the EEPROM
- *
- **********************************************************************************/
-static int get_eeprom_data( int id_port, int offset )
-{
- int i, data = 0;
- outb(id_port, 0x80 + offset);
- Wait_X_ms( 1 );
- for (i = 0; i < 16; i++)
- data = (data << 1) | (inw(id_port) & 1);
- return( data );
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * Driver interrupt handler. This routine is called by the RTEMS kernel when this
- * interrupt is raised.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static rtems_isr ap_interrupt_handler(void *arg)
-{
- struct ep_softc *sc = (struct ep_softc *)arg;
-
- /* de-activate any pending interrrupt, and sent and event to interrupt task
- * to process all events required by this interrupt.
- */
- outw( BASE + EP_COMMAND, SET_INTR_MASK ); /* disable all Ints */
- rtems_bsdnet_event_send( sc->rxDaemonTid, INTERRUPT_EVENT );
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * Initializes the ethernet hardware.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void _3c509_initialize_hardware (struct ep_softc *sc)
-{
- rtems_status_code status;
-
- epinit( sc );
-
- /*
- * Set up interrupts
- */
- printf ("3c509: IRQ with Kernel: %d\n", (int)sc->name );
- status = rtems_interrupt_handler_install(
- sc->name,
- "3c509",
- RTEMS_INTERRUPT_UNIQUE,
- ap_interrupt_handler,
- sc
- );
- assert(status == RTEMS_SUCCESSFUL);
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Driver interrupt daemon.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void _3c509_rxDaemon (void *arg)
-{
- struct ep_softc *dp = (struct ep_softc *)&ep_softc[ 0 ];
- rtems_event_set events;
-
- printf ("3C509: RX Daemon is starting.\n");
- for( ;; )
- {
- /* printk( "R-" ); */
- rtems_bsdnet_event_receive( INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events );
- /* printk( "R+" ); */
- ep_intr( dp );
- epstart( &dp->arpcom.ac_if );
- }
- printf ("3C509: RX Daemon is finishing.\n");
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Driver transmit daemon
- *
- * RETURNS:
- *
- **********************************************************************************/
-static void _3c509_txDaemon (void *arg)
-{
- struct ep_softc *sc = (struct ep_softc *)&ep_softc[0];
- struct ifnet *ifp = &sc->arpcom.ac_if;
- rtems_event_set events;
-
- printf ("3C509: TX Daemon is starting.\n");
- for( ;; )
- {
- /*
- * Wait for packet
- */
- /* printk( "T-\n" ); */
- rtems_bsdnet_event_receive( START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events );
- /* printk( "T+\n" ); */
- epstart( ifp );
- while( ifp->if_flags & IFF_OACTIVE )
- epstart( ifp );
- }
- printf ("3C509: TX Daemon is finishing.\n");
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Activates the trabsmitter task...
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void _3c509_start (struct ifnet *ifp)
-{
- struct ep_softc *sc = ifp->if_softc;
- /* printk ("S"); */
- ifp->if_flags |= IFF_OACTIVE;
- rtems_bsdnet_event_send( sc->txDaemonTid, START_TRANSMIT_EVENT );
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Initialize and start the device
- *
- * RETURNS:
- *
- **********************************************************************************/
-static void _3c509_init (void *arg)
-{
- struct ep_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- printf ("3C509: Initialization called.\n");
- if (sc->txDaemonTid == 0) {
-
- /*
- * Set up WD hardware
- */
- _3c509_initialize_hardware (sc);
- printf ("3C509: starting network driver tasks..\n");
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc ("APtx", 4096, _3c509_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc ("APrx", 4096, _3c509_rxDaemon, sc);
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Stop the device
- *
- * RETURNS:
- *
- **********************************************************************************/
-static void _3c509_stop (struct ep_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- ifp->if_flags &= ~IFF_RUNNING;
-
- printf ("3C509: stop() called.\n");
- /*
- * Stop the transmitter
- */
- outw(BASE + EP_COMMAND, RX_DISABLE);
- outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
- outw(BASE + EP_COMMAND, TX_DISABLE);
- outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
- outw(BASE + EP_COMMAND, RX_RESET);
- outw(BASE + EP_COMMAND, TX_RESET);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
- outw(BASE + EP_COMMAND, C_INTR_LATCH);
- outw(BASE + EP_COMMAND, SET_RD_0_MASK);
- outw(BASE + EP_COMMAND, SET_INTR_MASK);
- outw(BASE + EP_COMMAND, SET_RX_FILTER);
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Show interface statistics
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void _3c509_stats (struct ep_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- printf ("3C509: stats() called.\n");
- printf("\tStat: %x\n", sc->stat);
- printf("\tIpackets=%ld, Opackets=%ld\n", ifp->if_ipackets, ifp->if_opackets);
- printf("\tNOF=%d, NOMB=%d, BPFD=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
- sc->rx_no_first, sc->rx_no_mbuf, sc->rx_bpf_disc, sc->rx_overrunf,
- sc->rx_overrunl, sc->tx_underrun );
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Driver ioctl handler
- *
- * RETURNS:
- *
- **********************************************************************************/
-static int _3c509_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct ep_softc *sc = ifp->if_softc;
- int error = 0;
-
- printf ("3C509: ioctl() called.\n");
- 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:
- _3c509_stop (sc);
- break;
-
- case IFF_UP:
- _3c509_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- _3c509_stop (sc);
- _3c509_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- _3c509_stats( sc );
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * Attaches this network driver to the system. This function is called by the network
- * interface during the initialization of the system.
- *
- * RETURNS: - 1 - success; 0 - fail to initialize
- *
- **********************************************************************************/
-int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *config )
-{
- struct ep_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int i;
-
- printf ("3C509: attach() called.\n");
-
- /*
- * init some variables
- */
- overrun = 0;
- resend = 0;
- ep_unit = 0;
- ep_boards = 0;
-
- /*
- * Find a free driver
- */
- for (i = 0 ; i < NWDDRIVER ; i++) {
- sc = &ep_softc[i];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc == NULL)
- break;
- }
- if (i >= NWDDRIVER)
- {
- printf ("Too many 3C509 drivers.\n");
- return 0;
- }
-
- /*
- * Process options
- */
- if( config->hardware_address )
- {
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- }
- else
- {
- /* set it to something ... */
- memset (sc->arpcom.ac_enaddr, 0x08,ETHER_ADDR_LEN);
- }
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- if (config->irno)
- sc->name = config->irno;
- else
- sc->name = 10;
-
- if (config->port)
- sc->ep_io_addr = config->port;
- else
- sc->ep_io_addr = 0x300;
-
- sc->acceptBroadcast = !config->ignore_broadcast;
-
- printf ("3C509: isa_probe() looking for a card...\n");
- if( !ep_isa_probe( &isa_dev[ 0 ] ) )
- {
- printf ("3C509: isa_probe() fail to find a board.\n");
- return 0;
- }
-
- /* A board has been found, so proceed with the installation of the driver */
- ep_isa_attach( &isa_dev[ 0 ] );
- /*
- * Set up network interface values
- */
-
- ifp->if_softc = sc;
- ifp->if_unit = i;
- ifp->if_name = NET_DRIVER_NAME;
- ifp->if_mtu = mtu;
- ifp->if_init = _3c509_init;
- ifp->if_ioctl = _3c509_ioctl;
- ifp->if_start = _3c509_start;
- ifp->if_output = ether_output;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- if( ifp->if_snd.ifq_maxlen == 0 )
- {
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- }
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
- printf ("3C509: attach() is complete.\n");
- return 1;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * This function looks for a 3COM card 3c5x9 in an isa bus. If a board is found, it
- * returns a structure describing the caracteristics of the card. It returns zero when
- * card can not be found.
- *
- * RETURNS: 0 - fail - could not find a card...
- * <> description of the card.
- *
- **********************************************************************************/
-static struct ep_board *ep_look_for_board_at( struct isa_device *is )
-{
- int data, i, j, id_port = ELINK_ID_PORT;
- int count = 0;
-
- if(ep_current_tag == (EP_LAST_TAG + 1) )
- {
- /* Come here just one time */
- ep_current_tag--;
-
- /* Look for the ISA boards. Init and leave them actived */
- outb(id_port, 0);
- outb(id_port, 0);
-
- elink_idseq(0xCF);
- elink_reset();
- Wait_X_ms( 10 ); /* RPS: assuming delay in miliseconds */
- for (i = 0; i < EP_MAX_BOARDS; i++)
- {
- outb(id_port, 0);
- outb(id_port, 0);
- elink_idseq(0xCF);
-
- data = get_eeprom_data(id_port, EEPROM_MFG_ID);
- if (data != MFG_ID)
- break;
-
- /* resolve contention using the Ethernet address */
- for (j = 0; j < 3; j++)
- get_eeprom_data(id_port, j);
-
- /* and save this address for later use */
-
- for (j = 0; j < 3; j++)
- ep_board[ep_boards].eth_addr[j] = get_eeprom_data(id_port, j);
-
- ep_board[ep_boards].res_cfg = get_eeprom_data(id_port, EEPROM_RESOURCE_CFG);
- ep_board[ep_boards].prod_id = get_eeprom_data(id_port, EEPROM_PROD_ID);
- ep_board[ep_boards].epb_used = 0;
-#ifdef PC98
- ep_board[ep_boards].epb_addr =
- (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x100 + 0x40d0;
-#else
- ep_board[ep_boards].epb_addr =
- (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
- if (ep_board[ep_boards].epb_addr > 0x3E0)
- /* Board in EISA configuration mode */
- continue;
-#endif /* PC98 */
-
- outb(id_port, ep_current_tag); /* tags board */
- outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
- ep_boards++;
- count++;
- ep_current_tag--;
- }
- ep_board[ep_boards].epb_addr = 0;
- if( count )
- {
- printf("%d 3C5x9 board(s) on ISA found at", count);
- for (j = 0; ep_board[j].epb_addr; j++)
- if( ep_board[j].epb_addr <= 0x3E0 )
- printf(" 0x%x", ep_board[j].epb_addr );
- printf("\n");
- }
- }
-
- /* we have two cases:
- *
- * 1. Device was configured with 'port ?'
- * In this case we search for the first unused card in list
- *
- * 2. Device was configured with 'port xxx'
- * In this case we search for the unused card with that address
- *
- */
-
- if (IS_BASE == -1)
- { /* port? */
- for (i = 0; ep_board[i].epb_addr && ep_board[i].epb_used; i++) ;
- if (ep_board[i].epb_addr == 0)
- return 0;
-
- IS_BASE = ep_board[i].epb_addr;
- ep_board[i].epb_used = 1;
- return &ep_board[ i ];
- }
- else
- {
- for (i = 0; ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE; i++ ) ;
- if (ep_board[i].epb_used || ep_board[i].epb_addr != IS_BASE)
- return 0;
- if (inw(IS_BASE + EP_W0_EEPROM_COMMAND) & EEPROM_TST_MODE)
- {
- printf("ep%d: 3c5x9 at 0x%x in PnP mode. Disable PnP mode!\n",
- is->id_unit, IS_BASE );
- }
- ep_board[i].epb_used = 1;
- return &ep_board[i];
- }
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * This routine checks if there card installed on the machine.
- *
- * RETURNS: 0 - no card founded.
- * 16 - size of the IO range for the card.
- *
- **********************************************************************************/
-static int ep_isa_probe( struct isa_device *is )
-{
- struct ep_softc *sc;
- struct ep_board *epb;
- u_short k;
-
- /* try to find a 3COM 3c5x9 .... */
- if( (epb = ep_look_for_board_at(is)) == 0 )
- return (0);
-
- sc = &ep_softc[ 0 ];
- sc->ep_io_addr = epb->epb_addr;
- sc->epb = epb;
-
- /*
- * The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
- * 0x9[0-f]50 (IBM-PC)
- * 0x9[0-f]5[0-f] (PC-98)
- */
- GO_WINDOW(0);
- k = sc->epb->prod_id;
-#ifdef PC98
- if ((k & 0xf0f0) != (PROD_ID & 0xf0f0))
- {
-#else
- if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
- {
-#endif
- printf("ep_isa_probe: ignoring model %04x\n", k );
-/* ep_unit--; */
- return (0);
- }
- k = sc->epb->res_cfg;
- k >>= 12;
-
- /* Now we have two cases again:
- *
- * 1. Device was configured with 'irq?'
- * In this case we use irq read from the board
- *
- * 2. Device was configured with 'irq xxx'
- * In this case we set up the board to use specified interrupt
- *
- */
-
- if (is->id_irq == 0)
- { /* irq? */
- is->id_irq = ( k == 2 ) ? 9 : k;
- }
-
- sc->stat = 0; /* 16 bit access */
-
- /* By now, the adapter is already activated */
-
- return (EP_IOSIZE); /* 16 bytes of I/O space used. */
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * This routine attaches this network driver and the network interface routines.
- *
- * RETURNS: 0 - failed to attach
- * 1 - success
- *
- **********************************************************************************/
-static int ep_isa_attach( struct isa_device *is )
-{
- struct ep_softc *sc = &ep_softc[ 0 ];
- u_short config;
- int irq;
-
- sc->ep_connectors = 0;
- config = inw( IS_BASE + EP_W0_CONFIG_CTRL );
- if (config & IS_AUI)
- {
- sc->ep_connectors |= AUI;
- }
- if (config & IS_BNC)
- {
- sc->ep_connectors |= BNC;
- }
- if (config & IS_UTP)
- {
- sc->ep_connectors |= UTP;
- }
- if( !(sc->ep_connectors & 7) )
- printf( "no connectors!" );
- sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
-
- /*
- * Write IRQ value to board
- */
-
- irq = is->id_irq;
- /* update the interrupt line number to registered with kernel */
- sc->name = irq;
-
- GO_WINDOW( 0 );
- SET_IRQ( BASE, irq );
-
- printf( "3C509: I/O=0x%x, IRQ=%d, CONNECTOR=%s, ",
- sc->ep_io_addr, (int)sc->name,ep_conn_type[ sc->ep_connector ] );
-
- ep_attach( sc );
- return 1;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Completes the initialization/attachement of the driver.
- *
- * RETURNS: 0 - ok.
- *
- **********************************************************************************/
-static int ep_attach( struct ep_softc *sc )
-{
- u_short *p;
- int i;
-
- /*
- * Setup the station address
- */
- p = (u_short *) &sc->arpcom.ac_enaddr;
- GO_WINDOW(2);
- printf("ADDRESS=" );
- for (i = 0; i < 3; i++)
- {
- p[i] = htons( sc->epb->eth_addr[i] );
- outw( BASE + EP_W2_ADDR_0 + (i * 2), ntohs( p[i] ) );
- printf("%04x ", (u_short)ntohs( p[i] ) );
- }
- printf("\n" );
-
- sc->rx_no_first = sc->rx_no_mbuf =
- sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
- sc->tx_underrun = 0;
-
- ep_fset( F_RX_FIRST );
- sc->top = sc->mcur = 0;
- return 0;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * Initializes the card.
- * The order in here seems important. Otherwise we may not receive interrupts. ?!
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void epinit( struct ep_softc *sc )
-{
- register struct ifnet *ifp = &sc->arpcom.ac_if;
- int i, j;
-
- while( inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS ) ;
- GO_WINDOW(0);
- outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
- GO_WINDOW(4);
- outw(BASE + EP_W4_MEDIA_TYPE, DISABLE_UTP);
- GO_WINDOW(0);
-
- /* Disable the card */
- outw(BASE + EP_W0_CONFIG_CTRL, 0);
-
- /* Enable the card */
- outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
-
- GO_WINDOW(2);
-
- /* Reload the ether_addr. */
- for (i = 0; i < 6; i++)
- outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
-
- outw(BASE + EP_COMMAND, RX_RESET);
- outw(BASE + EP_COMMAND, TX_RESET);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
-
- /* Window 1 is operating window */
- GO_WINDOW(1);
- for (i = 0; i < 31; i++)
- inb(BASE + EP_W1_TX_STATUS);
-
- /* get rid of stray intr's */
- outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
-
- outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
-
- outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS);
-
- if (ifp->if_flags & IFF_PROMISC)
- outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
- FIL_GROUP | FIL_BRDCST | FIL_ALL);
- else
- outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | FIL_GROUP | FIL_BRDCST);
-
- /*
- * S.B.
- *
- * Now behavior was slightly changed:
- *
- * if any of flags link[0-2] is used and its connector is
- * physically present the following connectors are used:
- *
- * link0 - AUI * highest precedence
- * link1 - BNC
- * link2 - UTP * lowest precedence
- *
- * If none of them is specified then
- * connector specified in the EEPROM is used
- * (if present on card or AUI if not).
- *
- */
-
- /* Set the xcvr. */
- if (ifp->if_flags & IFF_LINK0 && sc->ep_connectors & AUI)
- {
- i = ACF_CONNECTOR_AUI;
- }
- else if (ifp->if_flags & IFF_LINK1 && sc->ep_connectors & BNC)
- {
- i = ACF_CONNECTOR_BNC;
- }
- else if (ifp->if_flags & IFF_LINK2 && sc->ep_connectors & UTP)
- {
- i = ACF_CONNECTOR_UTP;
- }
- else
- {
- i = sc->ep_connector;
- }
- GO_WINDOW(0);
- j = inw(BASE + EP_W0_ADDRESS_CFG) & 0x3fff;
- outw(BASE + EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
-
- switch(i)
- {
- case ACF_CONNECTOR_UTP:
- if (sc->ep_connectors & UTP)
- {
- GO_WINDOW(4);
- outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
- }
- break;
-
- case ACF_CONNECTOR_BNC:
- if (sc->ep_connectors & BNC)
- {
- outw(BASE + EP_COMMAND, START_TRANSCEIVER);
- Wait_X_ms( 1 );
- }
- break;
-
- case ACF_CONNECTOR_AUI:
- /* nothing to do */
- break;
-
- default:
- printf("ep%d: strange connector type in EEPROM: assuming AUI\n", sc->unit);
- break;
- }
-
- outw(BASE + EP_COMMAND, RX_ENABLE);
- outw(BASE + EP_COMMAND, TX_ENABLE);
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
-
- sc->rx_no_first = sc->rx_no_mbuf =
- sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
- sc->tx_underrun = 0;
-
- ep_fset(F_RX_FIRST);
- if( sc->top )
- {
- m_freem( sc->top );
- sc->top = sc->mcur = 0;
- }
- outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
- outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
-
- /*
- * Store up a bunch of mbuf's for use later. (MAX_MBS). First we free up
- * any that we had in case we're being called from intr or somewhere
- * else.
- */
-
- GO_WINDOW(1);
-}
-
-static const char padmap[] = {0, 3, 2, 1};
-
-/**********************************************************************************
- *
- * DESCRIPTION: Routine to transmit frames to the card.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void epstart( struct ifnet *ifp )
-{
- register struct ep_softc *sc = ifp->if_softc;
- register u_int len;
- register struct mbuf *m;
- struct mbuf *top;
- int pad;
-
- while( inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS )
- ;
-startagain:
- /* printk( "S-" ); */
-
- /* Sneak a peek at the next packet */
- m = ifp->if_snd.ifq_head;
- if (m == 0)
- {
- ifp->if_flags &= ~IFF_OACTIVE;
- return;
- }
-
- for( len = 0, top = m; m; m = m->m_next )
- len += m->m_len;
-
- pad = padmap[ len & 3 ];
-
- /*
- * The 3c509 automatically pads short packets to minimum ethernet length,
- * but we drop packets that are too large. Perhaps we should truncate
- * them instead?
- */
- if( len + pad > ETHER_MAX_LEN )
- {
- /* packet is obviously too large: toss it */
- ++ifp->if_oerrors;
- IF_DEQUEUE( &ifp->if_snd, m );
- m_freem( m );
- goto readcheck;
- }
- if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4)
- {
- /* no room in FIFO */
- outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
- /* make sure */
- if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4)
- {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
- }
- IF_DEQUEUE( &ifp->if_snd, m );
- outw(BASE + EP_W1_TX_PIO_WR_1, len);
- outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
-
- for (top = m; m != 0; m = m->m_next)
- {
- if( ep_ftst(F_ACCESS_32_BITS ) )
- {
- outsl( BASE + EP_W1_TX_PIO_WR_1, mtod(m, uint8_t *), m->m_len / 4 );
- if( m->m_len & 3 )
- outsb(BASE + EP_W1_TX_PIO_WR_1, mtod(m, uint8_t *) + (m->m_len & (~3)), m->m_len & 3 );
- }
- else
- {
- outsw( BASE + EP_W1_TX_PIO_WR_1, mtod(m, uint8_t *), m->m_len / 2 );
- if( m->m_len & 1 )
- outb( BASE + EP_W1_TX_PIO_WR_1, *(mtod(m, uint8_t *) + m->m_len - 1) );
- }
- }
- while( pad-- )
- {
- outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
- }
- ifp->if_timer = 2;
- ifp->if_opackets++;
- m_freem(top);
-
-/* goto startagain; */
- /*
- * Is another packet coming in? We don't want to overflow the tiny RX
- * fifo.
- */
-readcheck:
- if( inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK )
- {
- /*
- * we check if we have packets left, in that case we prepare to come
- * back later
- */
- if( ifp->if_snd.ifq_head )
- {
- outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
- }
- return;
- }
- goto startagain;
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION: Routine to read frames from the card.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void epread( register struct ep_softc *sc )
-{
- struct ether_header *eh;
- struct mbuf *top, *mcur, *m;
- struct ifnet *ifp;
- int lenthisone;
-
- short rx_fifo2, status;
- register short rx_fifo;
-
- ifp = &sc->arpcom.ac_if;
- status = inw( BASE + EP_W1_RX_STATUS );
-
-read_again:
-
- if (status & ERR_RX)
- {
- ++ifp->if_ierrors;
- if( status & ERR_RX_OVERRUN )
- {
- /*
- * we can think the rx latency is actually greather than we
- * expect
- */
- if( ep_ftst(F_RX_FIRST) )
- sc->rx_overrunf++;
- else
- sc->rx_overrunl++;
-
- }
- goto out;
- }
- rx_fifo = rx_fifo2 = status & RX_BYTES_MASK;
-
- if( ep_ftst( F_RX_FIRST ) )
- {
- MGETHDR( m, M_DONTWAIT, MT_DATA );
- if( !m )
- goto out;
- if( rx_fifo >= MINCLSIZE )
- MCLGET( m, M_DONTWAIT );
- sc->top = sc->mcur = top = m;
-#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
-#define EOFF (EROUND - sizeof(struct ether_header))
- top->m_data += EOFF;
-
- /* Read what should be the header. */
- insw(BASE + EP_W1_RX_PIO_RD_1, mtod(top, uint8_t *), sizeof(struct ether_header) / 2);
- top->m_len = sizeof(struct ether_header);
- rx_fifo -= sizeof(struct ether_header);
- sc->cur_len = rx_fifo2;
- }
- else
- {
- /* come here if we didn't have a complete packet last time */
- top = sc->top;
- m = sc->mcur;
- sc->cur_len += rx_fifo2;
- }
-
- /* Reads what is left in the RX FIFO */
- while (rx_fifo > 0)
- {
- lenthisone = min( rx_fifo, M_TRAILINGSPACE(m) );
- if( lenthisone == 0 )
- { /* no room in this one */
- mcur = m;
- MGET(m, M_WAIT, MT_DATA);
- if (!m)
- goto out;
- if (rx_fifo >= MINCLSIZE)
- MCLGET(m, M_WAIT);
- m->m_len = 0;
- mcur->m_next = m;
- lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
- }
- if( ep_ftst( F_ACCESS_32_BITS ) )
- { /* default for EISA configured cards*/
- insl( BASE + EP_W1_RX_PIO_RD_1, mtod(m, uint8_t *) + m->m_len, lenthisone / 4);
- m->m_len += (lenthisone & ~3);
- if (lenthisone & 3)
- insb(BASE + EP_W1_RX_PIO_RD_1, mtod(m, uint8_t *) + m->m_len, lenthisone & 3);
- m->m_len += (lenthisone & 3);
- }
- else
- {
- insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, uint8_t *) + m->m_len, lenthisone / 2);
- m->m_len += lenthisone;
- if( lenthisone & 1 )
- *(mtod(m, uint8_t *) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1);
- }
- rx_fifo -= lenthisone;
- }
-
- if( status & ERR_RX_INCOMPLETE)
- { /* we haven't received the complete packet */
- sc->mcur = m;
- sc->rx_no_first++; /* to know how often we come here */
- ep_frst( F_RX_FIRST );
- if( !((status = inw(BASE + EP_W1_RX_STATUS)) & ERR_RX_INCOMPLETE) )
- {
- /* we see if by now, the packet has completly arrived */
- goto read_again;
- }
- outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
- return;
- }
- outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
- ++ifp->if_ipackets;
- ep_fset(F_RX_FIRST);
- top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- top->m_pkthdr.len = sc->cur_len;
-
- eh = mtod(top, struct ether_header *);
- m_adj(top, sizeof(struct ether_header));
- ether_input(ifp, eh, top);
- sc->top = 0;
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
- ;
- outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
- return;
-
-out:
- outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
- if (sc->top)
- {
- m_freem(sc->top);
- sc->top = 0;
- sc->rx_no_mbuf++;
- }
- ep_fset(F_RX_FIRST);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) ;
- outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
-}
-
-/**********************************************************************************
- *
- * DESCRIPTION:
- * This routine handles interrupts. It is called from the "RX" task whenever
- * the ISR post an event to the task.
- * This is basically the "isr" from the FreeBSD driver.
- *
- * RETURNS: nothing.
- *
- **********************************************************************************/
-static void ep_intr( struct ep_softc *sc )
-{
- register int status;
- struct ifnet *ifp;
- ifp = &sc->arpcom.ac_if;
-
-rescan:
-
- /* printk( "I-" ); */
- while( ( status = inw(BASE + EP_STATUS)) & S_5_INTS )
- {
- /* first acknowledge all interrupt sources */
- outw( BASE + EP_COMMAND, ACK_INTR | ( status & S_MASK ) );
-
- if( status & ( S_RX_COMPLETE | S_RX_EARLY ) )
- {
- epread( sc );
- continue;
- }
- if (status & S_TX_AVAIL)
- {
- /* we need ACK */
- ifp->if_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
- GO_WINDOW(1);
- inw(BASE + EP_W1_FREE_TX);
- epstart(ifp);
- }
- if (status & S_CARD_FAILURE)
- {
- ifp->if_timer = 0;
- printf("\nep%d:\n\tStatus: %x\n", sc->unit, status);
- GO_WINDOW(4);
- printf("\tFIFO Diagnostic: %x\n", inw(BASE + EP_W4_FIFO_DIAG));
- printf("\tStat: %x\n", sc->stat);
- printf("\tIpackets=%ld, Opackets=%ld\n", ifp->if_ipackets, ifp->if_opackets);
- printf("\tNOF=%d, NOMB=%d, BPFD=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
- sc->rx_no_first, sc->rx_no_mbuf, sc->rx_bpf_disc, sc->rx_overrunf,
- sc->rx_overrunl, sc->tx_underrun);
-
- printf("ep%d: Status: %x (input buffer overflow)\n", sc->unit, status);
- ++ifp->if_ierrors;
- epinit(sc);
- return;
- }
- if (status & S_TX_COMPLETE)
- {
- ifp->if_timer = 0;
- /* we need ACK. we do it at the end */
- /*
- * We need to read TX_STATUS until we get a 0 status in order to
- * turn off the interrupt flag.
- */
- while ((status = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE)
- {
- if (status & TXS_SUCCES_INTR_REQ)
- ;
- else if( status & (TXS_UNDERRUN | TXS_JABBER | TXS_MAX_COLLISION ) )
- {
- outw(BASE + EP_COMMAND, TX_RESET);
- if (status & TXS_UNDERRUN)
- {
- sc->tx_underrun++;
- }
- else
- {
- if( status & TXS_JABBER )
- ;
- else /* TXS_MAX_COLLISION - we shouldn't get here */
- ++ifp->if_collisions;
- }
- ++ifp->if_oerrors;
- outw(BASE + EP_COMMAND, TX_ENABLE);
- /*
- * To have a tx_avail_int but giving the chance to the
- * Reception
- */
- if( ifp->if_snd.ifq_head )
- {
- outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
- }
- }
- outb( BASE + EP_W1_TX_STATUS, 0x0 ); /* pops up the next status */
- } /* while */
- ifp->if_flags &= ~IFF_OACTIVE;
- GO_WINDOW(1);
- inw(BASE + EP_W1_FREE_TX);
- epstart( ifp );
- } /* end TX_COMPLETE */
- }
- outw(BASE + EP_COMMAND, C_INTR_LATCH); /* ACK int Latch */
- if( (status = inw(BASE + EP_STATUS) ) & S_5_INTS )
- goto rescan;
-
- /* re-enable Ints */
- outw( BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS );
- /* printk( "I+" ); */
-}
diff --git a/c/src/lib/libbsp/i386/pc386/3c509/3c509.h b/c/src/lib/libbsp/i386/pc386/3c509/3c509.h
deleted file mode 100644
index 975342970a..0000000000
--- a/c/src/lib/libbsp/i386/pc386/3c509/3c509.h
+++ /dev/null
@@ -1,436 +0,0 @@
-/**
- * @file
- *
- * @ingroup pc386_3c509
- *
- * @brief 3C509 PC card support.
- */
-
-/*
- * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2. The name
- * of the author may not be used to endorse or promote products derived from
- * this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by:
- *
- October 2, 1994
-
- Modified by: Andres Vega Garcia
-
- INRIA - Sophia Antipolis, France
- e-mail: avega@sophia.inria.fr
- finger: avega@pax.inria.fr
-
- */
-/*
- * Promiscuous mode added and interrupt logic slightly changed
- * to reduce the number of adapter failures. Transceiver select
- * logic changed to use value from EEPROM. Autoconfiguration
- * features added.
- * Done by:
- * Serge Babkin
- * Chelindbank (Chelyabinsk, Russia)
- * babkin@hq.icb.chel.su
- */
-
-/*
- * Pccard support for 3C589 by:
- * HAMADA Naoki
- * nao@tom-yam.or.jp
- */
-
-/**
- * @defgroup pc386_3c509 3C509 Support
- *
- * @ingroup i386_pc386
- *
- * @brief 3C509 support.
- */
-
-/*
-typedef unsigned short u_short;
-typedef unsigned long u_long;
-typedef unsigned char u_char;
-*/
-
-/*
- * Some global constants
- */
-#define F_RX_FIRST 0x1
-#define F_PROMISC 0x8
-#define F_ACCESS_32_BITS 0x100
-
-#define TX_INIT_RATE 16
-#define TX_INIT_MAX_RATE 64
-#define RX_INIT_LATENCY 64
-#define RX_INIT_EARLY_THRESH 208 /* not less than MINCLSIZE */
-#define RX_NEXT_EARLY_THRESH 500
-
-#define EEPROMSIZE 0x40
-#define MAX_EEPROMBUSY 1000
-#define EP_LAST_TAG 0xd7
-#define EP_MAX_BOARDS 16
-/*
- * This `ID' port is a mere hack. There's currently no chance to register
- * it with config's idea of the ports that are in use.
- *
- * "After the automatic configuration is completed, the IDS is in its initial
- * state (ID-WAIT), and it monitors all write access to I/O port 01x0h, where
- * 'x' is any hex digit. If a zero is written to any one of these ports, then
- * that address is remembered and becomes the ID port. A second zero written
- * to that port resets the ID sequence to its initial state. The IDS watches
- * for the ID sequence to be written to the ID port."
- *
- * We prefer 0x110 over 0x100 so to not conflict with the Plaque&Pray
- * ports.
- */
-#define EP_ID_PORT 0x110
-#define EP_IOSIZE 16 /* 16 bytes of I/O space used. */
-
-/*
- * some macros to acces long named fields
- */
-#define IS_BASE (is->id_iobase)
-#define BASE (sc->ep_io_addr)
-
-/*
- * Commands to read/write EEPROM trough EEPROM command register (Window 0,
- * Offset 0xa)
- */
-#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
-#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
-#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
-#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
-
-#define EEPROM_BUSY (1<<15)
-#define EEPROM_TST_MODE (1<<14)
-
-/*
- * Some short functions, worth to let them be a macro
- */
-#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
-#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|(x))
-
-/**************************************************************************
- * *
- * These define the EEPROM data structure. They are used in the probe
- * function to verify the existence of the adapter after having sent
- * the ID_Sequence.
- *
- * There are others but only the ones we use are defined here.
- *
- **************************************************************************/
-
-#define EEPROM_NODE_ADDR_0 0x0 /* Word */
-#define EEPROM_NODE_ADDR_1 0x1 /* Word */
-#define EEPROM_NODE_ADDR_2 0x2 /* Word */
-#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
-#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
-#define EEPROM_ADDR_CFG 0x8 /* Base addr */
-#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
-
-/**************************************************************************
- * *
- * These are the registers for the 3Com 3c509 and their bit patterns when *
- * applicable. They have been taken out the the "EtherLink III Parallel *
- * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
- * from 3com. *
- * *
- **************************************************************************/
-
-#define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a
- * command reg. */
-#define EP_STATUS 0x0e /* Read. BASE+0x0e is always status
- * reg. */
-#define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window
- * reg. */
-/*
- * Window 0 registers. Setup.
- */
-/* Write */
-#define EP_W0_EEPROM_DATA 0x0c
-#define EP_W0_EEPROM_COMMAND 0x0a
-#define EP_W0_RESOURCE_CFG 0x08
-#define EP_W0_ADDRESS_CFG 0x06
-#define EP_W0_CONFIG_CTRL 0x04
-/* Read */
-#define EP_W0_PRODUCT_ID 0x02
-#define EP_W0_MFG_ID 0x00
-
-/*
- * Window 1 registers. Operating Set.
- */
-/* Write */
-#define EP_W1_TX_PIO_WR_2 0x02
-#define EP_W1_TX_PIO_WR_1 0x00
-/* Read */
-#define EP_W1_FREE_TX 0x0c
-#define EP_W1_TX_STATUS 0x0b /* byte */
-#define EP_W1_TIMER 0x0a /* byte */
-#define EP_W1_RX_STATUS 0x08
-#define EP_W1_RX_PIO_RD_2 0x02
-#define EP_W1_RX_PIO_RD_1 0x00
-
-/*
- * Window 2 registers. Station Address Setup/Read
- */
-/* Read/Write */
-#define EP_W2_ADDR_5 0x05
-#define EP_W2_ADDR_4 0x04
-#define EP_W2_ADDR_3 0x03
-#define EP_W2_ADDR_2 0x02
-#define EP_W2_ADDR_1 0x01
-#define EP_W2_ADDR_0 0x00
-
-/*
- * Window 3 registers. FIFO Management.
- */
-/* Read */
-#define EP_W3_FREE_TX 0x0c
-#define EP_W3_FREE_RX 0x0a
-
-/*
- * Window 4 registers. Diagnostics.
- */
-/* Read/Write */
-#define EP_W4_MEDIA_TYPE 0x0a
-#define EP_W4_CTRLR_STATUS 0x08
-#define EP_W4_NET_DIAG 0x06
-#define EP_W4_FIFO_DIAG 0x04
-#define EP_W4_HOST_DIAG 0x02
-#define EP_W4_TX_DIAG 0x00
-
-/*
- * Window 5 Registers. Results and Internal status.
- */
-/* Read */
-#define EP_W5_READ_0_MASK 0x0c
-#define EP_W5_INTR_MASK 0x0a
-#define EP_W5_RX_FILTER 0x08
-#define EP_W5_RX_EARLY_THRESH 0x06
-#define EP_W5_TX_AVAIL_THRESH 0x02
-#define EP_W5_TX_START_THRESH 0x00
-
-/*
- * Window 6 registers. Statistics.
- */
-/* Read/Write */
-#define TX_TOTAL_OK 0x0c
-#define RX_TOTAL_OK 0x0a
-#define TX_DEFERRALS 0x08
-#define RX_FRAMES_OK 0x07
-#define TX_FRAMES_OK 0x06
-#define RX_OVERRUNS 0x05
-#define TX_COLLISIONS 0x04
-#define TX_AFTER_1_COLLISION 0x03
-#define TX_AFTER_X_COLLISIONS 0x02
-#define TX_NO_SQE 0x01
-#define TX_CD_LOST 0x00
-
-/****************************************
- *
- * Register definitions.
- *
- ****************************************/
-
-/*
- * Command register. All windows.
- *
- * 16 bit register.
- * 15-11: 5-bit code for command to be executed.
- * 10-0: 11-bit arg if any. For commands with no args;
- * this can be set to anything.
- */
-#define GLOBAL_RESET (u_short) 0x0000 /* Wait at least 1ms
- * after issuing */
-#define WINDOW_SELECT (u_short) (0x1<<11)
-#define START_TRANSCEIVER (u_short) (0x2<<11) /* Read ADDR_CFG reg to
- * determine whether
- * this is needed. If
- * so; wait 800 uSec
- * before using trans-
- * ceiver. */
-#define RX_DISABLE (u_short) (0x3<<11) /* state disabled on
- * power-up */
-#define RX_ENABLE (u_short) (0x4<<11)
-#define RX_RESET (u_short) (0x5<<11)
-#define RX_DISCARD_TOP_PACK (u_short) (0x8<<11)
-#define TX_ENABLE (u_short) (0x9<<11)
-#define TX_DISABLE (u_short) (0xa<<11)
-#define TX_RESET (u_short) (0xb<<11)
-#define REQ_INTR (u_short) (0xc<<11)
-#define SET_INTR_MASK (u_short) (0xe<<11)
-#define SET_RD_0_MASK (u_short) (0xf<<11)
-#define SET_RX_FILTER (u_short) (0x10<<11)
-#define FIL_INDIVIDUAL (u_short) (0x1)
-#define FIL_GROUP (u_short) (0x2)
-#define FIL_BRDCST (u_short) (0x4)
-#define FIL_ALL (u_short) (0x8)
-#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
-#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
-#define SET_TX_START_THRESH (u_short) (0x13<<11)
-#define STATS_ENABLE (u_short) (0x15<<11)
-#define STATS_DISABLE (u_short) (0x16<<11)
-#define STOP_TRANSCEIVER (u_short) (0x17<<11)
-/*
- * The following C_* acknowledge the various interrupts. Some of them don't
- * do anything. See the manual.
- */
-#define ACK_INTR (u_short) (0x6800)
-#define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
-#define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
-#define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
-#define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
-#define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
-#define C_RX_EARLY (u_short) (ACK_INTR|0x20)
-#define C_INT_RQD (u_short) (ACK_INTR|0x40)
-#define C_UPD_STATS (u_short) (ACK_INTR|0x80)
-#define C_MASK (u_short) 0xFF /* mask of C_* */
-
-/*
- * Status register. All windows.
- *
- * 15-13: Window number(0-7).
- * 12: Command_in_progress.
- * 11: reserved.
- * 10: reserved.
- * 9: reserved.
- * 8: reserved.
- * 7: Update Statistics.
- * 6: Interrupt Requested.
- * 5: RX Early.
- * 4: RX Complete.
- * 3: TX Available.
- * 2: TX Complete.
- * 1: Adapter Failure.
- * 0: Interrupt Latch.
- */
-#define S_INTR_LATCH (u_short) (0x1)
-#define S_CARD_FAILURE (u_short) (0x2)
-#define S_TX_COMPLETE (u_short) (0x4)
-#define S_TX_AVAIL (u_short) (0x8)
-#define S_RX_COMPLETE (u_short) (0x10)
-#define S_RX_EARLY (u_short) (0x20)
-#define S_INT_RQD (u_short) (0x40)
-#define S_UPD_STATS (u_short) (0x80)
-#define S_MASK (u_short) 0xFF /* mask of S_* */
-#define S_5_INTS (S_CARD_FAILURE|S_TX_COMPLETE|\
- S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
-#define S_COMMAND_IN_PROGRESS (u_short) (0x1000)
-
-/* Address Config. Register.
- * Window 0/Port 06
- */
-
-#define ACF_CONNECTOR_BITS 14
-#define ACF_CONNECTOR_UTP 0
-#define ACF_CONNECTOR_AUI 1
-#define ACF_CONNECTOR_BNC 3
-
-/* Resource configuration register.
- * Window 0/Port 08
- *
- */
-
-#define SET_IRQ(base,irq) outw((base) + EP_W0_RESOURCE_CFG, \
- ((inw((base) + EP_W0_RESOURCE_CFG) & 0x0fff) | \
- ((u_short)(irq)<<12)) ) /* set IRQ i */
-
-/*
- * FIFO Registers.
- * RX Status. Window 1/Port 08
- *
- * 15: Incomplete or FIFO empty.
- * 14: 1: Error in RX Packet 0: Incomplete or no error.
- * 13-11: Type of error.
- * 1000 = Overrun.
- * 1011 = Run Packet Error.
- * 1100 = Alignment Error.
- * 1101 = CRC Error.
- * 1001 = Oversize Packet Error (>1514 bytes)
- * 0010 = Dribble Bits.
- * (all other error codes, no errors.)
- *
- * 10-0: RX Bytes (0-1514)
- */
-#define ERR_RX_INCOMPLETE (u_short) (0x1<<15)
-#define ERR_RX (u_short) (0x1<<14)
-#define ERR_RX_OVERRUN (u_short) (0x8<<11)
-#define ERR_RX_RUN_PKT (u_short) (0xb<<11)
-#define ERR_RX_ALIGN (u_short) (0xc<<11)
-#define ERR_RX_CRC (u_short) (0xd<<11)
-#define ERR_RX_OVERSIZE (u_short) (0x9<<11)
-#define ERR_RX_DRIBBLE (u_short) (0x2<<11)
-
-/*
- * FIFO Registers.
- * TX Status. Window 1/Port 0B
- *
- * Reports the transmit status of a completed transmission. Writing this
- * register pops the transmit completion stack.
- *
- * Window 1/Port 0x0b.
- *
- * 7: Complete
- * 6: Interrupt on successful transmission requested.
- * 5: Jabber Error (TP Only, TX Reset required. )
- * 4: Underrun (TX Reset required. )
- * 3: Maximum Collisions.
- * 2: TX Status Overflow.
- * 1-0: Undefined.
- *
- */
-#define TXS_COMPLETE 0x80
-#define TXS_SUCCES_INTR_REQ 0x40
-#define TXS_JABBER 0x20
-#define TXS_UNDERRUN 0x10
-#define TXS_MAX_COLLISION 0x8
-#define TXS_STATUS_OVERFLOW 0x4
-
-/*
- * Configuration control register.
- * Window 0/Port 04
- */
-/* Read */
-#define IS_AUI (1<<13)
-#define IS_BNC (1<<12)
-#define IS_UTP (1<<9)
-/* Write */
-#define ENABLE_DRQ_IRQ 0x0001
-#define W0_P4_CMD_RESET_ADAPTER 0x4
-#define W0_P4_CMD_ENABLE_ADAPTER 0x1
-/*
- * Media type and status.
- * Window 4/Port 0A
- */
-#define ENABLE_UTP 0xc0
-#define DISABLE_UTP 0x0
-
-/*
- * Misc defines for various things.
- */
-#define ACTIVATE_ADAPTER_TO_CONFIG 0xff /* to the id_port */
-#define MFG_ID 0x6d50 /* in EEPROM and W0 ADDR_CONFIG */
-#define PROD_ID 0x9150
-
-#define AUI 0x1
-#define BNC 0x2
-#define UTP 0x4
-
-#define RX_BYTES_MASK (u_short) (0x07ff)
diff --git a/c/src/lib/libbsp/i386/pc386/3c509/elink.c b/c/src/lib/libbsp/i386/pc386/3c509/elink.c
deleted file mode 100644
index ca637fb0a8..0000000000
--- a/c/src/lib/libbsp/i386/pc386/3c509/elink.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 1994 Charles Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Common code for dealing with 3COM ethernet cards.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <sys/types.h>
-
-#include "elink.h"
-
-#include <bsp.h>
-
-static void outb( unsigned short io_addr, unsigned char out_data )
-{
- outport_byte( io_addr, out_data );
-}
-
-/*
- * Issue a `global reset' to all cards. We have to be careful to do this only
- * once during autoconfig, to prevent resetting boards that have already been
- * configured.
- */
-void
-elink_reset()
-{
- static int x = 0;
-
- if (x == 0) {
- x = 1;
- outb(ELINK_ID_PORT, ELINK_RESET);
- }
-}
-
-/*
- * The `ID sequence' is really just snapshots of an 8-bit CRC register as 0
- * bits are shifted in. Different board types use different polynomials.
- */
-void
-elink_idseq(u_char p)
-{
- register int i;
- register u_char c;
-
- c = 0xff;
- for (i = 255; i; i--) {
- outb(ELINK_ID_PORT, c);
- if (c & 0x80) {
- c <<= 1;
- c ^= p;
- } else
- c <<= 1;
- }
-}
diff --git a/c/src/lib/libbsp/i386/pc386/3c509/elink.h b/c/src/lib/libbsp/i386/pc386/3c509/elink.h
deleted file mode 100644
index bcb13a494a..0000000000
--- a/c/src/lib/libbsp/i386/pc386/3c509/elink.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file
- *
- * @ingroup pc386_3c509
- *
- * @brief EtherLink definitions.
- */
-
-/*
- * Copyright (c) 1994 Charles Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef PC98
-#define ELINK_ID_PORT 0x71d0
-#else
-#define ELINK_ID_PORT 0x110
-#endif
-#define ELINK_RESET 0xc0
-
-#define ELINK_507_POLY 0xe7
-#define ELINK_509_POLY 0xcf
-
-extern void elink_reset ( void );
-extern void elink_idseq ( u_char p );
diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.am b/c/src/lib/libbsp/i386/pc386/Makefile.am
index 8cd12e3430..70028f5e65 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.am
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.am
@@ -148,10 +148,10 @@ appstart.$(OBJEXT): appcpustart.$(OBJEXT)
endif
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += 3c509/3c509.c
-librtemsbsp_a_SOURCES += 3c509/elink.c
-librtemsbsp_a_SOURCES += ne2000/ne2000.c
-librtemsbsp_a_SOURCES += wd8003/wd8003.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/net/3c509.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/net/elink.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/net/ne2000.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/net/wd8003.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/shared/cache/cache.c
diff --git a/c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c b/c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c
deleted file mode 100644
index 17861405a6..0000000000
--- a/c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c
+++ /dev/null
@@ -1,1310 +0,0 @@
-/* ne2k.c -- RTEMS NE2000 Ethernet driver.
- * Written by Ian Lance Taylor, Zembu Labs.
- * October, 1998.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- * Both the ne2000 and the wd80x3 are based on the National Semiconductor
- * 8390 chip, so there is a fair amount of overlap between the two
- * drivers. It would be possible in principle to combine some code into
- * a separate set of subroutines called by both. In fact, the drivers in
- * both OpenBSD and Linux work this way. I didn't bother, because for
- * the relatively simple drivers used by RTEMS, the overlap is not
- * especially large, and any reasonable use of subroutines would lead to
- * slightly less efficient code.
-
- * This ne2000 driver uses two transmit buffers. While one packet is
- * being transmitted over the Ethernet, RTEMS will upload another. Since
- * uploading a packet to the ne2000 is rather slow, I don't think there
- * is any point to having more than two transmit buffers. However, the
- * code does make it possible, by changing NE_TX_BUFS, although that
- * would of course reduce the number of receive buffers.
- *
- * I suspect that the wd80x3 driver would benefit slightly from copying
- * the multiple transmit buffer code. However, I have no way to test
- * that.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <libchip/wd80x3.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <bsp/irq.h>
-
-/* Define this to force byte-wide data transfers with the NIC. This
- is needed for boards like the TS-1325 386EX PC, which support only
- an 8-bit PC/104 bus. Undefine this on a normal PC.*/
-
-/* #define NE2000_BYTE_TRANSFERS */
-
-/* Define this to print debugging messages with printk. */
-
-/* #define DEBUG_NE2000 */
-/* #define DEBUG_NE */
-
-/* We expect to be able to read a complete packet into an mbuf. */
-
-#if (MCLBYTES < 1520)
-# error "Driver must have MCLBYTES >= 1520"
-#endif
-
-/* The 8390 macro definitions in wd80x3.h expect RO to be defined. */
-#define RO 0
-
-/* Minimum size of Ethernet packet. */
-#define ET_MINLEN 60
-
-/* The number of NE2000 devices supported by this driver. */
-
-#define NNEDRIVER 1
-
-/* RTEMS event number used by the interrupt handler to signal the
- driver task. This must not be any of the events used by the
- network task synchronization. */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/* RTEMS event number used to start the transmit daemon. This must
- not be the same as INTERRUPT_EVENT. */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
-/* Interrupts we want to handle from the device. */
-
-#define NE_INTERRUPTS \
- (MSK_PRX | MSK_PTX | MSK_RXE | MSK_TXE | MSK_OVW | MSK_CNT)
-
-/* The size of a page in device memory. */
-
-#define NE_PAGE_SIZE (256)
-
-/* The first page address in device memory. */
-
-#define NE_START_PAGE (0x40)
-
-/* The last page address, plus 1. */
-
-#define NE_STOP_PAGE (0x80)
-
-/* The number of pages used for a single transmit buffer. This is
- 1536 bytes, enough for a full size packet. */
-
-#define NE_TX_PAGES (6)
-
-/* The number of transmit buffers. We use two, so we can load one
- packet while the other is being sent. */
-
-#define NE_TX_BUFS (2)
-
-/* We use the first pages in memory as transmit buffers, and the
- remaining ones as receive buffers. */
-
-#define NE_FIRST_TX_PAGE (NE_START_PAGE)
-
-#define NE_FIRST_RX_PAGE (NE_FIRST_TX_PAGE + NE_TX_PAGES * NE_TX_BUFS)
-
-/* Data we store for each NE2000 device. */
-
-struct ne_softc {
- /* The bsdnet information structure. */
- struct arpcom arpcom;
-
- /* The interrupt request number. */
- unsigned int irno;
- /* The base IO port number. */
- unsigned int port;
-
- /* Whether we accept broadcasts. */
- int accept_broadcasts;
-
- /* The thread ID of the transmit task. */
- rtems_id tx_daemon_tid;
- /* The thread ID of the receive task. */
- rtems_id rx_daemon_tid;
-
- /* Whether we use byte-transfers with the device. */
- bool byte_transfers;
-
- /* The number of memory buffers which the transmit daemon has loaded
- with data to be sent, but which have not yet been completely
- sent. */
- int inuse;
- /* The index of the next available transmit memory buffer. */
- int nextavail;
- /* The index of the next transmit buffer to send. */
- int nextsend;
- /* Nonzero if the device is currently transmitting a packet. */
- int transmitting;
- /* The length of the data stored in each transmit buffer. */
- int sendlen[NE_TX_BUFS];
-
- /* Set if we have a packet overrun while receiving. */
- int overrun;
- /* Set if we should resend after an overrun. */
- int resend;
-
- /* Statistics. */
- struct {
- /* Number of packets received. */
- unsigned long rx_packets;
- /* Number of packets sent. */
- unsigned long tx_packets;
- /* Number of interrupts. */
- unsigned long interrupts;
- /* Number of receive acknowledgements. */
- unsigned long rx_acks;
- /* Number of transmit acknowledgements. */
- unsigned long tx_acks;
- /* Number of packet overruns. */
- unsigned long overruns;
- /* Number of frame errors. */
- unsigned long rx_frame_errors;
- /* Number of CRC errors. */
- unsigned long rx_crc_errors;
- /* Number of missed packets. */
- unsigned long rx_missed_errors;
- } stats;
-};
-
-/* The list of NE2000 devices on this system. */
-
-static struct ne_softc ne_softc[NNEDRIVER];
-
-/*
- * receive ring descriptor
- *
- * The National Semiconductor DS8390 Network interface controller uses
- * the following receive ring headers. The way this works is that the
- * memory on the interface card is chopped up into 256 bytes blocks.
- * A contiguous portion of those blocks are marked for receive packets
- * by setting start and end block #'s in the NIC. For each packet that
- * is put into the receive ring, one of these headers (4 bytes each) is
- * tacked onto the front. The first byte is a copy of the receiver status
- * register at the time the packet was received.
- */
-struct ne_ring
-{
- unsigned char rsr; /* receiver status */
- unsigned char next; /* pointer to next packet */
- unsigned char cnt_lo; /* bytes in packet (length + 4) */
- unsigned char cnt_hi; /* 16-bit, little-endian value */
-};
-
-/* Forward declarations to avoid warnings */
-
-static void ne_init_irq_handler (int irno);
-static void ne_stop (struct ne_softc *sc);
-static void ne_stop_hardware (struct ne_softc *sc);
-static void ne_init (void *arg);
-static void ne_init_hardware (struct ne_softc *sc);
-
-static void ne_reset(struct ne_softc *sc);
-#ifdef DEBUG_NE
-static void ne_dump(struct ne_softc *sc);
-#endif
-
-/* Find the NE2000 device which is attached at a particular interrupt
- vector. */
-
-static struct ne_softc *
-ne_device_for_irno (int irno)
-{
- int i;
-
- for (i = 0; i < NNEDRIVER; ++i)
- {
- if (ne_softc[i].irno == irno
- && ne_softc[i].arpcom.ac_if.if_softc != NULL)
- return &ne_softc[i];
- }
-
- return NULL;
-}
-
-/* Read data from an NE2000 device. Read LEN bytes at ADDR, storing
- them into P. */
-
-static void
-ne_read_data (struct ne_softc *sc, int addr, int len, unsigned char *p)
-{
- unsigned int port = sc->port;
- unsigned int dport = port + DATAPORT;
-
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
- outport_byte (port + RBCR0, len);
- outport_byte (port + RBCR1, len >> 8);
- outport_byte (port + RSAR0, addr);
- outport_byte (port + RSAR1, addr >> 8);
- outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
-
- if (sc->byte_transfers)
- {
- unsigned char d;
- while (len > 0)
- {
- inport_byte(dport, d);
- *p++ = d;
- len--;
- }
- }
- else /* word transfers */
- {
- unsigned short d;
- while (len > 1)
- {
- inport_word(dport, d);
- *p++ = d;
- *p++ = d >> 8;
- len -= 2;
- }
- if (len)
- {
- inport_word(dport, d);
- *p++ = d;
- }
- }
-
- outport_byte (port + ISR, MSK_RDC);
-}
-
-/* Handle the current NE2000 status. This is called when the device
- signals an interrupt. It is also called at other times while
- NE2000 interrupts have been disabled. */
-
-static void
-ne_check_status (struct ne_softc *sc, int from_irq_handler)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned int port = sc->port;
- unsigned char status;
-
- /* It seems that we need to use a loop here, because if the NE2000
- signals an interrupt because packet transmission is complete, and
- then receives a packet while interrupts are disabled, it seems to
- sometimes fail to signal the interrupt for the received packet
- when interrupts are reenabled. (Based on the behaviour of the
- Realtek 8019AS chip). */
-
- /* int count = 0; */
- while (1)
- {
- inport_byte (port + ISR, status);
- if (status == 0)
- break;
-
- /* ack */
- outport_byte (port + ISR, status);
-
-#ifdef DEBUG_NE2000
- printk ("NE2000 status 0x%x (8259 enabled: %s; mask: %x)\n", status,
- i8259s_cache & (1 << sc->irno) ? "no" : "yes",
- i8259s_cache);
-#endif
-
- /* Check for incoming packet overwrite. */
- if (status & MSK_OVW)
- {
- ifp->if_timer = 0;
-#ifdef DEBUG_NE
- printk("^");
-#endif
- ++sc->stats.overruns;
- ne_reset(sc);
- /* Reenable device interrupts. */
- if (from_irq_handler)
- outport_byte(port + IMR, NE_INTERRUPTS);
- return;
- }
-
- /* Check for transmitted packet. The transmit daemon may now be
- able to send another packet to the device. */
- if ((status & (MSK_PTX | MSK_TXE)) != 0)
- {
- ifp->if_timer = 0;
- ++sc->stats.tx_acks;
- --sc->inuse;
- sc->transmitting = 0;
- if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0)
- rtems_bsdnet_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
- }
-
- /* Check for received packet. */
- if ((status & (MSK_PRX | MSK_RXE)) != 0)
- {
- ++sc->stats.rx_acks;
- rtems_bsdnet_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
- }
-
- /* Check for counter change. */
- if ((status & MSK_CNT) != 0)
- {
- unsigned char add;
- inport_byte (port + CNTR0, add);
- sc->stats.rx_frame_errors += add;
- inport_byte (port + CNTR1, add);
- sc->stats.rx_crc_errors += add;
- inport_byte (port + CNTR2, add);
- sc->stats.rx_missed_errors += add;
- }
-
- break;
- /* if (++count >= 1000)
- {
- printk("status: %x\n", status);
- ne_reset(sc);
- if (from_irq_handler)
- outport_byte(port + IMR, NE_INTERRUPTS);
- return;
- } */
- }
-
- outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
-}
-
-/* Handle an NE2000 interrupt. */
-
-static void
-ne_interrupt_handler (rtems_irq_hdl_param cdata)
-{
- rtems_vector_number v = (rtems_vector_number) cdata;
- struct ne_softc *sc;
-
- sc = ne_device_for_irno (v);
- if (sc == NULL)
- return;
-
- ++sc->stats.interrupts;
-
-#ifdef DEBUG_NE
- printk("!");
-#endif
- ne_check_status(sc, 1);
-}
-
-/* Turn NE2000 interrupts on. */
-
-static void
-ne_interrupt_on (const rtems_irq_connect_data *irq)
-{
- struct ne_softc *sc;
-
-#ifdef DEBUG_NE
- printk ("ne_interrupt_on()\n");
-#endif
- sc = ne_device_for_irno (irq->name);
- if (sc != NULL)
- outport_byte (sc->port + IMR, NE_INTERRUPTS);
-}
-
-/* Turn NE2000 interrupts off. See ne_interrupt_on. */
-
-static void
-ne_interrupt_off (const rtems_irq_connect_data *irq)
-{
- struct ne_softc *sc;
-
-#ifdef DEBUG_NE
- printk ("ne_interrupt_off()\n");
-#endif
- sc = ne_device_for_irno (irq->name);
- if (sc != NULL)
- outport_byte (sc->port + IMR, 0);
-}
-
-/* Initialize the NE2000 hardware. */
-
-static void
-ne_init_hardware (struct ne_softc *sc)
-{
- unsigned int port = sc->port;
- int i;
-
-#ifdef DEBUG_NE2000
- printk ("ne_init_hardware()\n");
-#endif
-
- /* Initialize registers. */
-
- /* Set interface for page 0, Remote DMA complete, Stopped */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- /* Set FIFO threshold to 8, No auto-init Remote DMA, byte order=80x86 */
- /* byte-wide DMA xfers */
- if (sc->byte_transfers)
- outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
- /* word-wide DMA xfers */
- else
- outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
-
- /* Clear Remote Byte Count Registers */
- outport_byte (port + RBCR0, 0);
- outport_byte (port + RBCR1, 0);
-
- /* For the moment, don't store incoming packets in memory. */
- outport_byte (port + RCR, MSK_MON);
-
- /* Place NIC in internal loopback mode */
- outport_byte (port + TCR, MSK_LOOP);
-
- /* Initialize transmit/receive (ring-buffer) Page Start */
- outport_byte (port + TPSR, NE_FIRST_TX_PAGE);
- outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
-
- /* Initialize Receiver (ring-buffer) Page Stop and Boundary */
- outport_byte (port + PSTOP, NE_STOP_PAGE);
- outport_byte (port + BNRY, NE_STOP_PAGE - 1);
-
- /* Clear all interrupts */
- outport_byte (port + ISR, 0xff);
- /* Disable all interrupts */
- outport_byte (port + IMR, 0);
-
- /* Program Command Register for page 1 */
- outport_byte (port + CMDR, MSK_PG1 | MSK_RD2 | MSK_STP);
-
- /* Set the Ethernet hardware address. */
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
-
- /* Set Current Page pointer to next_packet */
- outport_byte (port + CURR, NE_FIRST_RX_PAGE);
-
- /* Clear the multicast address. */
- for (i = 0; i < MARsize; ++i)
- outport_byte (port + MAR + i, 0);
-
- /* Set page 0 registers */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- /* accept broadcast + multicast */
- outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0) | MSK_AM);
-
- /* Start interface */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
-
- /* Take interface out of loopback */
- outport_byte (port + TCR, 0);
-}
-
-/* Set up interrupts.
-*/
-static void
-ne_init_irq_handler(int irno)
-{
- rtems_irq_connect_data irq;
-
-#ifdef DEBUG_NE
- printk("ne_init_irq_handler(%d)\n", irno);
-#endif
- irq.name = irno;
- irq.hdl = ne_interrupt_handler;
- irq.handle = (rtems_irq_hdl) irno;
- irq.on = ne_interrupt_on;
- irq.off = ne_interrupt_off;
- irq.isOn = NULL;
-
- if (!BSP_install_rtems_irq_handler (&irq))
- rtems_panic ("Can't attach NE interrupt handler for irq %d\n", irno);
-}
-
-/* The NE2000 packet receive daemon. This task is started when the
- NE2000 driver is initialized. */
-
-#ifdef DEBUG_NE
-static int ccc = 0; /* experinent! */
-#endif
-
-static void
-ne_rx_daemon (void *arg)
-{
- struct ne_softc *sc = (struct ne_softc *) arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned int port = sc->port;
-
- while (1)
- {
- rtems_event_set events;
-
- /* Wait for the interrupt handler to tell us that there is a
- packet ready to receive. */
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- /* Don't let the device interrupt us now. */
- outport_byte (port + IMR, 0);
-
- while (1)
- {
- unsigned char startpage, currpage;
- unsigned short len;
- unsigned char next, cnt1, cnt2;
- struct mbuf *m;
- unsigned char *p;
- int startaddr;
- int toend;
- struct ether_header *eh;
- struct ne_ring hdr; /* ring buffer header */
- int reset;
-
- inport_byte (port + BNRY, startpage);
-
- outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
- inport_byte (port + CURR, currpage);
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
-
- ++startpage;
- if (startpage >= NE_STOP_PAGE)
- startpage = NE_FIRST_RX_PAGE;
-
- if (startpage == currpage)
- break;
-
-#ifdef DEBUG_NE2000
- printk ("ne_rx_daemon: start page %x; current page %x\n",
- startpage, currpage);
-#endif
-
- reset = 0;
-
- /* Read the buffer header */
- startaddr = startpage * NE_PAGE_SIZE;
- ne_read_data(sc, startaddr, sizeof(hdr), (unsigned char *)&hdr);
- next = hdr.next;
- if (next >= NE_STOP_PAGE)
- next = NE_FIRST_RX_PAGE;
-
- /* check packet length */
- len = ( hdr.cnt_hi << 8 ) | hdr.cnt_lo;
- if (currpage < startpage)
- cnt1 = currpage + (NE_STOP_PAGE - NE_FIRST_RX_PAGE) - startpage;
- else
- cnt1 = currpage - startpage;
- cnt2 = len / NE_PAGE_SIZE;
- if (len % NE_PAGE_SIZE)
- cnt2++;
- if (cnt1 < cnt2)
- {
-#ifdef DEBUG_NE
- printk("(%x<%x:%x)", cnt1, cnt2, len);
-/*
- printk("start page 0x%x; current page 0x%x\n",
- startpage, currpage);
- printk("cnt1 < cnt2 (0x%x, 0x%x); len 0x%x\n",
- cnt1, cnt2, len);
-*/
-#endif
- reset = 1;
- }
- if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
- len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
- len > MCLBYTES)
- {
-#ifdef DEBUG_NE
- printk("(%x)", len);
-/*
- printk("start page 0x%x; current page 0x%x\n",
- startpage, currpage);
- printk("len out of range: 0x%x\n", len);
- printk("stat: 0x%x, next: 0x%x\n", hdr.rsr, hdr.next);
-*/
-#endif
- reset = 1;
- }
-#ifdef DEBUG_NE
- if (++ccc == 100)
- { ccc = 0; reset = 1;
- printk("T");
- }
-#endif
-
- /* reset interface */
- if (reset)
- {
- ne_reset(sc);
- goto Next;
- }
-
- /* The first four bytes of the length are the buffer header. */
- len -= sizeof(struct ne_ring);
- startaddr += sizeof(struct ne_ring);
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
-
- p = mtod (m, unsigned char *);
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
-
- toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
- if (toend < len)
- {
- ne_read_data (sc, startaddr, toend, p);
- p += toend;
- len -= toend;
- startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
- }
-
- if (len > 0)
- ne_read_data (sc, startaddr, len, p);
-
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof (struct ether_header);
-
-#ifdef DEBUG_NE
- /* printk("[r%d]", ((hdr.cnt_hi<<8) + hdr.cnt_lo - sizeof(hdr))); */
- printk("<");
-#endif
- ether_input (ifp, eh, m);
- ++sc->stats.rx_packets;
-
- outport_byte (port + BNRY, next - 1);
- }
-
- if (sc->overrun) {
- outport_byte (port + ISR, MSK_OVW);
- outport_byte (port + TCR, 0);
- if (sc->resend)
- outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
- sc->resend = 0;
- sc->overrun = 0;
- }
-
- Next:
- /* Reenable device interrupts. */
- outport_byte (port + IMR, NE_INTERRUPTS);
- }
-}
-
-/* Load an NE2000 packet onto the device. */
-
-static void
-ne_loadpacket (struct ne_softc *sc, struct mbuf *m)
-{
- unsigned int port = sc->port;
- unsigned int dport = port + DATAPORT;
- struct mbuf *mhold = m;
- int leftover;
- unsigned char leftover_data;
- int timeout;
- int send_cnt = 0;
-
-#ifdef DEBUG_NE2000
- printk ("Uploading NE2000 packet\n");
-#endif
-
- /* Reset remote DMA complete flag. */
- outport_byte (port + ISR, MSK_RDC);
-
- /* Write out the count. */
- outport_byte (port + RBCR0, m->m_pkthdr.len);
- outport_byte (port + RBCR1, m->m_pkthdr.len >> 8);
-
- sc->sendlen[sc->nextavail] = m->m_pkthdr.len;
-
- /* Tell the device which address we want to write to. */
- outport_byte (port + RSAR0, 0);
- outport_byte (port + RSAR1,
- NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
-
- /* Set up the write. */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA);
-
- /* Transfer the mbuf chain to device memory. NE2000 devices require
- that the data be transferred as words, so we need to handle odd
- length mbufs. Never occurs if we force byte transfers. */
-
- leftover = 0;
- leftover_data = '\0';
-
- for (; m != NULL; m = m->m_next) {
- int len;
- unsigned char *data;
-
- len = m->m_len;
- if (len == 0)
- continue;
-
- data = mtod (m, unsigned char *);
-
- if (leftover) {
- unsigned char next;
-
- /* Data left over from previous mbuf in chain. */
- next = *data++;
- --len;
- outport_word (dport, leftover_data | (next << 8));
- send_cnt += 2;
- leftover = 0;
- }
-
- /* If using byte transfers, len always ends up as zero so
- there are no leftovers. */
-
- if (sc->byte_transfers)
- while (len > 0) {
- outport_byte (dport, *data++);
- len--;
- }
- else
- while (len > 1) {
- outport_word (dport, data[0] | (data[1] << 8));
- data += 2;
- len -= 2;
- send_cnt += 2;
- }
-
- if (len > 0)
- {
- leftover = 1;
- leftover_data = *data++;
- }
- }
-
- if (leftover)
- {
- outport_word (dport, leftover_data);
- send_cnt += 2;
- }
-
-#ifdef DEBUG_NE
- /* printk("{l%d|%d}", send_cnt, sc->nextavail); */
- printk("v");
-#endif
- m_freem (mhold);
-
- /* Wait for the device to complete accepting the data, with a
- limiting counter so that we don't wait too long. */
- for (timeout = 0; timeout < 100; ++timeout)
- {
- unsigned char status;
-
- inport_byte (port + ISR, status);
-
-#ifdef DEBUG_NE2000
- if ((status &~ MSK_RDC) != 0)
- printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
- status);
-#endif
-
- if ((status & MSK_RDC) != 0) {
- outport_byte (port + ISR, MSK_RDC);
- break;
- }
- }
-
- if (timeout >= 100)
- printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n");
-
- ++sc->nextavail;
- if (sc->nextavail == NE_TX_BUFS)
- sc->nextavail = 0;
-}
-
-/* Tell the NE2000 to transmit a buffer whose contents we have already
- loaded onto the device. */
-
-static void
-ne_transmit (struct ne_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned int port = sc->port;
- int len;
-
-#ifdef DEBUG_NE2000
- printk ("Transmitting NE2000 packet\n");
-#endif
-
- len = sc->sendlen[sc->nextsend];
- if (len < ET_MINLEN)
- len = ET_MINLEN;
- outport_byte (port + TBCR0, len);
- outport_byte (port + TBCR1, len >> 8);
-
- outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES));
-
- outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
-
-#ifdef DEBUG_NE
- /* printk("{s%d|%d}", len, sc->nextsend); */
- printk(">");
-#endif
- ++sc->nextsend;
- if (sc->nextsend == NE_TX_BUFS)
- sc->nextsend = 0;
-
- ++sc->stats.tx_packets;
-
- /* set watchdog timer */
- ifp->if_timer = 2;
-}
-
-/* The NE2000 packet transmit daemon. This task is started when the
- NE2000 driver is initialized. */
-
-static void
-ne_tx_daemon (void *arg)
-{
- struct ne_softc *sc = (struct ne_softc *) arg;
- unsigned int port = sc->port;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- while (1) {
- rtems_event_set events;
-
- /* Wait for a packet to be ready for sending, or for there to be
- room for another packet in the device memory. */
- rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events);
-
-#ifdef DEBUG_NE2000
- printk ("ne_tx_daemon\n");
-#endif
-
- /* This daemon handles both uploading data onto the device and
- telling the device to transmit data which has been uploaded.
- These are separate tasks, because while the device is
- transmitting one buffer we will upload another. */
-
- /* Don't let the device interrupt us now. */
- outport_byte (port + IMR, 0);
-
- while (1) {
- struct mbuf *m;
-
- /* If the device is not transmitting a packet, and we have
- uploaded a packet, tell the device to transmit it. */
- if (! sc->transmitting && sc->inuse > 0) {
- sc->transmitting = 1;
- ne_transmit (sc);
- }
-
- /* If we don't have any more buffers to send, quit now. */
- if (ifp->if_snd.ifq_head == NULL) {
- ifp->if_flags &= ~IFF_OACTIVE;
- break;
- }
-
- /* Allocate a buffer to load data into. If there are none
- available, quit until a buffer has been transmitted. */
- if (sc->inuse >= NE_TX_BUFS)
- break;
-
- ++sc->inuse;
-
- IF_DEQUEUE (&ifp->if_snd, m);
- if (m == NULL)
- panic ("ne_tx_daemon");
-
- ne_loadpacket (sc, m);
-
- /* Check the device status. It may have finished transmitting
- the last packet. */
- ne_check_status(sc, 0);
- }
-
- /* Reenable device interrupts. */
- outport_byte (port + IMR, NE_INTERRUPTS);
- }
-}
-
-/* Start sending an NE2000 packet. */
-
-static void
-ne_start (struct ifnet *ifp)
-{
- struct ne_softc *sc = ifp->if_softc;
-
-#ifdef DEBUG_NE
- printk("S");
-#endif
- /* Tell the transmit daemon to wake up and send a packet. */
- rtems_bsdnet_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/* Initialize and start and NE2000. */
-
-static void
-ne_init (void *arg)
-{
- struct ne_softc *sc = (struct ne_softc *) arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
-#ifdef DEBUG_NE
- printk("ne_init()\n");
- ne_dump(sc);
-#endif
-
- /* only once... */
- if (sc->tx_daemon_tid == 0)
- {
- sc->inuse = 0;
- sc->nextavail = 0;
- sc->nextsend = 0;
- sc->transmitting = 0;
-
- ne_init_hardware (sc);
-
- sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
- sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
-
- /* install rtems irq handler */
- ne_init_irq_handler(sc->irno);
- }
-
- ifp->if_flags |= IFF_RUNNING;
-}
-
-/* Stop an NE2000. */
-
-static void
-ne_stop (struct ne_softc *sc)
-{
- sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
-
- ne_stop_hardware(sc);
-
- sc->inuse = 0;
- sc->nextavail = 0;
- sc->nextsend = 0;
- sc->transmitting = 0;
- sc->overrun = 0;
- sc->resend = 0;
-}
-
-static void
-ne_stop_hardware (struct ne_softc *sc)
-{
- unsigned int port = sc->port;
- int i;
-
- /* Stop everything. */
- outport_byte (port + CMDR, MSK_STP | MSK_RD2);
-
- /* Wait for the interface to stop, using I as a time limit. */
- for (i = 0; i < 5000; ++i)
- {
- unsigned char status;
-
- inport_byte (port + ISR, status);
- if ((status & MSK_RST) != 0)
- break;
- }
-}
-
-/* reinitializing interface
-*/
-static void
-ne_reset(struct ne_softc *sc)
-{
- ne_stop(sc);
- ne_init_hardware(sc);
- sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
-#ifdef DEBUG_NE
- printk("*");
-#endif
-}
-
-#ifdef DEBUG_NE
-/* show anything about ne
-*/
-static void
-ne_dump(struct ne_softc *sc)
-{
- int i;
- printk("\nne configuration:\n");
- printk("ethernet addr:");
- for (i=0; i<ETHER_ADDR_LEN; i++)
- printk(" %x", sc->arpcom.ac_enaddr[i]);
- printk("\n");
- printk("irq = %d\n", sc->irno);
- printk("port = 0x%x\n", sc->port);
- printk("accept_broadcasts = %d\n", sc->accept_broadcasts);
- printk("byte_transfers = %d\n", sc->byte_transfers);
-}
-#endif
-
-/* Show NE2000 interface statistics. */
-
-static void
-ne_stats (struct ne_softc *sc)
-{
- printf (" Received packets: %-8lu", sc->stats.rx_packets);
- printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets);
- printf (" Receive acks: %-8lu", sc->stats.rx_acks);
- printf (" Transmit acks: %-8lu\n", sc->stats.tx_acks);
- printf (" Packet overruns: %-8lu", sc->stats.overruns);
- printf (" Frame errors: %-8lu\n", sc->stats.rx_frame_errors);
- printf (" CRC errors: %-8lu", sc->stats.rx_crc_errors);
- printf (" Missed packets: %-8lu\n", sc->stats.rx_missed_errors);
- printf (" Interrupts: %-8lu\n", sc->stats.interrupts);
-}
-
-static int ne_set_multicast_filter(struct ne_softc* sc)
-{
- int i=0;
- unsigned int port = sc->port;
- unsigned char cmd = 0;
-
- /* Save CMDR settings */
- inport_byte(port + CMDR, cmd);
- /* Change to page 1 */
- outport_byte(port + CMDR, cmd | MSK_PG1);
-
- /* Set MAR to accept _all_ multicast packets */
- for (i = 0; i < MARsize; ++i) {
- outport_byte (port + MAR + i, 0xFF);
- }
-
- /* Revert to original CMDR settings */
- outport_byte(port + CMDR, cmd);
-
- return 0;
-}
-
-/* NE2000 driver ioctl handler. */
-
-static int
-ne_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct ne_softc *sc = ifp->if_softc;
- int error = 0;
-
- switch (command) {
- case SIOCGIFADDR:
- case SIOCSIFADDR:
- error = ether_ioctl (ifp, command, data);
- break;
-
- case SIOCSIFFLAGS:
- switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
- case IFF_RUNNING:
- ne_stop (sc);
- break;
-
- case IFF_UP:
- ne_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- ne_stop (sc);
- ne_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- {
- struct ifreq* ifr = (struct ifreq*) data;
- error = (command == SIOCADDMULTI ?
- ether_addmulti(ifr, &(sc->arpcom)) :
- ether_delmulti(ifr, &(sc->arpcom)) );
- /* ENETRESET indicates that driver should update its multicast filters */
- if(error == ENETRESET) {
- error = ne_set_multicast_filter(sc);
- }
- break;
- }
-
- case SIO_RTEMS_SHOW_STATS:
- ne_stats (sc);
- break;
-
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-/*
- * Device timeout/watchdog routine. Entered if the device neglects to
- * generate an interrupt after a transmit has been started on it.
- */
-static void
-ne_watchdog(struct ifnet *ifp)
-{
- struct ne_softc *sc = ifp->if_softc;
-
- printk("ne2000: device timeout\n");
- ifp->if_oerrors++;
-
- ne_reset(sc);
-}
-
-static void
-print_byte(unsigned char b)
-{
- printk("%x%x", b >> 4, b & 0x0f);
-}
-
-/* Attach an NE2000 driver to the system. */
-
-int
-rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
-{
- int i;
- struct ne_softc *sc;
- struct ifnet *ifp;
- int mtu;
-
- /* dettach ... */
- if (!attach)
- return 0;
-
- /* Find a free driver. */
- sc = NULL;
- for (i = 0; i < NNEDRIVER; ++i) {
- sc = &ne_softc[i];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc == NULL)
- break;
- }
-
- if (sc == NULL) {
- printf ("Too many NE2000 drivers.\n");
- return 0;
- }
-
- memset (sc, 0, sizeof *sc);
-
- /* Check whether we do byte-wide or word-wide transfers. */
-
-#ifdef NE2000_BYTE_TRANSFERS
- sc->byte_transfers = true;
-#else
- sc->byte_transfers = false;
-#endif
-
- /* Handle the options passed in by the caller. */
-
- if (config->mtu != 0)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- if (config->irno != 0)
- sc->irno = config->irno;
- else {
- const char* opt;
- opt = bsp_cmdline_arg ("--ne2k-irq=");
- if (opt) {
- opt += sizeof ("--ne2k-irq=") - 1;
- sc->irno = strtoul (opt, 0, 0);
- }
- if (sc->irno == 0) {
- /* We use 5 as the default IRQ. */
- sc->irno = 5;
- }
- }
-
- if (config->port != 0)
- sc->port = config->port;
- else {
- const char* opt;
- opt = bsp_cmdline_arg ("--ne2k-port=");
- if (opt) {
- opt += sizeof ("--ne2k-port=") - 1;
- sc->port = strtoul (opt, 0, 0);
- }
- if (config->port == 0) {
- /* We use 0x300 as the default IO port number. */
- sc->port = 0x300;
- }
- }
-
- sc->accept_broadcasts = ! config->ignore_broadcast;
-
- if (config->hardware_address != NULL)
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
- ETHER_ADDR_LEN);
- else
- {
- unsigned char prom[16];
- int ia;
-
- /* Read the PROM to get the Ethernet hardware address. */
-
- outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- if (sc->byte_transfers) {
- outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
- }
- else {
- outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
- }
-
- outport_byte (sc->port + RBCR0, 0);
- outport_byte (sc->port + RBCR1, 0);
- outport_byte (sc->port + RCR, MSK_MON);
- outport_byte (sc->port + TCR, MSK_LOOP);
- outport_byte (sc->port + IMR, 0);
- outport_byte (sc->port + ISR, 0xff);
-
- ne_read_data (sc, 0, sizeof prom, prom);
-
- outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
- sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
- }
-
- /* Set up the network interface. */
-
- ifp->if_softc = sc;
- ifp->if_unit = i + 1;
- ifp->if_name = "ne";
- ifp->if_mtu = mtu;
- ifp->if_init = ne_init;
- ifp->if_ioctl = ne_ioctl;
- ifp->if_watchdog = ne_watchdog;
- ifp->if_start = ne_start;
- ifp->if_output = ether_output;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- if (ifp->if_snd.ifq_maxlen == 0)
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
-
- /* Attach the interface. */
-
- if_attach (ifp);
- ether_ifattach (ifp);
-
- printk("network device '%s' <", config->name);
- print_byte(sc->arpcom.ac_enaddr[0]);
- for (i=1; i<ETHER_ADDR_LEN; i++)
- { printk(":");
- print_byte(sc->arpcom.ac_enaddr[i]);
- }
- printk("> initialized on port 0x%x, irq %d\n", sc->port, sc->irno);
-
- return 1;
-}
diff --git a/c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c b/c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c
deleted file mode 100644
index d10361bf2c..0000000000
--- a/c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * RTEMS driver for WD800x
- *
- * Based on the 68360 Network Driver by:
- * W. Eric Norum
- * Saskatchewan Accelerator Laboratory
- * University of Saskatchewan
- * Saskatoon, Saskatchewan, CANADA
- * eric@skatter.usask.ca
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <libchip/wd80x3.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h> /* memcpy, memset */
-#include <errno.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <assert.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <bsp/irq.h>
-
-#define ET_MINLEN 60 /* minimum message length */
-
-/*
- * Number of WDs supported by this driver
- */
-#define NWDDRIVER 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 driver tasks.
- * This must not be any of the events used by the network task synchronization.
- */
-#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
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-#define RBUF_SIZE 1520
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/*
- * Per-device data
- */
-struct wd_softc {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
- rtems_vector_number name;
-
- unsigned int port;
- unsigned char *base;
- unsigned long bpar;
-
- /*
- * 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;
-};
-
-#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 volatile unsigned long overrun;
-static volatile unsigned long resend;
-static struct wd_softc wd_softc[NWDDRIVER];
-
-/*
- * WD interrupt handler
- */
-static void
-wd8003Enet_interrupt_handler (void * unused)
-{
- unsigned int tport;
- unsigned char status, status2;
-
- tport = wd_softc[0].port ;
-
- /*
- * Read status
- */
- inport_byte(tport+ISR, status);
- outport_byte(tport+IMR, 0x00);
-
- /*
- * Ring overwrite
- */
-
- if (status & MSK_OVW){
- outport_byte(tport+CMDR, MSK_STP + MSK_RD2); /* stop 8390 */
- Wait_X_ms(2);
- 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 */
- overrun = 1 ;
- if ((status & (MSK_PTX+MSK_TXE)) == 0)
- resend = 1;
- }
-
- /*
- * Frame received?
- */
- if (status & (MSK_PRX+MSK_RXE)) {
- outport_byte(tport+ISR, status & (MSK_PRX+MSK_RXE));
- wd_softc[0].rxInterrupts++;
- rtems_bsdnet_event_send (wd_softc[0].rxDaemonTid, INTERRUPT_EVENT);
- }
-
-}
-
-/*
- * Initialize the ethernet hardware
- */
-static void
-wd8003Enet_initialize_hardware (struct wd_softc *sc)
-{
- int i1, ultra;
- char cc1, cc2;
- unsigned char temp;
- rtems_status_code status;
- unsigned int tport;
- unsigned char *hwaddr;
-
- tport = sc->port;
-
- /* address from board ROM */
- inport_byte(tport+0x04, temp);
- outport_byte(tport+0x04, temp & 0x7f);
-
- hwaddr = sc->arpcom.ac_enaddr;
- for (i1=cc2=0; i1<8; i1++) {
- inport_byte(tport + ADDROM + i1, cc1);
- cc2 += cc1;
- if (i1 < 6)
- 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)((sc->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); /* enable interrupt */
-
- outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
-
- for (i1=0; i1<6; i1++) /* initial physical addr */
- outport_byte(tport+PAR+i1, 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
- */
-
- status = rtems_interrupt_handler_install(
- sc->name,
- "wd8003",
- RTEMS_INTERRUPT_UNIQUE,
- wd8003Enet_interrupt_handler,
- NULL
- );
- assert(status == RTEMS_SUCCESSFUL);
-}
-
-static void
-wd_rxDaemon (void *arg)
-{
- unsigned int tport;
- struct ether_header *eh;
- struct wd_softc *dp = (struct wd_softc *)&wd_softc[0];
- struct ifnet *ifp = &dp->arpcom.ac_if;
- struct mbuf *m;
- unsigned int i2;
- unsigned int len;
- volatile unsigned char start, next, current;
- unsigned char *shp, *temp;
- unsigned short *real_short_ptr;
- rtems_event_set events;
-
- tport = wd_softc[0].port ;
-
- for (;;){
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- for (;;){
- inport_byte(tport+BNRY, start);
-
- outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2);
- inport_byte(tport+CURR, current);
- outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2);
-
- start += 1;
- if (start >= OUTPAGE){
- start = 0;
- }
-
- if (current == start)
- break;
-
- /* real_short_ptr avoids cast on lvalue which gcc no longer allows */
- shp = dp->base + 1 + (SHAPAGE * start);
- next = *shp++;
- real_short_ptr = (unsigned short *)shp;
- len = *(real_short_ptr)++ - 4;
-
- if (next >= OUTPAGE){
- next = 0;
- }
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
-
- temp = (unsigned char *) m->m_data;
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
-
- if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){
- memcpy(temp, shp, i2);
- len -= i2;
- temp += i2;
- shp = dp->base;
- }
- memcpy(temp, shp, len);
-
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input (ifp, eh, m);
-
- outport_byte(tport+BNRY, next-1);
- }
-
- /*
- * Ring overwrite
- */
- if (overrun){
- outport_byte(tport+ISR, MSK_OVW); /* reset IR */
- outport_byte(tport+TCR, 0); /* out of loopback */
- if (resend == 1)
- outport_byte(tport+CMDR, MSK_TXP + MSK_RD2); /* resend */
- resend = 0;
- overrun = 0;
- }
-
- outport_byte(tport+IMR, 0x15); /* re-enable IT rx */
- }
-}
-
-static void
-sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct wd_softc *dp = ifp->if_softc;
- struct mbuf *n;
- unsigned int len, tport;
- uint8_t *shp, txReady;
-
- tport = dp->port;
-
- /*
- * Waiting for Transmitter ready
- */
- inport_byte(tport+CMDR, txReady);
- while(txReady & MSK_TXP)
- inport_byte(tport+CMDR, txReady);
-
- len = 0;
- shp = dp->base + (SHAPAGE * OUTPAGE);
-
- n = m;
-
- for (;;){
- len += m->m_len;
- memcpy(shp, (char *)m->m_data, m->m_len);
- shp += m->m_len ;
- if ((m = m->m_next) == NULL)
- break;
- }
-
- m_freem(n);
-
- 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);
-}
-
-/*
- * Driver transmit daemon
- */
-static void
-wd_txDaemon (void *arg)
-{
- struct wd_softc *sc = (struct wd_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;
- sendpacket (ifp, m);
- }
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-}
-
-/*
- * Send packet (caller provides header).
- */
-static void
-wd_start (struct ifnet *ifp)
-{
- struct wd_softc *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/*
- * Initialize and start the device
- */
-static void
-wd_init (void *arg)
-{
- struct wd_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
-
- /*
- * Set up WD hardware
- */
- wd8003Enet_initialize_hardware (sc);
-
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, wd_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, wd_rxDaemon, sc);
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
-}
-
-/*
- * Stop the device
- */
-static void
-wd_stop (struct wd_softc *sc)
-{
- unsigned int tport;
- unsigned char temp;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Stop the transmitter
- */
- tport=wd_softc[0].port ;
- inport_byte(tport+0x04,temp);
- outport_byte(tport+0x04, temp & 0x7f);
- outport_byte(tport + CMDR, MSK_STP + MSK_RD2);
-
-}
-
-/*
- * Show interface statistics
- */
-static void
-wd_stats (struct wd_softc *sc)
-{
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Not First:%-8lu", sc->rxNotFirst);
- printf (" Not Last:%-8lu\n", sc->rxNotLast);
- printf (" Giant:%-8lu", sc->rxGiant);
- printf (" Runt:%-8lu", sc->rxRunt);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Overrun:%-8lu", sc->rxOverrun);
- printf (" Collision:%-8lu\n", sc->rxCollision);
-
- printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
- printf (" Deferred:%-8lu", sc->txDeferred);
- printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
- printf (" No Carrier:%-8lu", sc->txLostCarrier);
- printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
- printf (" Late Collision:%-8lu\n", sc->txLateCollision);
- printf (" Underrun:%-8lu", sc->txUnderrun);
- printf (" Raw output wait:%-8lu\n", sc->txRawWait);
-}
-
-/*
- * Driver ioctl handler
- */
-static int
-wd_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct wd_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:
- wd_stop (sc);
- break;
-
- case IFF_UP:
- wd_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- wd_stop (sc);
- wd_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- wd_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-/*
- * Attach an WD driver to the system
- */
-int
-rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
-{
- struct wd_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int i;
-
- /*
- * Find a free driver
- */
- for (i = 0 ; i < NWDDRIVER ; i++) {
- sc = &wd_softc[i];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc == NULL)
- break;
- }
- if (i >= NWDDRIVER) {
- printf ("Too many WD drivers.\n");
- return 0;
- }
-
- /*
- * 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->irno)
- sc->name = config->irno;
- else
- sc->name = 5;
-
- if (config->port)
- sc->port = config->port;
- else
- sc->port = 0x240;
-
- if (config->bpar) {
- sc->bpar = config->bpar;
- sc->base = (unsigned char*) config->bpar;
- }
- else {
- sc->bpar = 0xD0000;
- sc->base = (unsigned char*) 0xD0000;
- }
-
- sc->acceptBroadcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = i + 1;
- ifp->if_name = "wd";
- ifp->if_mtu = mtu;
- ifp->if_init = wd_init;
- ifp->if_ioctl = wd_ioctl;
- ifp->if_start = wd_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;
-
- /*
- * init some variables
- */
- overrun = 0;
- resend = 0;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
- return 1;
-};