summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mvme2307/network/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mvme2307/network/network.c')
-rw-r--r--c/src/lib/libbsp/powerpc/mvme2307/network/network.c946
1 files changed, 0 insertions, 946 deletions
diff --git a/c/src/lib/libbsp/powerpc/mvme2307/network/network.c b/c/src/lib/libbsp/powerpc/mvme2307/network/network.c
deleted file mode 100644
index 6f147ec6f0..0000000000
--- a/c/src/lib/libbsp/powerpc/mvme2307/network/network.c
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * RTEMS driver for TULIP based Ethernet Controller
- *
- * $Header$
- */
-
-
-
-/* make sure we can identify the platform (is __i386 valid?) */
-#if !defined(__PPC) && !defined(__i386)
-# error "unknown platform: should be __i386 or __PPC"
-#endif
-
-
-#include <bsp.h>
-#if defined(i386)
-#include <pcibios.h>
-#endif
-
-/* #include <stdlib.h> */
-#include <stdio.h>
-#include <stdarg.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <rtems/score/cpu.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>
-
-#if defined(i386)
-#include <irq.h>
-#endif
-
-#ifdef malloc
-#undef malloc
-#endif
-#ifdef free
-#undef free
-#endif
-
-#define PCI_VENDOR_ID_DEC 0x1011
-#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
-
-#define IO_MASK 0x3
-#define MEM_MASK 0xF
-
-/* command and status registers, 32-bit access, only if MEMORY-ACCESS */
-#define CSR0 0x00 /* bus mode register */
-#define CSR1 0x02 /* transmit poll demand */
-#define CSR2 0x04 /* receive poll demand */
-#define CSR3 0x06 /* receive list base address */
-#define CSR4 0x08 /* transmit list base address */
-#define CSR5 0x0A /* status register */
-#define CSR6 0x0C /* operation mode register */
-#define CSR7 0x0E /* interrupt mask register */
-#define CSR8 0x10 /* missed frame counter */
-#define CSR9 0x12 /* Ethernet ROM register */
-#define CSR10 0x14 /* reserved */
-#define CSR11 0x16 /* full-duplex register */
-#define CSR12 0x18 /* SIA status register */
-#define CSR13 0x1A
-#define CSR14 0x1C
-#define CSR15 0x1E /* SIA general register */
-
-#define DEC_REGISTER_SIZE 0x100 /* to reserve virtual memory */
-
-#define RESET_CHIP 0x00000001
-#if defined(__PPC)
-#define CSR0_MODE 0x0020E002
-#define CSR6_INIT 0x0224c000
-#else
-#define CSR0_MODE 0x01a08000
-#define CSR6_INIT 0x020c0000
-#endif
-#define ROM_ADDRESS 0x00004800
-#define CSR6_TX 0x00002000
-#define CSR6_TXRX 0x00002002
-#define IT_SETUP 0x0001a3ef
-#define CLEAR_IT 0xFFFFFFFF
-#define NO_IT 0x00000000
-
-#define SETUP_PACKET 0x08000000
-#define END_OF_RING 0x02000000
-#define CHAINED_ADDRESS 0x01000000
-#define OWNED_BY_DEC21140 0x80000000
-#define OWNED_BY_HOST 0x00000000
-#define LAST_SEGMENT 0x40000000
-#define FIRST_SEGMENT 0x20000000
-
-#define NRXBUFS 8 /* number of receive buffers */
-#define NTXBUFS 32 /* number of transmit buffers */
-
-/* message descriptor entry */
-struct MD {
- /* used by hardware */
- volatile unsigned32 status;
- volatile unsigned32 counts;
- unsigned32 buf1, buf2;
- /* used by software */
- struct mbuf *m;
- struct MD *next;
-};
-
-static inline void write_descr_status(volatile struct MD *m, unsigned32 status) {
- st_le32(&(m->status), status);
-}
-
-static inline unsigned32 read_descr_status(volatile struct MD *m) {
- return ld_le32(&(m->status));
-}
-
-static inline void write_descr_counts(volatile struct MD *m, unsigned32 counts) {
- st_le32(&(m->counts), counts);
-}
-
-static inline unsigned32 read_descr_counts(volatile struct MD *m) {
- return ld_le32(&(m->counts));
-}
-
-static inline void set_chain_address(volatile struct MD *m, void *addr) {
- st_le32(&(m->buf2), LOCAL_TO_PCI(addr));
-}
-
-static inline void set_buffer_address(volatile struct MD *m, void *addr) {
- st_le32(&(m->buf1), LOCAL_TO_PCI(addr));
-}
-
-static inline void *get_buffer_address(volatile struct MD *m) {
- return (void *)INVERSE_LOCAL_TO_PCI(ld_le32(&(m->buf1)));
-}
-
-/*
- * Number of WDs supported by this driver
- */
-#define NDECDRIVER 1
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-#define RBUF_SIZE 1520
-
-#define ET_MINLEN 60 /* minimum message length */
-
-/*
- * 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
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/*
- * Per-device data
- */
-struct dec21140_softc {
- struct arpcom arpcom;
-#if defined(__PPC)
- int irqInfo;
-#else
- rtems_irq_connect_data irqInfo;
-#endif
- struct MD *MDbase;
- char *bufferBase;
- int acceptBroadcast;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- struct MD *TxMD;
- struct MD *SentTxMD;
- int PendingTxCount;
- int TxSuspended;
-
- unsigned32 port;
- unsigned32 *base;
-
- /*
- * Statistics
- */
- unsigned32 rxInterrupts;
- unsigned32 rxNotFirst;
- unsigned32 rxNotLast;
- unsigned32 rxGiant;
- unsigned32 rxNonOctet;
- unsigned32 rxRunt;
- unsigned32 rxBadCRC;
- unsigned32 rxOverrun;
- unsigned32 rxCollision;
-
- unsigned32 txInterrupts;
- unsigned32 txDeferred;
- unsigned32 txHeartbeat;
- unsigned32 txLateCollision;
- unsigned32 txRetryLimit;
- unsigned32 txUnderrun;
- unsigned32 txLostCarrier;
- unsigned32 txRawWait;
-};
-
-static struct dec21140_softc dec21140_softc[NDECDRIVER];
-static rtems_interval ticks_per_second;
-
-/* ================================================================ */
-
-static inline void write_csr(unsigned32 *base, int csr, unsigned32 value) {
- synchronize_io();
- st_le32(base + csr, value);
-}
-
-static inline unsigned32 read_csr(unsigned32 *base, int csr) {
- synchronize_io();
- return ld_le32(base + csr);
-}
-
-
-
-
-/* ================================================================ */
-
-/*
- * DEC21140 interrupt handler
- */
-static rtems_isr dec21140Enet_interrupt_handler (rtems_vector_number v) {
- unsigned32 *tbase;
- unsigned32 status;
- struct dec21140_softc *sc;
-
-#if NDECDRIVER == 1
- sc = &dec21140_softc[0];
-#else
-# error "need to find dec21140_softc[i] based on vector number"
-#endif
- tbase = sc->base ;
-
- /*
- * Read status
- */
- status = read_csr(tbase, CSR5);
- write_csr(tbase, CSR5, status); /* clear the bits we've read */
-
- /*
- * severe error?
- */
- if (status & 0x0000230a){
- printk("FATAL ERROR in network driver: CSR5=0x%08x\n", status);
- }
- /*
- * Frame received?
- */
- if (status & 0x000000c0){
- sc->rxInterrupts++;
- rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
- }
-
- /*
- * Frame transmitted or transmit error?
- */
- if (status & 0x00000025) {
- if (status & 0x00000004) {
- sc->TxSuspended = 1;
- }
- sc->txInterrupts++;
- rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
- }
-}
-
-#if defined(__i386)
-static void nopOn(const rtems_irq_connect_data* notUsed) {
- /*
- * code should be moved from dec21140Enet_initialize_hardware
- * to this location
- */
-}
-
-static int dec21140IsOn(const rtems_irq_connect_data* irq) {
- return BSP_irq_enabled_at_i8259s (irq->name);
-}
-#endif
-
-
-/*
- * Initialize the ethernet hardware
- */
-#define PPCBUG_HW_ADDR_STORAGE 0x1f2c
-static void dec21140Enet_initialize_hardware (struct dec21140_softc *sc) {
- rtems_status_code st;
- unsigned32 *tbase;
- int i;
- char *cp, *setup_frm, *eaddrs;
- unsigned char *buffer;
- struct MD *rmd;
-
-
- tbase = sc->base;
-
- /*
- * WARNING : First write in CSR6
- * Then Reset the chip ( 1 in CSR0)
- */
-
- write_csr(tbase, CSR6, CSR6_INIT);
- write_csr(tbase, CSR0, RESET_CHIP);
- delay_in_bus_cycles(200);
-
- /*
- * Init CSR0
- */
- write_csr(tbase, CSR0, CSR0_MODE);
-
- read_nvram(sc->arpcom.ac_enaddr, PPCBUG_HW_ADDR_STORAGE, 6);
-
-#ifdef DEC_DEBUG
- printk("DC21140 %x:%x:%x:%x:%x:%x IRQ %d IO %x M %x .........\n",
- sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
- sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
- sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
- sc->irqInfo, sc->port, sc->base);
-#endif
-
- /*
- * Init RX ring
- */
-
-#if defined(__i386)
- cp = (char *)malloc((NRXBUFS + NTXBUFS) * (sizeof(struct MD) + RBUF_SIZE) +
- PG_SIZE);
- sc->bufferBase = cp;
- cp += (PG_SIZE - (int)cp) & MASK_OFFSET ;
- if (_CPU_is_paging_enabled()) {
- _CPU_change_memory_mapping_attribute
- (NULL, cp,
- (NRXBUFS + NTXBUFS) * (sizeof(struct MD) + RBUF_SIZE),
- PTE_CACHE_DISABLE | PTE_WRITABLE);
- }
-#endif
-#if defined(__PPC)
- cp = (char *)malloc((NRXBUFS + NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) +
- 4096);
-#endif
- rmd = (struct MD *)cp;
- sc->MDbase = rmd;
- buffer = cp + ((NRXBUFS + NTXBUFS)*sizeof(struct MD));
-
- write_csr(tbase, CSR3, LOCAL_TO_PCI(sc->MDbase));
- for (i = 0 ; i < NRXBUFS; i++){
- struct mbuf *m;
-
- /* allocate an mbuf for each receive descriptor */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- rmd->m = m;
-
- set_buffer_address(rmd, mtod(m, void *));
- if (i == NRXBUFS - 1) {
- write_descr_counts(rmd, END_OF_RING | RBUF_SIZE);
- rmd->next = sc->MDbase;
- } else {
- write_descr_counts(rmd, CHAINED_ADDRESS | RBUF_SIZE);
- set_chain_address(rmd, rmd + 1);
- rmd->next = rmd + 1;
- }
- write_descr_status(rmd, OWNED_BY_DEC21140);
- rmd++;
- }
-
- /*
- * Init TX ring
- */
- write_csr(tbase, CSR4, LOCAL_TO_PCI(rmd));
- for (i = 0 ; i < NTXBUFS; i++){
- set_buffer_address(rmd + i, buffer + NRXBUFS * RBUF_SIZE + i * RBUF_SIZE);
- write_descr_counts(rmd + i, FIRST_SEGMENT | LAST_SEGMENT | CHAINED_ADDRESS);
- if (i == NTXBUFS - 1) {
- set_chain_address(rmd + i, rmd);
- (rmd + i)->next = rmd;
- } else {
- set_chain_address(rmd + i, rmd + i + 1);
- (rmd + i)->next = rmd + i + 1;
- }
- write_descr_status(rmd + i, OWNED_BY_HOST);
- }
-
-#if defined(__i386)
- sc->irqInfo.hdl = (rtems_irq_hdl)dec21140Enet_interrupt_handler;
- sc->irqInfo.on = nopOn;
- sc->irqInfo.off = nopOn;
- sc->irqInfo.isOn = dec21140IsOn;
- st = BSP_install_rtems_irq_handler (&sc->irqInfo);
- if (!st) {
- rtems_panic ("Can't attach DEC21140 interrupt handler for irq %d\n",
- sc->irqInfo.name);
- }
-#endif
-#if defined(__PPC)
- {
- rtems_isr_entry old_handler;
-
- st = bsp_interrupt_catch(dec21140Enet_interrupt_handler,
- IRQ_ETHERNET, &old_handler);
- if (st != RTEMS_SUCCESSFUL) {
- rtems_panic("Can't attach DEC21140 interrupt handler\n");
- }
- bsp_interrupt_enable(IRQ_ETHERNET, PRIORITY_ISA_INT);
- }
-#endif
-
- /* no interrupts for now */
- write_csr(tbase, CSR7, NO_IT);
-
- /*
- * Build setup frame
- */
- setup_frm = get_buffer_address(rmd);
- eaddrs = (char *)(sc->arpcom.ac_enaddr);
- /* Fill the buffer with our physical address. */
- for (i = 1; i < 16; i++) {
- *setup_frm++ = eaddrs[0];
- *setup_frm++ = eaddrs[1];
- setup_frm += 2;
- *setup_frm++ = eaddrs[2];
- *setup_frm++ = eaddrs[3];
- setup_frm += 2;
- *setup_frm++ = eaddrs[4];
- *setup_frm++ = eaddrs[5];
- setup_frm += 2;
- }
- /* Add the broadcast address when doing perfect filtering */
- memset((char*)setup_frm, 0xff, 12);
- write_descr_counts(rmd, SETUP_PACKET | CHAINED_ADDRESS | 192);
- write_descr_status(rmd, OWNED_BY_DEC21140);
- /*
- * Start TX for setup frame
- */
- write_csr(tbase, CSR6, CSR6_INIT | CSR6_TX);
-
- write_csr(tbase, CSR1, 1);
- while (read_descr_status(rmd) & OWNED_BY_DEC21140);
- sc->SentTxMD = sc->TxMD = rmd + 1;
- sc->PendingTxCount = 0;
- sc->TxSuspended = 1;
- /*
- * Set up interrupts
- */
- write_csr(tbase, CSR5, IT_SETUP);
- write_csr(tbase, CSR7, IT_SETUP);
-
- /*
- * Enable RX and TX
- */
- write_csr(tbase, CSR6, CSR6_INIT | CSR6_TXRX);
-
-}
-
-static void dec21140_rxDaemon (void *arg) {
- unsigned32 *tbase;
- struct dec21140_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct MD *rmd;
- unsigned32 len;
- unsigned32 rx_status;
- rtems_event_set events;
-
- tbase = sc->base;
- rmd = sc->MDbase;
-
- for (;;){
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- while (((rx_status = read_descr_status(rmd)) & OWNED_BY_DEC21140) == 0) {
- struct ether_header *eh;
- struct mbuf *m = rmd->m;
-
- /*
- * packet is good if Error Summary = 0 and First Descriptor = 1
- * and Last Descriptor = 1
- */
- if ((rx_status & 0x00008300) == 0x00000300) {
- /* pass on the packet in the mbuf */
- len = (rx_status >> 16) & 0x7ff;
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input (ifp, eh, m);
-
- /* get a new mbuf for the 21140 */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- rmd->m = m;
- set_buffer_address(rmd, mtod(m, void *));
- } else {
- if ((rx_status & (1 << 9)) == 0) {
- sc->rxNotFirst++;
- }
- if ((rx_status & (1 << 8)) == 0) {
- sc->rxNotLast++;
- }
- if (rx_status & (1 << 7)) {
- sc->rxGiant++;
- }
- if (rx_status & (1 << 2)) {
- sc->rxNonOctet++;
- }
- if (rx_status & (1 << 11)) {
- sc->rxRunt++;
- }
- if (rx_status & (1 << 1)) {
- sc->rxBadCRC++;
- }
- if (rx_status & (1 << 14)) {
- sc->rxOverrun++;
- }
- if (rx_status & (1 << 6)) {
- sc->rxCollision++;
- }
- }
-
- /* give the descriptor back to the 21140 */
- write_descr_status(rmd, OWNED_BY_DEC21140);
-
- /* check for more ready descriptors */
- rmd = rmd->next;
- }
- }
-}
-
-static void reap_sent_descriptors(struct dec21140_softc *sc) {
- struct MD *descr = sc->SentTxMD;
- unsigned32 *tbase = sc->base;
- unsigned32 tx_status = 0;
- struct mbuf *m, *n;
-
- while (sc->PendingTxCount > 0 &&
- ((tx_status = read_descr_status(descr)) & OWNED_BY_DEC21140) == 0 ) {
- for (m = descr->m; m; m = n) {
- MFREE(m, n);
- }
- if (read_descr_counts(descr) & LAST_SEGMENT) {
- if (tx_status & (1 << 0)) {
- sc->txDeferred++;
- }
- if (tx_status & (1 << 7)) {
- sc->txHeartbeat++;
- }
- if (tx_status & (1 << 9)) {
- sc->txLateCollision++;
- }
- if (tx_status & (1 << 8)) {
- sc->txRetryLimit++;
- }
- if (tx_status & (1 << 1)) {
- sc->txUnderrun++;
- write_csr(tbase, CSR1, 0x1); /* restart transmitter */
- /* this shouldn't happen - descriptor should still be
- owned by 21140 */
- printk("ethernet chip underrun error\n");
- }
- if (tx_status & (1 << 10)) {
- sc->txLostCarrier++;
- }
- }
- descr = descr->next;
- sc->PendingTxCount--;
- }
- sc->SentTxMD = descr;
- /* check for Underflow and restart transmission */
- if ((tx_status & 0x80000002) == 0x80000002) {
- sc->txUnderrun++;
- write_csr(tbase, CSR1, 0x1); /* restart transmitter */
- printk("ethernet chip underrun error\n");
- }
-}
-
-static void sendpacket (volatile struct ifnet *ifp, struct mbuf *m) {
- struct mbuf *mbuf = m;
- struct dec21140_softc *sc = ifp->if_softc;
- struct MD *descr, *first, *last;
- unsigned32 *tbase = sc->base;
- int count = 0;
-
- first = last = descr = sc->TxMD;
- reap_sent_descriptors(sc);
- while (mbuf) {
- if (mbuf->m_len) {
- /* if no descriptor is available, wait for interrupt */
- while ((sc->PendingTxCount + count) == NTXBUFS) {
- rtems_event_set events;
- rtems_status_code result;
-
- if (sc->PendingTxCount == 0) {
- printk("ERROR: too many segments to transmit in mbuf\n");
- }
- result = rtems_bsdnet_event_receive(INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- 20 * ticks_per_second,
- &events);
- if (result == RTEMS_TIMEOUT) {
- printk("still waiting for tx descriptor in sendpacket\n");
- }
- reap_sent_descriptors(sc);
- if (sc->TxSuspended) {
- sc->TxSuspended = 0;
- write_csr(tbase, CSR1, 0x1);
- }
- }
- set_buffer_address(descr, mtod (mbuf, void *));
- write_descr_counts(descr, CHAINED_ADDRESS | mbuf->m_len);
- last = descr;
- if (descr != first) {
- write_descr_status(descr, OWNED_BY_DEC21140);
- }
- descr->m = 0;
- count++;
- descr = descr->next;
- }
- mbuf = mbuf->m_next;
- }
- write_descr_counts(first, read_descr_counts(first) | FIRST_SEGMENT);
- write_descr_counts(last, read_descr_counts(last) | LAST_SEGMENT);
- last->m = m;
- sc->TxMD = descr;
- synchronize_io();
- write_descr_status(first, OWNED_BY_DEC21140);
- sc->PendingTxCount += count;
- if (sc->TxSuspended) {
- sc->TxSuspended = 0;
- synchronize_io();
- write_csr(tbase, CSR1, 0x1);
- }
-}
-
-/*
- * Driver transmit daemon
- */
-static void dec21140_txDaemon (void *arg) {
- struct dec21140_softc *sc = (struct dec21140_softc *)arg;
- volatile struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned32 *tbase = sc->base;
- 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;
- }
-}
-
-
-static void dec21140_start (struct ifnet *ifp) {
- struct dec21140_softc *sc = ifp->if_softc;
-
- ifp->if_flags |= IFF_OACTIVE;
- rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
-}
-
-/*
- * Initialize and start the device
- */
-static void dec21140_init (void *arg) {
- struct dec21140_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
-
- /*
- * Set up DEC21140 hardware
- */
- dec21140Enet_initialize_hardware (sc);
-
- /*
- * Start driver tasks
- */
-#if NDECDRIVER == 1
- sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
- dec21140_rxDaemon, sc);
- sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
- dec21140_txDaemon, sc);
-#else
-# error "need to fix task IDs"
-#endif
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
-}
-
-/*
- * Stop the device
- */
-static void dec21140_stop (struct dec21140_softc *sc) {
- unsigned32 *tbase;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Stop the transmitter
- */
- tbase = sc->base;
- write_csr(tbase, CSR7, NO_IT);
- write_csr(tbase, CSR6, CSR6_INIT);
- free(sc->bufferBase);
-}
-
-
-/*
- * Show interface statistics
- */
-static void dec21140_stats (struct dec21140_softc *sc) {
- printf (" Rx Interrupts:%-8u", sc->rxInterrupts);
- printf (" Not First:%-8u", sc->rxNotFirst);
- printf (" Not Last:%-8u\n", sc->rxNotLast);
- printf (" Giant:%-8u", sc->rxGiant);
- printf (" Runt:%-8u", sc->rxRunt);
- printf (" Non-octet:%-8u\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8u", sc->rxBadCRC);
- printf (" Overrun:%-8u", sc->rxOverrun);
- printf (" Collision:%-8u\n", sc->rxCollision);
-
- printf (" Tx Interrupts:%-8u", sc->txInterrupts);
- printf (" Deferred:%-8u", sc->txDeferred);
- printf (" Missed Hearbeat:%-8u\n", sc->txHeartbeat);
- printf (" No Carrier:%-8u", sc->txLostCarrier);
- printf ("Retransmit Limit:%-8u", sc->txRetryLimit);
- printf (" Late Collision:%-8u\n", sc->txLateCollision);
- printf (" Underrun:%-8u", sc->txUnderrun);
- printf (" Raw output wait:%-8u\n", sc->txRawWait);
-}
-
-/*
- * Driver ioctl handler
- */
-static int dec21140_ioctl (struct ifnet *ifp, int command, caddr_t data) {
- struct dec21140_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:
- dec21140_stop (sc);
- break;
-
- case IFF_UP:
- dec21140_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- dec21140_stop (sc);
- dec21140_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- dec21140_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-/*
- * Attach an DEC21140 driver to the system
- */
-int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config) {
- struct dec21140_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int i;
-#if defined(__i386)
- int signature;
- int value;
- char interrupt;
- int diag;
-
- /*
- * Initialise PCI module
- */
- if (pcib_init() == PCIB_ERR_NOTPRESENT) {
- rtems_panic("PCI BIOS not found !!");
- }
-
- /*
- * First, find a DEC board
- */
- if ((diag = pcib_find_by_devid(PCI_VENDOR_ID_DEC,
- PCI_DEVICE_ID_DEC_TULIP_FAST,
- 0,
- &signature)) != PCIB_ERR_SUCCESS) {
- rtems_panic("DEC PCI board not found !! (%d)\n", diag);
- } else {
- printk("DEC PCI Device found\n");
- }
-#endif
-#if defined(__PPC)
- int sig;
-
- /* search PCI bus for Tulip chip */
- sig = pci_find_by_devid(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, 0);
- if (sig == PCI_NOT_FOUND) {
- printk("PCI scan failed: DEC 21140 not found\n");
- return 0;
- }
-
-#endif
-
- /*
- * Find a free driver
- */
- for (i = 0 ; i < NDECDRIVER ; i++) {
- sc = &dec21140_softc[i];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc == NULL) {
- break;
- }
- }
- if (i >= NDECDRIVER) {
- printk ("Too many DEC drivers.\n");
- return 0;
- }
-
- /*
- * Process options
- */
-
- sc->port = pci_conf_read32(sig, PCI_BASE_ADDRESS_0) & ~IO_MASK;
- sc->base = (void *)
- PCI_TO_LOCAL(pci_conf_read32(sig, PCI_BASE_ADDRESS_1) & ~MEM_MASK);
- sc->irqInfo = pci_conf_read8(sig, 60);
-#if defined(__i386)
- pcib_conf_read32(signature, 16, &value);
- sc->port = value & ~IO_MASK;
-
- pcib_conf_read32(signature, 20, &value);
- if (_CPU_is_paging_enabled()) {
- _CPU_map_phys_address(&(sc->base),
- (void *)(value & ~MEM_MASK),
- DEC_REGISTER_SIZE ,
- PTE_CACHE_DISABLE | PTE_WRITABLE);
- } else {
- sc->base = (unsigned32 *)(value & ~MEM_MASK);
- }
-
- pcib_conf_read8(signature, 60, &interrupt);
- sc->irqInfo.name = (rtems_irq_symbolic_name)interrupt;
-#endif
-
- 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;
- }
-
- sc->acceptBroadcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = i + 1;
- ifp->if_name = "dc";
- ifp->if_mtu = mtu;
- ifp->if_init = dec21140_init;
- ifp->if_ioctl = dec21140_ioctl;
- ifp->if_start = dec21140_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);
-
- /*
- * Determine clock rate for timeout calculation
- */
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
-
- return 1;
-};
-