diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mvme2307/network/network.c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/mvme2307/network/network.c | 946 |
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; -}; - |