⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec21140.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  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 + -