📄 dec21140.c
字号:
/* * RTEMS driver for TULIP based Ethernet Controller * * Copyright (C) 1999 Emmanuel Raguet. raguet@crf.canon.fr * * The license and distribution terms for this file may be * found in found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. * * $Id: dec21140.c,v 1.13.2.6 2004/11/10 22:27:55 joel Exp $ * * ------------------------------------------------------------------------ * [22.05.2000,StWi/CWA] added support for the DEC/Intel 21143 chip * * The 21143 support is (for now) only available for the __i386 target, * because that's the only testing platform I have. It should (to my best * knowledge) work in the same way for the "__PPC" target, but someone * should test this first before it's put into the code. Thanks go to * Andrew Klossner who provided the vital information about the * Intel 21143 chip. * (FWIW: I tested this driver using a Kingston KNE100TX with 21143PD chip) * * The driver will automatically detect whether there is a 21140 or 21143 * network card in the system and activate support accordingly. It will * look for the 21140 first. If the 21140 is not found the driver will * look for the 21143. * ------------------------------------------------------------------------ * * 2003-03-13, Greg Menke, gregory.menke@gsfc.nasa.gov * * Added support for up to 8 units (which is an arbitrary limit now), * consolidating their support into a single pair of rx/tx daemons and a * single ISR for all vectors servicing the DEC units. The driver now * simply uses whatever INTERRUPT_LINE the card supplies, requiring it * be configured either by the boot monitor or bspstart() hackery. * Tested on a MCP750 PPC based system with 2 DEC21140 boards. * * Also fixed a few bugs related to board configuration, start and stop. * */#include <rtems.h>/* * This driver only supports architectures with the new style * exception processing. The following checks try to keep this * from being compiled on systems which can't support this driver. */#if defined(__i386__) #define DEC21140_SUPPORTED#endif#if defined(__PPC__) && (defined(mpc604) || defined(mpc750) || defined(mpc603e)) #define DEC21140_SUPPORTED#endif#if defined(DEC21140_SUPPORTED)#include <bsp.h>#if defined(__i386__)#include <pcibios.h>#endif#if defined(__PPC__)#include <bsp/pci.h>#include <libcpu/byteorder.h>#include <libcpu/io.h>#endif#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <rtems/error.h>#include <rtems/bspIo.h>#include <rtems/rtems_bsdnet.h>#include <sys/param.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <sys/sockio.h>#include <net/if.h>#include <netinet/in.h>#include <netinet/if_ether.h> #if defined(__i386__)#include <irq.h>#endif#if defined(__PPC)#include <bsp/irq.h>#endif#ifdef malloc#undef malloc#endif#ifdef free#undef free #endif#define DEC_DEBUG/* note: the 21143 isn't really a DEC, it's an Intel chip */#define PCI_INVALID_VENDORDEVICEID 0xffffffff#define PCI_VENDOR_ID_DEC 0x1011#define PCI_DEVICE_ID_DEC_21140 0x0009#define PCI_DEVICE_ID_DEC_21143 0x0019#define DRIVER_PREFIX "dc"#define IO_MASK 0x3#define MEM_MASK 0xF/* command and status registers, 32-bit access, only if IO-ACCESS */#define ioCSR0 0x00 /* bus mode register */#define ioCSR1 0x08 /* transmit poll demand */#define ioCSR2 0x10 /* receive poll demand */#define ioCSR3 0x18 /* receive list base address */#define ioCSR4 0x20 /* transmit list base address */#define ioCSR5 0x28 /* status register */#define ioCSR6 0x30 /* operation mode register */#define ioCSR7 0x38 /* interrupt mask register */#define ioCSR8 0x40 /* missed frame counter */#define ioCSR9 0x48 /* Ethernet ROM register */#define ioCSR10 0x50 /* reserved */#define ioCSR11 0x58 /* full-duplex register */#define ioCSR12 0x60 /* SIA status register */#define ioCSR13 0x68#define ioCSR14 0x70#define ioCSR15 0x78 /* SIA general register *//* command and status registers, 32-bit access, only if MEMORY-ACCESS */#define memCSR0 0x00 /* bus mode register */#define memCSR1 0x02 /* transmit poll demand */#define memCSR2 0x04 /* receive poll demand */#define memCSR3 0x06 /* receive list base address */#define memCSR4 0x08 /* transmit list base address */#define memCSR5 0x0A /* status register */#define memCSR6 0x0C /* operation mode register */#define memCSR7 0x0E /* interrupt mask register */#define memCSR8 0x10 /* missed frame counter */#define memCSR9 0x12 /* Ethernet ROM register */#define memCSR10 0x14 /* reserved */#define memCSR11 0x16 /* full-duplex register */#define memCSR12 0x18 /* SIA status register */#define memCSR13 0x1A#define memCSR14 0x1C#define memCSR15 0x1E /* SIA general register */#define DEC_REGISTER_SIZE 0x100 /* to reserve virtual memory */#define RESET_CHIP 0x00000001#if defined(__PPC)#define CSR0_MODE 0x0030e002 /* 01b08000 */#else#define CSR0_MODE 0x0020e002 /* 01b08000 */#endif#define ROM_ADDRESS 0x00004800#define CSR6_INIT 0x022cc000 /* 022c0000 020c0000 */ #define CSR6_TX 0x00002000 #define CSR6_TXRX 0x00002002 #define IT_SETUP 0x000100c0 /* 000100e0 */#define CLEAR_IT 0xFFFFFFFF #define NO_IT 0x00000000 /* message descriptor entry */struct MD { /* used by hardware */ volatile unsigned32 status; volatile unsigned32 counts; volatile unsigned32 buf1, buf2; /* used by software */ volatile struct mbuf *m; volatile struct MD *next;} __attribute__ ((packed));/*** These buffers allocated for each unit, so ensure**** rtems_bsdnet_config.mbuf_bytecount** rtems_bsdnet_config.mbuf_cluster_bytecount**** are adequately sized to provide enough clusters and mbufs for all the** units. The default bsdnet configuration is sufficient for one dec** unit, but will be nearing exhaustion with 2 or more. Although a** little expensive in memory, the following configuration should** eliminate all mbuf/cluster issues;**** rtems_bsdnet_config.mbuf_bytecount = 128*1024;** rtems_bsdnet_config.mbuf_cluster_bytecount = 256*1024;*/#define NRXBUFS 16 /* number of receive buffers */#define NTXBUFS 16 /* number of transmit buffers *//* * Number of DEC boards supported by this driver */#define NDECDRIVER 8/* * Receive buffer size -- Allow for a full ethernet packet including CRC */#define RBUF_SIZE 1536#define ET_MINLEN 60 /* minimum message length *//*** Events, one per unit. The event is sent to the rx task from the isr** or from the stack to the tx task whenever a unit needs service. The** rx/tx tasks identify the requesting unit(s) by their particular** events so only requesting units are serviced.*/static rtems_event_set unit_signals[NDECDRIVER]= { RTEMS_EVENT_1, RTEMS_EVENT_2, RTEMS_EVENT_3, RTEMS_EVENT_4, RTEMS_EVENT_5, RTEMS_EVENT_6, RTEMS_EVENT_7, RTEMS_EVENT_8 };#if defined(__PPC)#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT#elseextern void Wait_X_ms( unsigned int timeToWait );#define phys_to_bus(address) ((unsigned int) ((address)))#define bus_to_phys(address) ((unsigned int) ((address)))#define rtems_bsp_delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZEstatic inline void st_le32(volatile unsigned32 *addr, unsigned32 value){ *(addr)=value ;}static inline unsigned32 ld_le32(volatile unsigned32 *addr){ return(*addr);}#endif#if (MCLBYTES < RBUF_SIZE)# error "Driver must have MCLBYTES > RBUF_SIZE"#endif/* * Per-device data */struct dec21140_softc { struct arpcom arpcom; rtems_irq_connect_data irqInfo; rtems_event_set ioevent; int numRxbuffers, numTxbuffers; volatile struct MD *MDbase; volatile struct MD *nextRxMD; volatile unsigned char *bufferBase; int acceptBroadcast; volatile struct MD *TxMD; volatile struct MD *SentTxMD; int PendingTxCount; int TxSuspended; unsigned int port; volatile unsigned int *base; /* * Statistics */ unsigned long rxInterrupts; unsigned long rxNotFirst; unsigned long rxNotLast; unsigned long rxGiant; unsigned long rxNonOctet; unsigned long rxRunt; unsigned long rxBadCRC; unsigned long rxOverrun; unsigned long rxCollision; unsigned long txInterrupts; unsigned long txDeferred; unsigned long txHeartbeat; unsigned long txLateCollision; unsigned long txRetryLimit; unsigned long txUnderrun; unsigned long txLostCarrier; unsigned long txRawWait;};static struct dec21140_softc dec21140_softc[NDECDRIVER];static rtems_id rxDaemonTid;static rtems_id txDaemonTid;/* * This routine reads a word (16 bits) from the serial EEPROM. *//* EEPROM_Ctrl bits. */#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */#define EE_CS 0x01 /* EEPROM chip select. */#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */#define EE_WRITE_0 0x01#define EE_WRITE_1 0x05#define EE_DATA_READ 0x08 /* EEPROM chip data out. */#define EE_ENB (0x4800 | EE_CS)/* The EEPROM commands include the alway-set leading bit. */#define EE_WRITE_CMD (5 << 6)#define EE_READ_CMD (6 << 6)#define EE_ERASE_CMD (7 << 6)static int eeget16(volatile unsigned int *ioaddr, int location){ int i; unsigned short retval = 0; int read_cmd = location | EE_READ_CMD; st_le32(ioaddr, EE_ENB & ~EE_CS); st_le32(ioaddr, EE_ENB); /* Shift the read command bits out. */ for (i = 10; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; st_le32(ioaddr, EE_ENB | dataval); rtems_bsp_delay_in_bus_cycles(200); st_le32(ioaddr, EE_ENB | dataval | EE_SHIFT_CLK); rtems_bsp_delay_in_bus_cycles(200); st_le32(ioaddr, EE_ENB | dataval); /* Finish EEPROM a clock tick. */ rtems_bsp_delay_in_bus_cycles(200); } st_le32(ioaddr, EE_ENB); for (i = 16; i > 0; i--) { st_le32(ioaddr, EE_ENB | EE_SHIFT_CLK); rtems_bsp_delay_in_bus_cycles(200); retval = (retval << 1) | ((ld_le32(ioaddr) & EE_DATA_READ) ? 1 : 0); st_le32(ioaddr, EE_ENB); rtems_bsp_delay_in_bus_cycles(200); } /* Terminate the EEPROM access. */ st_le32(ioaddr, EE_ENB & ~EE_CS); return ( ((retval<<8)&0xff00) | ((retval>>8)&0xff) );}static void no_op(const rtems_irq_connect_data* irq){ return;}static int dec21140IsOn(const rtems_irq_connect_data* irq){ return BSP_irq_enabled_at_i8259s (irq->name);}/* * DEC21140 interrupt handler */static rtems_isrdec21140Enet_interrupt_handler ( struct dec21140_softc *sc ){ volatile unsigned32 *tbase; unsigned32 status; tbase = (unsigned32 *)(sc->base); /* * Read status
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -