From 0c04c377bc8ac177d28bd0e0096d7c6940d33cd4 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 18 Feb 1999 16:48:14 +0000 Subject: ./clock/Makefile.in,v ./clock/clock.c,v ./console/Makefile.in,v ./console/config.c,v ./console/console.c,v ./console/console.h,v ./console/debugio.c,v ./console/i8042.c,v ./console/i8042_p.h,v ./console/i8042vga.c,v ./console/i8042vga.h,v ./console/ns16550.c,v ./console/ns16550.h,v ./console/ns16550_p.h,v ./console/ns16550cfg.c,v ./console/ns16550cfg.h,v ./console/vga.c,v ./console/vga_p.h,v ./console/z85c30.c,v ./console/z85c30.h,v ./console/z85c30_p.h,v ./console/z85c30cfg.c,v ./console/z85c30cfg.h,v ./include/Makefile.in,v ./include/bsp.h,v ./include/chain.h,v ./include/coverhd.h,v ./include/extisrdrv.h,v ./include/nvram.h,v ./include/pci.h,v ./include/tod.h,v ./network/Makefile.in,v ./network/amd79c970.c,v ./network/amd79c970.h,v ./nvram/Makefile.in,v ./nvram/ds1385.h,v ./nvram/mk48t18.h,v ./nvram/nvram.c,v ./nvram/prepnvr.h,v ./nvram/stk11c68.h,v ./pci/Makefile.in,v ./pci/pci.c,v ./start/Makefile.in,v ./start/start.s,v ./startup/Makefile.in,v ./startup/bspclean.c,v ./startup/bspstart.c,v ./startup/bsptrap.s,v ./startup/device-tree,v ./startup/genpvec.c,v ./startup/linkcmds,v ./startup/rtems-ctor.cc,v ./startup/sbrk.c,v ./startup/setvec.c,v ./startup/spurious.c,v ./startup/swap.c,v ./timer/Makefile.in,v ./timer/timer.c,v ./tod/Makefile.in,v ./tod/cmos.h,v ./tod/tod.c,v ./universe/Makefile.in,v ./universe/universe.c,v ./vectors/Makefile.in,v ./vectors/README,v ./vectors/align_h.s,v ./vectors/vectors.s,v ./wrapup/Makefile.in,v ./Makefile.in,v ./README,v ./STATUS,v ./bsp_specs,v --- .../libbsp/powerpc/ppcn_60x/network/Makefile.in | 54 ++ .../libbsp/powerpc/ppcn_60x/network/amd79c970.c | 1010 ++++++++++++++++++++ .../libbsp/powerpc/ppcn_60x/network/amd79c970.h | 426 +++++++++ 3 files changed, 1490 insertions(+) create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c create mode 100644 c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h (limited to 'c/src/lib/libbsp/powerpc/ppcn_60x/network') diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in new file mode 100644 index 0000000000..cef35eb353 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/network/Makefile.in @@ -0,0 +1,54 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/network.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=amd79c970 +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c new file mode 100644 index 0000000000..ba3849df9a --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.c @@ -0,0 +1,1010 @@ +/* + * COPYRIGHT (c) 1998 by Radstone Technology + * + * + * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK + * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU. + * + * You are hereby granted permission to use, copy, modify, and distribute + * this file, provided that this notice, plus the above copyright notice + * and disclaimer, appears in all copies. Radstone Technology will provide + * no support for this code. + * + */ +/* + * RTEMS/KA9Q driver for PC-NET + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "amd79c970.h" + +/* + * Number of PC-NETs supported by this driver + */ +#define NPCNETDRIVER 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. + * + * Set the number of Tx and Rx buffers, using Log_2(# buffers). + */ +#define LANCE_LOG2_TX_BUFFERS 4 +#define LANCE_LOG2_RX_BUFFERS 4 +#define TX_RING_SIZE (1 << (LANCE_LOG2_TX_BUFFERS)) +#define TX_RING_MOD_MASK (TX_RING_SIZE - 1) +#define TX_RING_LEN_BITS ((LANCE_LOG2_TX_BUFFERS) << 4) +#define RX_RING_SIZE (1 << (LANCE_LOG2_RX_BUFFERS)) +#define RX_RING_MOD_MASK (RX_RING_SIZE - 1) +#define RX_RING_LEN_BITS ((LANCE_LOG2_RX_BUFFERS) << 4) + +/* + * RTEMS event used by interrupt handler to signal daemons. + * This must *not* be the same event used by the KA9Q task synchronization. + */ +#define INTERRUPT_EVENT RTEMS_EVENT_1 + +/* + * Receive buffer size -- Allow for a full ethernet packet plus a pointer + */ +#define ETHPKT_SIZE 1520 +#define RBUF_SIZE (ETHPKT_SIZE + sizeof (struct iface *)) + +/* + * LANCE Register Access Macros + */ +#define PCNET_IO_RD32(dp, reg, value) \ + inport_32(&dp->pPCNet->u.dwio.##reg, value) +#define PCNET_IO_WR32(dp, reg, value) \ + outport_32(&dp->pPCNet->u.dwio.##reg, value) + +/* + * LANCE Register Access Macros + */ +#define RD_CSR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_RD32(dp, rdp, value) + +#define WR_CSR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_WR32(dp, rdp, value) + +#define RD_BCR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_RD32(dp, bdp, value) + +#define WR_BCR32(dp, index, value) \ + PCNET_IO_WR32(dp, rap, index); \ + PCNET_IO_WR32(dp, bdp, value) + +/* + * Hardware-specific storage + * + * Note that the enetInitBlk field must be aligned to a 16 byte + * boundary + */ +typedef struct amd79c970Context { + rmde_t rxBdBase[RX_RING_SIZE]; + tmde_t txBdBase[TX_RING_SIZE]; + initblk_t initBlk; + pc_net_t *pPCNet; + unsigned32 ulIntVector; + struct mbuf **rxMbuf; + struct mbuf **txMbuf; + int rxBdCount; + int txBdCount; + int txBdHead; + int txBdTail; + int txBdActiveCount; + struct iface *iface; + rtems_id txWaitTid; + + /* + * Statistics + */ + unsigned long rxInterrupts; + unsigned long rxNotFirst; + unsigned long rxNotLast; + unsigned long rxGiant; + unsigned long rxNonOctet; + unsigned long rxRunt; + unsigned long rxBadCRC; + unsigned long rxOverrun; + unsigned long rxCollision; + unsigned long rxDiscarded; + + unsigned long txInterrupts; + unsigned long txDeferred; + unsigned long txHeartbeat; + unsigned long txLateCollision; + unsigned long txRetryLimit; + unsigned long txUnderrun; + unsigned long txLostCarrier; + unsigned long txRawWait; +} amd79c970Context_t; +static amd79c970Context_t *pAmd79c970Context[NPCNETDRIVER]; + +/* + * PC-NET interrupt handler + */ +static rtems_isr +amd79c970_isr (rtems_vector_number v) +{ + unsigned32 ulCSR0, ulCSR4, ulCSR5; + amd79c970Context_t *dp; + int i; + + for(i=0; iulIntVector==v) + { + RD_CSR32(dp, CSR0, ulCSR0); + if(ulCSR0 & CSR0_RINT) + { + /* + * We have recieve data + */ + dp->rxInterrupts++; + rtems_event_send( + dp->iface->rxproc, + INTERRUPT_EVENT); + } + + if(ulCSR0 & CSR0_TINT) + { + /* + * Data tranmitted or error + */ + dp->txInterrupts++; + if(dp->txWaitTid) + { + rtems_event_send( + dp->txWaitTid, + INTERRUPT_EVENT); + } + } + + if((ulCSR0 & CSR0_INTR) && + !(ulCSR0 & (CSR0_RINT | CSR0_TINT))) + { + /* + * Many possible sources + */ + RD_CSR32(dp, CSR4, ulCSR4); + RD_CSR32(dp, CSR5, ulCSR5); + DEBUG_puts("CSR0="); + DEBUG_puth(ulCSR0); + DEBUG_puts(", CSR4="); + DEBUG_puth(ulCSR4); + DEBUG_puts(", CSR5="); + DEBUG_puth(ulCSR5); + DEBUG_puts("\n\r"); + /* + * Clear it + */ + WR_CSR32(dp, CSR4, ulCSR4); + WR_CSR32(dp, CSR5, ulCSR5); + } + + /* + * Clear interrupts + */ + ulCSR0&=CSR0_BABL | CSR0_CERR | CSR0_MISS | + CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IENA; + WR_CSR32(dp, CSR0, ulCSR0); + + RD_CSR32(dp, CSR0, ulCSR0); + } + } +} + +/* + * Initialize the ethernet hardware + */ +static boolean +amd79c970_initialize_hardware (int instance, int broadcastFlag) +{ + amd79c970Context_t *dp; + struct mbuf *bp; + int i; + unsigned8 ucPCIBusCount; + unsigned8 ucBusNumber; + unsigned8 ucSlotNumber; + unsigned32 ulDeviceID; + unsigned32 ulBAR0; + unsigned8 ucIntVector; + unsigned32 ulInitClkPCIAddr; + unsigned32 ulAPROM; + unsigned32 ulCSR0; + + ucPCIBusCount=BusCountPCI(); + + /* + * Scan the available busses for instance of hardware + */ + i=0; + + dp=pAmd79c970Context[instance]; + dp->pPCNet=(pc_net_t *)NULL; + + for(ucBusNumber=0; + (ucBusNumberpPCNet==(pc_net_t *)NULL); + ucBusNumber++) + { + for(ucSlotNumber=0;ucSlotNumberpPCNet=(pc_net_t *)(ulBAR0&~PCI_ADDRESS_IO_SPACE); + + /* + * Read interrupt vector + */ + PCIConfigRead8(ucBusNumber, + ucSlotNumber, + 0, + PCI_CONFIG_INTERRUPTLINE, + &ucIntVector); + dp->ulIntVector=PPCN_60X_IRQ_PCI(ucIntVector); + + /* + * Ensure that device is enabled + */ + PCIConfigWrite16(ucBusNumber, + ucSlotNumber, + 0, + PCI_CONFIG_COMMAND, + PCI_ENABLE_IO_SPACE | + PCI_ENABLE_BUS_MASTER); + break; + } + } + + if(dp->pPCNet==(pc_net_t *)NULL) + { + return(FALSE); + } + + /* + * Read the ethernet number + */ + if(!dp->iface->hwaddr) + { + dp->iface->hwaddr=mallocw (EADDR_LEN); + PCNET_IO_RD32(dp, aprom[0], ulAPROM); + for(i=0;i<4;i++) + { + dp->iface->hwaddr[i]=(ulAPROM>>(i*8))&0xff; + } + PCNET_IO_RD32(dp, aprom[1], ulAPROM); + for(i=0;i<2;i++) + { + dp->iface->hwaddr[i+4]=(ulAPROM>>(i*8))&0xff; + } + } + + /* + * Allocate mbuf pointers + */ + dp->rxMbuf=mallocw (dp->rxBdCount * sizeof(*dp->rxMbuf)); + dp->txMbuf=mallocw (dp->txBdCount * sizeof(*dp->txMbuf)); + + /* + * Allocate space for incoming packets + */ + for(i=0; irxBdCount; i++) + { + dp->rxMbuf[i]=bp=ambufw (RBUF_SIZE); + bp->data += sizeof (struct iface *); + dp->rxBdBase[i].rmde_addr= + Swap32((unsigned32)bp->data+PCI_SYS_MEM_BASE); + dp->rxBdBase[i].rmde_bcnt= + Swap16(-(bp->size-sizeof (struct iface *))); + dp->rxBdBase[i].rmde_flags=Swap16(RFLG_OWN); + } + + /* + * Set up transmit buffer descriptors + */ + for(i=0; itxBdCount; i++) + { + dp->txBdBase[i].tmde_status=Swap16(TST_STP | TST_ENP); + dp->txBdBase[i].tmde_error=0; + dp->txMbuf[i]=NULL; + } + + /* + * Initialise initblk + */ + if(broadcastFlag) + { + dp->initBlk.ib_mode=0; + } + else + { + dp->initBlk.ib_mode=Swap16(CSR15_DRCVBC); + } + + /* + * Set the receive descriptor ring length + */ + dp->initBlk.ib_rlen=RX_RING_LEN_BITS; + /* + * Set the receive descriptor ring address + */ + dp->initBlk.ib_rdra=Swap32((unsigned32)&dp->rxBdBase[0]+ + PCI_SYS_MEM_BASE); + + /* + * Set the transmit descriptor ring length + */ + dp->initBlk.ib_tlen=TX_RING_LEN_BITS; + /* + * Set the tranmit descriptor ring address + */ + dp->initBlk.ib_tdra=Swap32((unsigned32)&dp->txBdBase[0]+ + PCI_SYS_MEM_BASE); + + for(i=0;i<6;i++) + { + dp->initBlk.ib_padr[i]=dp->iface->hwaddr[i]; + } + + /* + * Ensure that we are in DWIO mode + */ + PCNET_IO_WR32(dp, rdp, 0); + + WR_CSR32(dp, 58,CSR58_PCISTYLE); + + WR_CSR32(dp, CSR3, + CSR3_BABLM | CSR3_MERRM | CSR3_IDONM | CSR3_DXSUFLO); + + WR_CSR32(dp, CSR4, + CSR4_APADXMIT | CSR4_MFCOM | CSR4_RCVCCOM | + CSR4_TXSTRTM | CSR4_JABM); + + WR_CSR32(dp, CSR5, 0); + + ulInitClkPCIAddr=(unsigned32)&dp->initBlk+PCI_SYS_MEM_BASE; + /* + * CSR2 must contain the high order 16 bits of the first word in + * the initialization block + */ + WR_CSR32(dp, CSR2, (ulInitClkPCIAddr >> 16) & 0xffff); + /* + * CSR1 must contain the low order 16 bits of the first word in + * the initialization block + */ + WR_CSR32(dp, CSR1, (ulInitClkPCIAddr & 0xffff)); + + /* + * Set up interrupts + */ + set_vector(amd79c970_isr, + dp->ulIntVector, + instance); + + /* + * Start the device + */ + WR_CSR32(dp, CSR0, CSR0_INIT | CSR0_STRT); + + /* + * Wait for 100mS for the device to initialise + */ + for(i=0; i<100; i++) + { + RD_CSR32(dp, CSR0, ulCSR0); + if(ulCSR0 & CSR0_IDON) + { + break; + } + rtems_ka9q_ppause(1); /* 1mS */ + } + if(i >= 100) + { + return(FALSE); + } + + /* + * Enable interrupts + */ + WR_CSR32(dp, CSR0, CSR0_IENA); + + dp->txBdHead=dp->txBdTail=0; + dp->txBdActiveCount=0; + + return(TRUE); +} + +/* + * Soak up buffer descriptors that have been sent + */ +static void +amd79c970_retire_tx_bd (amd79c970Context_t *dp) +{ + unsigned16 status; + unsigned32 error; + int i; + int nRetired; + + i = dp->txBdTail; + nRetired = 0; + while((dp->txBdActiveCount != 0) && + (((status=Swap16(dp->txBdBase[i].tmde_status)) & TST_OWN)==0)) + { + /* + * See if anything went wrong + */ + if(status & TST_ERR) + { + /* + * Check for errors + */ + error=Swap16(dp->txBdBase[i].tmde_error); + + if (error & TERR_LCOL) + dp->txLateCollision++; + if (error & TERR_RTRY) + dp->txRetryLimit++; + if (error & TERR_UFLO) + dp->txUnderrun++; + if (error & TERR_EXDEF) + dp->txDeferred++; + if (error & TERR_LCAR) + dp->txLostCarrier++; + } + nRetired++; + if (status & TST_ENP) + { + /* + * A full frame has been transmitted. + * Free all the associated buffer descriptors. + */ + dp->txBdActiveCount -= nRetired; + while (nRetired) { + nRetired--; + free_mbuf (&dp->txMbuf[dp->txBdTail]); + if (++dp->txBdTail == dp->txBdCount) + dp->txBdTail = 0; + } + } + if (++i == dp->txBdCount) + { + i = 0; + } + } +} + +/* + * Send raw packet (caller provides header). + * This code runs in the context of the interface transmit + * task or in the context of the network task. + */ +static int +amd79c970_raw (struct iface *iface, struct mbuf **bpp) +{ + amd79c970Context_t *dp; + struct mbuf *bp; + tmde_t *firstTxBd, *txBd; + unsigned16 status; + int nAdded; + + dp = pAmd79c970Context[iface->dev]; + + /* + * Fill in some logging data + */ + iface->rawsndcnt++; + iface->lastsent = secclock (); + dump (iface, IF_TRACE_OUT, *bpp); + + /* + * It would not do to have two tasks active in the transmit + * loop at the same time. + * The blocking is simple-minded since the odds of two tasks + * simultaneously attempting to use this code are low. The only + * way that two tasks can try to run here is: + * 1) Task A enters this code and ends up having to + * wait for a transmit buffer descriptor. + * 2) Task B gains control and tries to transmit a packet. + * The RTEMS/KA9Q scheduling semaphore ensures that there + * are no race conditions associated with manipulating the + * txWaitTid variable. + */ + if (dp->txWaitTid) { + dp->txRawWait++; + while (dp->txWaitTid) + rtems_ka9q_ppause (10); + } + + /* + * Free up buffer descriptors + */ + amd79c970_retire_tx_bd (dp); + + /* + * Set up the transmit buffer descriptors. + * No need to pad out short packets since the + * hardware takes care of that automatically. + * No need to copy the packet to a contiguous buffer + * since the hardware is capable of scatter/gather DMA. + */ + bp = *bpp; + nAdded = 0; + txBd = firstTxBd = dp->txBdBase + dp->txBdHead; + for (;;) { + /* + * Wait for buffer descriptor to become available. + */ + if ((dp->txBdActiveCount + nAdded) == dp->txBdCount) { + /* + * Find out who we are + */ + if (dp->txWaitTid == 0) + rtems_task_ident (0, 0, &dp->txWaitTid); + + /* + * Wait for buffer descriptor to become available. + * Note that the buffer descriptors are checked + * *before* * entering the wait loop -- this catches + * the possibility that a buffer descriptor became + * available between the `if' above, and the clearing + * of the event register. + * Also, the event receive doesn't wait forever. + * This is to catch the case where the transmitter + * stops in the middle of a frame -- and only the + * last buffer descriptor in a frame can generate + * an interrupt. + */ + amd79c970_retire_tx_bd (dp); + while ((dp->txBdActiveCount + nAdded) == dp->txBdCount) { + rtems_ka9q_event_receive (INTERRUPT_EVENT, + RTEMS_WAIT|RTEMS_EVENT_ANY, + 1 + 1000000/BSP_Configuration.microseconds_per_tick); + amd79c970_retire_tx_bd (dp); + } + } + + /* + * Fill in the buffer descriptor + */ + txBd->tmde_addr=Swap32((unsigned32)bp->data+PCI_SYS_MEM_BASE); + txBd->tmde_bcnt=Swap16(-bp->cnt); + dp->txMbuf[dp->txBdHead] = bp; + + nAdded++; + if (++dp->txBdHead == dp->txBdCount) + { + dp->txBdHead = 0; + } + + /* + * Set the transmit buffer status. + * Break out of the loop if this mbuf is the last in the frame. + */ + if ((bp = bp->next) == NULL) { + if(txBd==firstTxBd) + { + /* + * There is only one frame + */ + txBd->tmde_status=Swap16(TST_OWN | + TST_STP | + TST_ENP); + } + else + { + /* + * Mark the last buffer + */ + txBd->tmde_status=Swap16(TST_OWN | + TST_ENP); + /* + * Trigger the first transmit + */ + firstTxBd->tmde_status=Swap16(TST_OWN | + TST_STP); + } + /* + * Sync instruction required to overcome the Grackle + * stale data bug + */ + asm volatile("sync"); + dp->txBdActiveCount += nAdded; + break; + } + else if(txBd!=firstTxBd) + { + txBd->tmde_status = Swap16(TST_OWN); + } + txBd = dp->txBdBase + dp->txBdHead; + } + + /* + * Show that we've finished with the packet + */ + dp->txWaitTid = 0; + *bpp = NULL; + return 0; +} + +/* + * PC-NET reader task + */ +static void +amd79c970_rx (int dev, void *p1, void *p2) +{ + struct iface *iface=(struct iface *)p1; + amd79c970Context_t *dp=(amd79c970Context_t *)p2; + struct mbuf *bp; + rtems_unsigned16 status; + rmde_t *rxBd; + int rxBdIndex; + int continuousCount; + + /* + * Input packet handling loop + */ + continuousCount=0; + rxBdIndex=0; + + while(TRUE) + { + rxBd=&dp->rxBdBase[rxBdIndex]; + + /* + * Wait for packet if there's not one ready + */ + if((status=Swap16(rxBd->rmde_flags)) & RFLG_OWN) + { + /* + * Reset `continuous-packet' count + */ + continuousCount=0; + + /* + * Wait for packet + * Note that the buffer descriptor is checked + * *before* the event wait -- this catches the + * possibility that a packet arrived between the + * `if' above, and the clearing of the event register. + */ + while ((status=Swap16(rxBd->rmde_flags)) & RFLG_OWN) + { + rtems_ka9q_event_receive (INTERRUPT_EVENT, + RTEMS_WAIT|RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT); + } + } + + /* + * Check that packet is valid + */ + if((status & RFLG_ERR) || + ((status & (RFLG_STP|RFLG_ENP)) != (RFLG_STP|RFLG_ENP))) + { + /* + * Something went wrong with the reception + */ + if(!(status & RFLG_ENP)) + dp->rxNotLast++; + if(!(status & RFLG_STP)) + dp->rxNotFirst++; + if(status & RFLG_OFLO) + dp->rxGiant++; + if(status & RFLG_FRAM) + dp->rxNonOctet++; + if(status & RFLG_CRC) + dp->rxBadCRC++; + if(status & RFLG_BUFF) + dp->rxOverrun++; + } + else + { + /* + * Pass the packet up the chain + * The mbuf count is reduced to remove + * the frame check sequence at the end + * of the packet. + */ + bp=dp->rxMbuf[rxBdIndex]; + bp->cnt=Swap16(rxBd->rmde_mcnt) - sizeof (uint32); + net_route (iface, &bp); + + /* + * Give the network code a chance to digest the + * packet. This guards against a flurry of + * incoming packets (usually an ARP storm) from + * using up all the available memory. + */ + if(++continuousCount >= dp->rxBdCount) + kwait_null (); + + /* + * Allocate a new mbuf + * FIXME: It seems to me that it would be better + * if there were some way to limit number of mbufs + * in use by this interface, but I don't see any + * way of determining when the mbuf we pass up + * is freed. + */ + dp->rxMbuf[rxBdIndex]=bp=ambufw (RBUF_SIZE); + bp->data += sizeof (struct iface *); + rxBd->rmde_addr=Swap32( + (unsigned32)bp->data+PCI_SYS_MEM_BASE); + rxBd->rmde_bcnt=Swap16( + -(bp->size-sizeof (struct iface *))); + } + + /* + * Reenable the buffer descriptor + */ + rxBd->rmde_flags=Swap16(RFLG_OWN); + + /* + * Move to next buffer descriptor + */ + if(++rxBdIndex==dp->rxBdCount) + rxBdIndex=0; + } +} + +/* + * Shut down the interface + * FIXME: This is a pretty simple-minded routine. It doesn't worry + * about cleaning up mbufs, shutting down daemons, etc. + */ +static int +amd79c970_stop (struct iface *iface) +{ + amd79c970Context_t *dp; + unsigned32 ulCSR0; + int i; + + dp=pAmd79c970Context[iface->dev]; + + /* + * Stop the device + */ + WR_CSR32(dp, CSR0, CSR0_STOP); + + /* + * Wait for 100mS for the device to stop + */ + for(i=0; i<100; i++) + { + RD_CSR32(dp, CSR0, ulCSR0); + if(!(ulCSR0 & (CSR0_RXON | CSR0_TXON))) + { + break; + } + rtems_ka9q_ppause(1); /* 1mS */ + } + if(i >= 100) + { + return(-1); + } + + /* + * Free up all the mbufs we've allocated + */ + for(i=0; irxBdCount; i++) + { + free_mbuf(&dp->rxMbuf[i]); + } + + return 0; +} + +/* + * Show interface statistics + */ +static void +amd79c970_show (struct iface *iface) +{ + int i; + + i=iface->dev; + + printf (" Rx Interrupts:%-8lu", pAmd79c970Context[i]->rxInterrupts); + printf (" Not First:%-8lu", pAmd79c970Context[i]->rxNotFirst); + printf (" Not Last:%-8lu\n", pAmd79c970Context[i]->rxNotLast); + printf (" Giant:%-8lu", pAmd79c970Context[i]->rxGiant); + printf (" Runt:%-8lu", pAmd79c970Context[i]->rxRunt); + printf (" Non-octet:%-8lu\n", pAmd79c970Context[i]->rxNonOctet); + printf (" Bad CRC:%-8lu", pAmd79c970Context[i]->rxBadCRC); + printf (" Overrun:%-8lu", pAmd79c970Context[i]->rxOverrun); + printf (" Collision:%-8lu\n", pAmd79c970Context[i]->rxCollision); + printf (" Discarded:%-8lu\n", pAmd79c970Context[i]->rxDiscarded); + + printf (" Tx Interrupts:%-8lu", pAmd79c970Context[i]->txInterrupts); + printf (" Deferred:%-8lu", pAmd79c970Context[i]->txDeferred); + printf (" Missed Hearbeat:%-8lu\n", pAmd79c970Context[i]->txHeartbeat); + printf (" No Carrier:%-8lu", pAmd79c970Context[i]->txLostCarrier); + printf ("Retransmit Limit:%-8lu", pAmd79c970Context[i]->txRetryLimit); + printf (" Late Collision:%-8lu\n", pAmd79c970Context[i]->txLateCollision); + printf (" Underrun:%-8lu", pAmd79c970Context[i]->txUnderrun); + printf (" Raw output wait:%-8lu\n", pAmd79c970Context[i]->txRawWait); +} + +/* + * Attach an PC-NET driver to the system + * This is the only `extern' function in the driver. + * + * argv[0]: interface label, e.g., "amd79c970" + * argv[1]: maximum transmission unit, bytes, e.g., "1500" + * argv[2]: accept ("broadcast") or ignore ("nobroadcast") broadcast packets + * Following arguments are optional, but if present, must appear in + * the following order: + * Following arguments are optional, but if Ethernet address is + * specified, Internet address must also be specified. + * ###.###.###.### -- IP address + * ##:##:##:##:##:## -- Ethernet address + */ +int +rtems_ka9q_driver_attach (int argc, char *argv[], void *p) +{ + struct iface *iface; + struct amd79c970Context *dp; + char *cp; + int i; + int argIndex; + int broadcastFlag; + + /* + * Find a free driver + */ + for(i=0; iname=strdup (argv[0]); + iface->mtu=atoi (argv[1]); + + /* + * Select broadcast packet handling + */ + cp=argv[2]; + if(strnicmp (cp, "broadcast", strlen (cp))==0) + { + broadcastFlag=1; + } + else if(strnicmp (cp, "nobroadcast", strlen (cp))==0) + { + broadcastFlag=0; + } + else { + printf ("Argument `%s' is neither `broadcast' nor `nobroadcast'.\n", cp); + return -1; + } + argIndex=3; + + /* + * Set receive buffer descriptor count + */ + dp->rxBdCount=RX_RING_SIZE; + + /* + * Set transmit buffer descriptor count + */ + dp->txWaitTid=0; + dp->txBdCount=TX_RING_SIZE; + + /* + * Set Internet address + */ + if(argIndexaddr=resolve (argv[argIndex++]); + else + iface->addr=Ip_addr; + + /* + * Set Ethernet address + */ + if(argIndexhwaddr=mallocw (EADDR_LEN); + gether (iface->hwaddr, argv[argIndex++]); + } + + iface->dev=i; + iface->raw=amd79c970_raw; + iface->stop=amd79c970_stop; + iface->show=amd79c970_show; + dp->iface=iface; + setencap (iface, "Ethernet"); + + /* + * Set up PC-NET hardware + */ + if(!amd79c970_initialize_hardware (i, broadcastFlag)) + { + printf ("Unable to initialize hardware for %s\n", argv[0]); + return -1; + } + + /* + * Chain onto list of interfaces + */ + iface->next=Ifaces; + Ifaces=iface; + + /* + * Start I/O daemons + */ + cp=if_name (iface, " tx"); + iface->txproc=newproc (cp, 1024, if_tx, iface->dev, iface, NULL, 0); + free (cp); + cp=if_name (iface, " rx"); + iface->rxproc=newproc (cp, 1024, amd79c970_rx, iface->dev, iface, dp, 0); + free (cp); + return 0; +} + +/* + * FIXME: There should be an ioctl routine to allow things like + * enabling/disabling reception of broadcast packets. + */ diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h new file mode 100644 index 0000000000..dd30d90b0d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ppcn_60x/network/amd79c970.h @@ -0,0 +1,426 @@ +/* + * COPYRIGHT (c) 1998 by Radstone Technology + * + * + * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK + * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU. + * + * You are hereby granted permission to use, copy, modify, and distribute + * this file, provided that this notice, plus the above copyright notice + * and disclaimer, appears in all copies. Radstone Technology will provide + * no support for this code. + * + */ +#ifndef _PCNET_H +#define _PCNET_H + +/* + * IO space structure for the AMD79C970 device + */ + +typedef volatile struct pc_net +{ + union + { + struct { + unsigned16 aprom[8]; /* 0x00 */ + unsigned16 rdp; /* 0x10 */ + unsigned16 rap; /* 0x14 */ + unsigned16 reset; /* 0x18 */ + unsigned16 bdp; /* 0x1C */ + } wio; + struct { + unsigned32 aprom[4]; /* 0x00 */ + unsigned32 rdp; /* 0x10 */ + unsigned32 rap; /* 0x12 */ + unsigned32 reset; /* 0x14 */ + unsigned32 bdp; /* 0x16 */ + } dwio; + } u; +} pc_net_t; + +/* + * The EEPROM is 2Kbit (128bytes) + */ +#define EEPROM_SIZE 128 +#define EEPROM_HEAD_SIZE 36 + +typedef struct pc_net_eeprom { + unsigned8 EthNumber[6]; + unsigned16 Reserved1; /* Must be 0x0000 */ + unsigned16 Reserved2; /* Must be 0x1000 */ + unsigned16 User1; + unsigned16 checksum; + unsigned16 Reserved3; /* Must be 0x5757 */ + unsigned16 bcr16; + unsigned16 bcr17; + unsigned16 bcr18; + unsigned16 bcr2; + unsigned16 bcr21; + unsigned16 Reserved4; /* Must be 0x0000 */ + unsigned16 Reserved5; /* Must be 0x0000 */ + unsigned8 Reserved6; /* Must be 0x00 */ + unsigned8 checksumAdjust; + unsigned16 Reserved7; /* Must be 0x0000 */ + unsigned16 crc; /* CCITT checksum from Serial[] onwards */ + unsigned8 Serial[16]; /* Radstone Serial Number */ +} pc_net_eeprom_t; + +/* + * PCnet-PCI Single Chip Ethernet Controller for PCI Local Bus + */ +/* + * Register and bit definitions + */ + +#define CSR0 0 +#define CSR1 1 +#define CSR2 2 +#define CSR3 3 +#define CSR4 4 +#define CSR5 5 +#define CSR6 6 +#define CSR7 7 +#define CSR8 8 +#define CSR9 9 +#define CSR15 15 +#define CSR47 47 +#define CSR82 82 /* Bus Activity Timer */ +#define CSR100 100 /* Memory Error Timeout register */ +#define CSR114 114 +#define CSR122 122 /* Receiver Packet Alignment Register */ + +#define BCR2 2 /* Misc. Configuration */ +#define BCR18 18 /* Bus size and burst control */ +#define DEFAULT_BCR18 0x2162 /* default BCR18 value - was 0x21e2*/ +#define BCR19 19 +#define BCR20 20 /* Software Style */ +#define BCR21 21 + +#define APROM0 0x00 +#define APROM1 0x04 +#define APROM2 0x08 + +/* + * CSR0: Bit definitions + */ +#define CSR0_ERR 0x8000 /* error summary */ +#define CSR0_BABL 0x4000 /* babble error */ +#define CSR0_CERR 0x2000 /* collision error */ +#define CSR0_MISS 0x1000 /* missed packet */ +#define CSR0_MERR 0x0800 /* memory error */ +#define CSR0_RINT 0x0400 /* receiver interrupt */ +#define CSR0_TINT 0x0200 /* transmitter interrupt */ +#define CSR0_IDON 0x0100 /* initialization done */ +#define CSR0_INTR 0x0080 /* interrupt flag */ +#define CSR0_IENA 0x0040 /* interrupt enable */ +#define CSR0_RXON 0x0020 /* receiver on */ +#define CSR0_TXON 0x0010 /* transmitter on */ +#define CSR0_TDMD 0x0008 /* transmit demand */ +#define CSR0_STOP 0x0004 /* stop the ilacc */ +#define CSR0_STRT 0x0002 /* start the ilacc */ +#define CSR0_INIT 0x0001 /* initialize the ilacc */ + +#define CSR3_BABLM 0x4000 /* BABL Mask */ +#define CSR3_MISSM 0x1000 /* Missed packet Mask */ +#define CSR3_MERRM 0x0800 /* Memory error Mask */ +#define CSR3_RINTM 0x0400 /* Receive Interrupt Mask */ +#define CSR3_TINTM 0x0200 /* Transmit Interrupt Mask */ +#define CSR3_IDONM 0x0100 /* Initialization Done Mask */ +#define CSR3_DXSUFLO 0x0040 /* Disable tx stop on underrun */ +#define CSR3_LAPPEN 0x0020 /* lookahead packet proc enable */ +#define CSR3_DXMT2PD 0x0010 /* disable 2 part deferral */ +#define CSR3_EMBA 0x0008 /* enable modified backoff */ +#define CSR3_BSWP 0x0004 /* byte swap */ + +#define CSR4_DMAPLUS 0x4000 /* DMA burst transfer until FIFO empty */ +#define CSR4_BACON_68K 0x0040 /* 32 bit 680x0 */ +#define CSR4_TXSTRT 0x0008 /* Transmit STaRT status */ +#define CSR4_TXSTRTM 0x0004 /* Transmit STaRT interrupt Mask */ +#define CSR4_ENTST 0x8000 /* enable test mode */ +#define CSR4_TIMER 0x2000 /* enable bus timer csr82 */ +#define CSR4_DPOLL 0x1000 /* disable tx polling */ +#define CSR4_APADXMIT 0x0800 /* auto pad tx to 64 */ +#define CSR4_ASTRPRCV 0x0400 /* auto strip rx pad and fcs */ +#define CSR4_MFCO 0x0200 /* missed frame counter oflo interrupt */ +#define CSR4_MFCOM 0x0100 /* mask to disable */ +#define CSR4_RCVCCO 0x0020 /* rx collision counter oflo interrupt */ +#define CSR4_RCVCCOM 0x0010 /* mask to disable */ +#define CSR4_JAB 0x0002 /* jabber error 10baseT interrupt */ +#define CSR4_JABM 0x0001 /* mask to disable */ + +#define CSR5_SPND 0x0001 /* Suspend */ + +#define CSR15_PROM 0x8000 /* Promiscuous */ +#define CSR15_DRCVBC 0x4000 /* Disable receiver broadcast */ +#define CSR15_DRCVPA 0x2000 /* Disable receiver phys. addr. */ +#define CSR15_DLNKTST 0x1000 /* Disable link status */ +#define CSR15_DAPC 0x0800 /* Disable auto polarity det. */ +#define CSR15_MENDECL 0x0400 /* MENDEC loopback mode */ +#define CSR15_LRT 0x0200 /* Low receiver threshold */ +#define CSR15_TSEL 0x0200 /* Transmit mode select */ +#define CSR15_INTL 0x0040 /* Internal loopback */ +#define CSR15_DRTY 0x0020 /* Disable retry */ +#define CSR15_FCOLL 0x0010 /* Force collision */ +#define CSR15_DXMTFCS 0x0008 /* Disable transmit CRC */ +#define CSR15_LOOP 0x0004 /* Loopback enable */ +#define CSR15_DTX 0x0002 /* Disable transmitter */ +#define CSR15_DRX 0x0001 /* Disable receiver */ + +#define CSR58_PCISTYLE 0x0002 /* software style */ + +#define CSR80_RCVFW16 (0<<12) /* fifo level to trigger rx dma */ +#define CSR80_RCVFW32 (1<<12) +#define CSR80_RCVFW64 (2<<12) +#define CSR80_XMTSP4 (0<<10) /* fifo level to trigger tx */ +#define CSR80_XMTSP16 (1<<10) +#define CSR80_XMTSP64 (2<<10) +#define CSR80_XMTSP112 (3<<10) +#define CSR80_XMTFW16 (0<<8) /* fifo level to stop dma */ +#define CSR80_XMTFW32 (1<<8) +#define CSR80_XMTFW64 (2<<8) +/* must also clear csr4 CSR4_DMAPLUS: */ +#define CSR80_DMATC(x) ((x)&0xff) /* max transfers per burst. deflt 16 */ +/* + * must also set csr4 CSR4_TIMER: + */ +#define CSR82_DMABAT(x) ((x)&0xffff) /* max burst time nanosecs*100 */ + +#define BCR18_MUSTSET 0x0100 /* this bit must be written as 1 !! */ +#define BCR18_BREADE 0x0040 /* linear burst enable. yes ! on pci */ +#define BCR18_BWRITE 0x0020 /* in write direction */ +#define BCR18_LINBC4 0x0001 /* linear burst count 4 8 or 16 */ +#define BCR18_LINBC8 0x0002 /* NOTE LINBC must be <= fifo trigger*/ +#define BCR18_LINBC16 0x0004 + +#define BCR19_PVALID 0x8000 /* aprom (eeprom) read checksum ok */ + +/* + * initial setting of csr0 + */ +#define CSR0_IVALUE (CSR0_IDON | CSR0_IENA | CSR0_STRT | CSR0_INIT) + +/* + * our setting of csr3 + */ +#define CSR3_VALUE (CSR3_ACON | CSR3_BSWP) + +/* + * Initialization Block. + * Chip initialization includes the reading of the init block to obtain + * the operating parameters. + * + * This essentially consists of 7, 32 bit LE words. In the following the + * fields are ordered so that they map correctly in BE mode, however each + * 16 and 32 byte field will require swapping. + */ + +typedef volatile struct initblk { + /* mode can be set in csr15 */ + unsigned16 ib_mode; /* Chip's operating parameters */ + unsigned8 ib_rlen; /* rx ring length (power of 2) */ + unsigned8 ib_tlen; /* tx ring length (power of 2) */ +/* + * The bytes must be swapped within the word, so that, for example, + * the address 8:0:20:1:25:5a is written in the order + * 0 8 1 20 5a 25 + * For PCI970 that is long word swapped: so no swapping needed, since + * the bus will swap. + */ + unsigned8 ib_padr[8]; /* physical address */ + unsigned16 ib_ladrf[4]; /* logical address filter */ + unsigned32 ib_rdra; /* rcv ring desc addr */ + unsigned32 ib_tdra; /* xmit ring desc addr */ +} initblk_t; + + +/* + * bits in mode register: allows alteration of the chips operating parameters + */ +#define IBM_PROM 0x8000 /* promiscuous mode */ +/* + * mode is also in cr15 + */ +#define MODE_DRCVBC 0x4000 /* disable receive broadcast */ +#define MODE_DRCVPA 0x2000 /* disable receive physical address */ +#define MODE_DLNKTST 0x1000 /* disable link status monitoring 10T */ +#define MODE_DAPC 0x0800 /* disable auto polarity 10T */ +#define MODE_MENDECL 0x0400 /* mendec loopback */ +#define MODE_LRT 0x0200 /* low receive threshold/tx mode sel tmau */ +#define MODE_PORTSEL10T 0x0080 /* port select 10T ?? */ +#define MODE_PORTSELAUI 0x0000 /* port select aui ?? */ +#define IBM_INTL 0x0040 /* internal loopback */ +#define IBM_DRTY 0x0020 /* disable retry */ +#define IBM_COLL 0x0010 /* force collision */ +#define IBM_DTCR 0x0008 /* disable transmit crc */ +#define IBM_LOOP 0x0004 /* loopback */ +#define IBM_DTX 0x0002 /* disable transmitter */ +#define IBM_DRX 0x0001 /* disable receiver */ + +/* + * Buffer Management is accomplished through message descriptors organized + * in ring structures in main memory. There are two rings allocated for the + * device: a receive ring and a transmit ring. The following defines the + * structure of the descriptor rings. + */ + +/* + * Receive List type definition + * + * This essentially consists of 4, 32 bit LE words. In the following the + * fields are ordered so that they map correctly in BE mode, however each + * 16 and 32 byte field will require swapping. + */ + +typedef volatile struct rmde { + unsigned32 rmde_addr; /* buf addr */ + + unsigned16 rmde_bcnt; + unsigned16 rmde_flags; + + unsigned16 rmde_mcnt; + unsigned16 rmde_misc; + + unsigned32 align; +} rmde_t; + + +/* + * bits in the flags field + */ +#define RFLG_OWN 0x8000 /* ownership bit, 1==LANCE */ +#define RFLG_ERR 0x4000 /* error summary */ +#define RFLG_FRAM 0x2000 /* framing error */ +#define RFLG_OFLO 0x1000 /* overflow error */ +#define RFLG_CRC 0x0800 /* crc error */ +#define RFLG_BUFF 0x0400 /* buffer error */ +#define RFLG_STP 0x0200 /* start of packet */ +#define RFLG_ENP 0x0100 /* end of packet */ + +/* + * bits in the buffer byte count field + */ +#define RBCNT_ONES 0xf000 /* must be ones */ +#define RBCNT_BCNT 0x0fff /* buf byte count, in 2's compl */ + +/* + * bits in the message byte count field + */ +#define RMCNT_RES 0xf000 /* reserved, read as zeros */ +#define RMCNT_BCNT 0x0fff /* message byte count */ + +/* + * Transmit List type definition + * + * This essentially consists of 4, 32 bit LE words. In the following the + * fields are ordered so that they map correctly in BE mode, however each + * 16 and 32 byte field will require swapping. + */ +typedef volatile struct tmde { + unsigned32 tmde_addr; /* buf addr */ + + unsigned16 tmde_bcnt; + unsigned16 tmde_status; /* misc error and status bits */ + + unsigned32 tmde_error; + + unsigned32 align; +} tmde_t; + +/* + * bits in the status field + */ +#define TST_OWN 0x8000 /* ownership bit, 1==LANCE */ +#define TST_ERR 0x4000 /* error summary */ +#define TST_RES 0x2000 /* reserved bit */ +#define TST_MORE 0x1000 /* more than one retry was needed */ +#define TST_ONE 0x0800 /* one retry was needed */ +#define TST_DEF 0x0400 /* defer while trying to transmit */ +#define TST_STP 0x0200 /* start of packet */ +#define TST_ENP 0x0100 /* end of packet */ + +/* + * setting of status field when packet is to be transmitted + */ +#define TST_XMIT (TST_STP | TST_ENP | TST_OWN) + +/* + * bits in the buffer byte count field + */ +#define TBCNT_ONES 0xf000 /* must be ones */ +#define TBCNT_BCNT 0x0fff /* buf byte count, in 2's compl */ + +/* + * bits in the error field + */ +#define TERR_BUFF 0x8000 /* buffer error */ +#define TERR_UFLO 0x4000 /* underflow error */ +#define TERR_EXDEF 0x2000 /* excessive deferral */ +#define TERR_LCOL 0x1000 /* late collision */ +#define TERR_LCAR 0x0800 /* loss of carrier */ +#define TERR_RTRY 0x0400 /* retry error */ +#define TERR_TDR 0x03ff /* time domain reflectometry */ + +/* + * Defines pertaining to statistics gathering (diagnostic only) + */ + +/* + * receive errors + */ +#define ERR_FRAM 0 /* framing error */ +#define ERR_OFLO 1 /* overflow error */ +#define ERR_CRC 2 /* crc error */ +#define ERR_RBUFF 3 /* receive buffer error */ + +/* + * transmit errors + */ +#define ERR_MORE 4 /* more than one retry */ +#define ERR_ONE 5 /* one retry */ +#define ERR_DEF 6 /* defer'd packet */ +#define ERR_TBUFF 7 /* transmit buffer error */ +#define ERR_UFLO 8 /* underflow error */ +#define ERR_LCOL 9 /* late collision */ +#define ERR_LCAR 10 /* loss of carrier */ +#define ERR_RTRY 11 /* retry error, >16 retries */ + +/* + * errors reported in csr0 + */ +#define ERR_BABL 12 /* transmitter timeout error */ +#define ERR_MISS 13 /* missed packet */ +#define ERR_MEM 14 /* memory error */ +#define ERR_CERR 15 /* collision errors */ +#define XMIT_INT 16 /* transmit interrupts */ +#define RCV_INT 17 /* receive interrupts */ + +#define NHARD_ERRORS 18 /* error types used in diagnostic */ + +/* + * other statistics + */ +#define ERR_TTOUT 18 /* transmit timeouts */ +#define ERR_ITOUT 19 /* init timeouts */ +#define ERR_INITS 20 /* reinitializations */ +#define ERR_RSILO 21 /* silo ptrs misaligned on recv */ +#define ERR_TSILO 22 /* silo ptrs misaligned on xmit */ +#define ERR_SINTR 23 /* spurious interrupts */ + +#define NUM_ERRORS 24 /* number of errors types */ + +/* + * Bit definitions for BCR19 + */ +#define prom_EDI (unsigned16)0x0001 +#define prom_EDO (unsigned16)0x0001 +#define prom_ESK (unsigned16)0x0002 +#define prom_ECS (unsigned16)0x0004 +#define prom_EEN (unsigned16)0x0010 +#define prom_EEDET (unsigned16)0x2000 +#define prom_PVALID (unsigned16)0x8000 +#define prom_PREAD (unsigned16)0x4000 + +#endif -- cgit v1.2.3