diff options
Diffstat (limited to 'bsps/arm/gumstix')
-rw-r--r-- | bsps/arm/gumstix/net/rtl8019.c | 1197 | ||||
-rw-r--r-- | bsps/arm/gumstix/net/wd80x3.h | 303 |
2 files changed, 0 insertions, 1500 deletions
diff --git a/bsps/arm/gumstix/net/rtl8019.c b/bsps/arm/gumstix/net/rtl8019.c deleted file mode 100644 index 00fd2fdf09..0000000000 --- a/bsps/arm/gumstix/net/rtl8019.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* - *By Yang Xi <hiyangxi@gmail.com>. - *RTL8019 ethernet driver for Gumstix on SKYEYE simulator - *Based on NE2000 driver for pc386 bsp - * - * 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. - */ - -#include <machine/rtems-bsd-kernel-space.h> - -#include <bsp.h> -#include <bsp/irq.h> -#include "wd80x3.h" - -#include <stdio.h> -#include <assert.h> -#include <errno.h> - -#include <rtems/bspIo.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 <net/if_arp.h> - -#include <netinet/in.h> -#include <netinet/if_ether.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 short count; /* bytes in packet (length + 4) */ -}; - -/* Forward declarations to avoid warnings */ - -static void ne_init_irq_handler (struct ne_softc *sc); -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 - -/* 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); -#ifdef DEBUG_NE2000 - printk ("NE2000 status 0x%x\n", status); -#endif - if (status == 0) - break; - - /* ack */ - outport_byte (port + ISR, status); - - /* Check for incoming packet overwrite. */ - if (status & MSK_OVW) - { - ifp->if_timer = 0; -#ifdef DEBUG_NE - printk("^\n"); -#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; - } - - outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2); - -} - -/* Handle an NE2000 interrupt. */ - -static void -ne_interrupt_handler (void *arg) -{ - struct ne_softc *sc = arg; - - 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 (struct ne_softc *sc) -{ -#ifdef DEBUG_NE - printk ("ne_interrupt_on()\n"); -#endif - if (sc != NULL) - outport_byte (sc->port + IMR, NE_INTERRUPTS); -} - -/* 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 */ - outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0)); - - /* 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(struct ne_softc *sc) -{ - rtems_status_code status = RTEMS_SUCCESSFUL; - -#ifdef DEBUG_NE - printk("ne_init_irq_handler(%d)\n", sc->irno); -#endif - - status = rtems_interrupt_handler_install( - sc->irno, - "RTL8019", - RTEMS_INTERRUPT_UNIQUE, - ne_interrupt_handler, - sc - ); - assert(status == RTEMS_SUCCESSFUL); - ne_interrupt_on(sc); -} - -/* 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 = NULL; - 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.count; - 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)\n", 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) - { - printk("Reset in RX\n"); - ne_reset(sc); - goto Next; - } - - /* The first four bytes of the length are the buffer header - * Just decrease them by 2 since in ARM, we have to make sure - * 4bytes memory access align on 4bytes - */ - len -= 2; - startaddr += 2; - - MGETHDR (m, M_WAIT, MT_DATA); - MCLGET (m, M_WAIT); - - if (m == NULL) - panic ("ne_rx_daemon"); - - m->m_pkthdr.rcvif = ifp; - m->m_nextpkt = 0; - - p = mtod (m, unsigned char *); - m->m_len = m->m_pkthdr.len = len - (sizeof(struct ether_header) + 2); - - 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); - - m->m_data +=2; - eh = mtod(m, struct ether_header *); - m->m_data += sizeof (struct ether_header); - -#ifdef DEBUG_NE - /*printk("[r%d]", hdr.count - sizeof(hdr));*/ - printk("<\n"); -#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 < 1000; ++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 >= 1000) - 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); - } - - 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); -} - -/* 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: - printk("IFF_UP\n"); - ne_init (sc); - break; - - case IFF_UP | IFF_RUNNING: - ne_stop (sc); - ne_init (sc); - break; - - default: - break; - } - break; - - case SIO_RTEMS_SHOW_STATS: - ne_stats (sc); - break; - - /* FIXME: Multicast commands must be added here. */ - - 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; - - /* We use 16 as the default IRQ. */ - sc->irno = XSCALE_IRQ_NETWORK; - - - - /*IO prts are mapped to 0X40000600 */ - sc->port = 0x40000600; - - 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; - 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/bsps/arm/gumstix/net/wd80x3.h b/bsps/arm/gumstix/net/wd80x3.h deleted file mode 100644 index 0a9f3432bc..0000000000 --- a/bsps/arm/gumstix/net/wd80x3.h +++ /dev/null @@ -1,303 +0,0 @@ -/** - * @file - * @ingroup gumstix_dp8390 - * @brief DP8390 Ethernet Controller Support - */ - -/* - * Information about the DP8390 Ethernet controller. - */ - -#ifndef __BSP_WD80x3_h -#define __BSP_WD80x3_h - -/* Register descriptions */ - -/** - * @defgroup gumstix_dp8390 DP8390 Support - * @ingroup RTEMSBSPsARMGumstix - * @brief DP8390 Ethernet Controller Support - * @{ - */ - -/** - * @name Controller DP8390. - * @{ - */ - -/** @brief Port Window. */ -#define DATAPORT 0x10 -/** @brief Issue a read for reset */ -#define RESET 0x1f -/** @brief I/O port definition */ -#define W83CREG 0x00 -#define ADDROM 0x08 - -/** @} */ - -/** - * @name page 0 read or read/write registers - * @{ - */ - -#define CMDR 0x00+RO -/** @brief current local dma addr 0 for read */ -#define CLDA0 0x01+RO -/** @brief current local dma addr 1 for read */ -#define CLDA1 0x02+RO -/** @brief boundary reg for rd and wr */ -#define BNRY 0x03+RO -/** @brief tx status reg for rd */ -#define TSR 0x04+RO -/** @brief number of collision reg for rd */ -#define NCR 0x05+RO -/** @breif FIFO for rd */ -#define FIFO 0x06+RO -/** @brief interrupt status reg for rd and wr */ -#define ISR 0x07+RO -/** @brief current remote dma address 0 for rd */ -#define CRDA0 0x08+RO -/** @brief current remote dma address 1 for rd */ -#define CRDA1 0x09+RO -/** @brief rx status reg for rd */ -#define RSR 0x0C+RO -/** @brief tally cnt 0 for frm alg err for rd */ -#define CNTR0 0x0D+RO -/** @brief tally cnt 1 for crc err for rd */ -#define CNTR1 RO+0x0E -/** @brief tally cnt 2 for missed pkt for rd */ -#define CNTR2 0x0F+RO - -/** @} */ - -/** - * @name page 0 write registers - * @{ - */ - -/** @brief page start register */ -#define PSTART 0x01+RO -/** @brief page stop register */ -#define PSTOP 0x02+RO -/** @breif tx start page start reg */ -#define TPSR 0x04+RO -/** @brief tx byte count 0 reg */ -#define TBCR0 0x05+RO -/** @brief tx byte count 1 reg */ -#define TBCR1 0x06+RO -/** @brief remote start address reg 0 */ -#define RSAR0 0x08+RO -/** @brief remote start address reg 1 */ -#define RSAR1 0x09+RO -/** @brief remote byte count reg 0 */ -#define RBCR0 0x0A+RO -/** @brief remote byte count reg 1 */ -#define RBCR1 0x0B+RO -/** @brief rx configuration reg */ -#define RCR 0x0C+RO -/** @brief tx configuration reg */ -#define TCR 0x0D+RO -/** @brief data configuration reg */ -#define DCR RO+0x0E -/** @brief interrupt mask reg */ -#define IMR 0x0F+RO - -/** @} */ - -/** - * @name page 1 registers - * @{ - */ - -/** @brief physical addr reg base for rd and wr */ -#define PAR 0x01+RO -/** @brief current page reg for rd and wr */ -#define CURR 0x07+RO -/** @brief multicast addr reg base fro rd and WR */ -#define MAR 0x08+RO -/** @brief size of multicast addr space */ -#define MARsize 8 - -/** @} */ - -/** - * @name W83CREG command bits - * @{ - */ - -/** @brief W83CREG masks */ -#define MSK_RESET 0x80 -#define MSK_ENASH 0x40 -/** @brief memory decode bits, corresponding */ -#define MSK_DECOD 0x3F - -/** @} */ - -/** - * @name CMDR command bits - * @{ - */ - -/** @brief stop the chip */ -#define MSK_STP 0x01 -/** @brief start the chip */ -#define MSK_STA 0x02 -/** @brief initial txing of a frm */ -#define MSK_TXP 0x04 -/** @brief remote read */ -#define MSK_RRE 0x08 -/** @brief remote write */ -#define MSK_RWR 0x10 -/** @brief no DMA used */ -#define MSK_RD2 0x20 -/** @brief select register page 0 */ -#define MSK_PG0 0x00 -/** @brief select register page 1 */ -#define MSK_PG1 0x40 -/** @brief select register page 2 */ -#define MSK_PG2 0x80 - -/** @} */ - -/** - * @name ISR and TSR status bits - * @{ - */ - -/* @brief rx with no error */ -#define MSK_PRX 0x01 -/* @brief tx with no error */ -#define MSK_PTX 0x02 -/* @brief rx with error */ -#define MSK_RXE 0x04 -/* @brief tx with error */ -#define MSK_TXE 0x08 -/* @brief overwrite warning */ -#define MSK_OVW 0x10 -/* @brief MSB of one of the tally counters is set */ -#define MSK_CNT 0x20 -/* @brief remote dma completed */ -#define MSK_RDC 0x40 -/* @brief reset state indicator */ -#define MSK_RST 0x80 - -/** @} */ - -/** - * @name DCR command bits - * @{ - */ - -/** @brief word transfer mode selection */ -#define MSK_WTS 0x01 -/** @brief byte order selection */ -#define MSK_BOS 0x02 -/** @brief long addr selection */ -#define MSK_LAS 0x04 -/** @brief burst mode selection */ -#define MSK_BMS 0x08 -/** @brief autoinitialize remote */ -#define MSK_ARM 0x10 -/** @brief burst lrngth selection */ -#define MSK_FT00 0x00 -/** @brief burst lrngth selection */ -#define MSK_FT01 0x20 -/** @brief burst lrngth selection */ -#define MSK_FT10 0x40 -/** @brief burst lrngth selection */ -#define MSK_FT11 0x60 - -/** @} */ - -/** - * @name RCR command bits - * @{ - */ - -/** @brief save error pkts */ -#define MSK_SEP 0x01 -/** @brief accept runt pkt */ -#define MSK_AR 0x02 -/** @brief 8390 RCR */ -#define MSK_AB 0x04 -/** @brief accept multicast */ -#define MSK_AM 0x08 -/** @brief accept all pkt with physical adr */ -#define MSK_PRO 0x10 -/** @brief monitor mode */ -#define MSK_MON 0x20 - -/** @} */ - -/** - * @name TCR command bits - * @{ - */ - -/** @brief inhibit CRC, do not append crc */ -#define MSK_CRC 0x01 -/** @brief set loopback mode */ -#define MSK_LOOP 0x02 -/** @brief Accept broadcasts */ -#define MSK_BCST 0x04 -/** @brief encoded loopback control */ -#define MSK_LB01 0x06 -/** @brief auto tx disable */ -#define MSK_ATD 0x08 -/** @brief collision offset enable */ -#define MSK_OFST 0x10 - -/** @} */ - -/** - * @name receive status bits - * @{ - */ - -/** @brief rx without error */ -#define SMK_PRX 0x01 -/** @brief CRC error */ -#define SMK_CRC 0x02 -/** @brief frame alignment error */ -#define SMK_FAE 0x04 -/** @brief FIFO overrun */ -#define SMK_FO 0x08 -/** @brief missed pkt */ -#define SMK_MPA 0x10 -/** @brief physical/multicase address */ -#define SMK_PHY 0x20 -/** @brief receiver disable. set in monitor mode */ -#define SMK_DIS 0x40 -/** @brief deferring */ -#define SMK_DEF 0x80 - -/** @} */ - -/** - * @name transmit status bits - * @{ - */ - -/** @brief tx without error */ -#define SMK_PTX 0x01 -/** @brief non deferred tx */ -#define SMK_DFR 0x02 -/** @brief tx collided */ -#define SMK_COL 0x04 -/** @brief tx abort because of excessive collisions */ -#define SMK_ABT 0x08 -/** @brief carrier sense lost */ -#define SMK_CRS 0x10 -/** @brief FIFO underrun */ -#define SMK_FU 0x20 -/** @brief collision detect heartbeat */ -#define SMK_CDH 0x40 -/** @brief out of window collision */ -#define SMK_OWC 0x80 - -/** @} */ - -/** @} */ - -#endif -/* end of include */ |