📄 elnk.c
字号:
/* * RTEMS driver for Etherlink based Ethernet Controllers * * Copyright (C) 2003, Gregory Menke, NASA/GSFC * * 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. * * elnk.c * * *//* * Portions of this driver are taken from the Freebsd if_xl.c driver, * version "1.133 2003/03/19 01:48:14" and are covered by the license * text included below that was taken verbatim from the original file. * More particularly, all structures, variables, and #defines prefixed * with XL_ or xl_, along with their associated comments were taken * directly from the Freebsd driver and modified as required to suit the * purposes of this one. Additionally, much of the device setup & * manipulation logic was also copied and modified to suit. All types * and functions beginning with elnk are either my own creations or were * adapted from other RTEMS components, and regardless, are subject to * the standard OAR licensing terms given in the comments at the top of * this file. * * Greg Menke, 6/11/2003 */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */#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 ELNK_SUPPORTED#endif#if defined(__PPC__) && (defined(mpc604) || defined(mpc750) || defined(mpc603e))#define ELNK_SUPPORTED#endif/* #undef ELNK_SUPPORTED */#if defined(ELNK_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>#include "if_media.h"#include "mii.h"#if defined(__i386__)#include <irq.h>#define IO_MASK 0x3#define MEM_MASK 0xF#endif#if defined(__PPC__)#include <bsp/irq.h>#endif#ifdef malloc#undef malloc#endif#ifdef free#undef free #endif#define ELNK_DEBUG#define DRIVER_PREFIX "elnk"/** 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 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;** The default size in buffers of the rx & tx rings are given below.* This driver honors the rtems_bsdnet_ifconfig fields 'rbuf_count' and* 'xbuf_count', allowing the user to specify something else.*/#define RX_RING_SIZE 16 /* default number of receive buffers */#define TX_RING_SIZE 16 /* default number of transmit buffers *//* * Number of boards supported by this driver */#define NUM_UNITS 8/* * Receive buffer size -- Allow for a full ethernet packet including CRC */#define XL_PACKET_SIZE 1540/*** 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[NUM_UNITS]= { 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/* the actual duration waited in DELAY is not especially predictable, * though it will be consistent on a given host. It should not be * relied upon for specific timing given the vague per-bsp, * per-architecture implementation of the actual delay function. It * would probably be helpful to make this more accurate at some point... */#define DELAY(n) rtems_bsp_delay_in_bus_cycles( n*20 )/* * Register layouts. */#define XL_COMMAND 0x0E#define XL_STATUS 0x0E#define XL_TX_STATUS 0x1B#define XL_TX_FREE 0x1C#define XL_DMACTL 0x20#define XL_DOWNLIST_PTR 0x24#define XL_DOWN_POLL 0x2D /* 3c90xB only */#define XL_TX_FREETHRESH 0x2F#define XL_UPLIST_PTR 0x38#define XL_UPLIST_STATUS 0x30#define XL_UP_POLL 0x3D /* 3c90xB only */#define XL_PKTSTAT_UP_STALLED 0x00002000#define XL_PKTSTAT_UP_ERROR 0x00004000#define XL_PKTSTAT_UP_CMPLT 0x00008000#define XL_DMACTL_DN_CMPLT_REQ 0x00000002#define XL_DMACTL_DOWN_STALLED 0x00000004#define XL_DMACTL_UP_CMPLT 0x00000008#define XL_DMACTL_DOWN_CMPLT 0x00000010#define XL_DMACTL_UP_RX_EARLY 0x00000020#define XL_DMACTL_ARM_COUNTDOWN 0x00000040#define XL_DMACTL_DOWN_INPROG 0x00000080#define XL_DMACTL_COUNTER_SPEED 0x00000100#define XL_DMACTL_DOWNDOWN_MODE 0x00000200#define XL_DMACTL_TARGET_ABORT 0x40000000#define XL_DMACTL_MASTER_ABORT 0x80000000/* * Command codes. Some command codes require that we wait for * the CMD_BUSY flag to clear. Those codes are marked as 'mustwait.' */#define XL_CMD_RESET 0x0000 /* mustwait */#define XL_CMD_WINSEL 0x0800#define XL_CMD_COAX_START 0x1000#define XL_CMD_RX_DISABLE 0x1800#define XL_CMD_RX_ENABLE 0x2000#define XL_CMD_RX_RESET 0x2800 /* mustwait */#define XL_CMD_UP_STALL 0x3000 /* mustwait */#define XL_CMD_UP_UNSTALL 0x3001#define XL_CMD_DOWN_STALL 0x3002 /* mustwait */#define XL_CMD_DOWN_UNSTALL 0x3003#define XL_CMD_RX_DISCARD 0x4000#define XL_CMD_TX_ENABLE 0x4800#define XL_CMD_TX_DISABLE 0x5000#define XL_CMD_TX_RESET 0x5800 /* mustwait */#define XL_CMD_INTR_FAKE 0x6000#define XL_CMD_INTR_ACK 0x6800#define XL_CMD_INTR_ENB 0x7000#define XL_CMD_STAT_ENB 0x7800#define XL_CMD_RX_SET_FILT 0x8000#define XL_CMD_RX_SET_THRESH 0x8800#define XL_CMD_TX_SET_THRESH 0x9000#define XL_CMD_TX_SET_START 0x9800#define XL_CMD_DMA_UP 0xA000#define XL_CMD_DMA_STOP 0xA001#define XL_CMD_STATS_ENABLE 0xA800#define XL_CMD_STATS_DISABLE 0xB000#define XL_CMD_COAX_STOP 0xB800#define XL_CMD_SET_TX_RECLAIM 0xC000 /* 3c905B only */#define XL_CMD_RX_SET_HASH 0xC800 /* 3c905B only */#define XL_HASH_SET 0x0400#define XL_HASHFILT_SIZE 256/* * status codes * Note that bits 15 to 13 indicate the currently visible register window * which may be anything from 0 to 7. */#define XL_STAT_INTLATCH 0x0001 /* 0 */#define XL_STAT_ADFAIL 0x0002 /* 1 */#define XL_STAT_TX_COMPLETE 0x0004 /* 2 */#define XL_STAT_TX_AVAIL 0x0008 /* 3 first generation */#define XL_STAT_RX_COMPLETE 0x0010 /* 4 */#define XL_STAT_RX_EARLY 0x0020 /* 5 */#define XL_STAT_INTREQ 0x0040 /* 6 */#define XL_STAT_STATSOFLOW 0x0080 /* 7 */#define XL_STAT_DMADONE 0x0100 /* 8 first generation */#define XL_STAT_LINKSTAT 0x0100 /* 8 3c509B */#define XL_STAT_DOWN_COMPLETE 0x0200 /* 9 */#define XL_STAT_UP_COMPLETE 0x0400 /* 10 */#define XL_STAT_DMABUSY 0x0800 /* 11 first generation */#define XL_STAT_CMDBUSY 0x1000 /* 12 *//* * Interrupts we normally want enabled. */#define XL_INTRS \ (XL_STAT_UP_COMPLETE | XL_STAT_STATSOFLOW | XL_STAT_ADFAIL| \ XL_STAT_DOWN_COMPLETE | XL_STAT_TX_COMPLETE | XL_STAT_INTLATCH)/* * General constants that are fun to know. * * 3Com PCI vendor ID */#define TC_VENDORID 0x10B7/* * 3Com chip device IDs. */#define TC_DEVICEID_BOOMERANG_10BT 0x9000#define TC_DEVICEID_BOOMERANG_10BT_COMBO 0x9001#define TC_DEVICEID_BOOMERANG_10_100BT 0x9050#define TC_DEVICEID_BOOMERANG_100BT4 0x9051#define TC_DEVICEID_KRAKATOA_10BT 0x9004#define TC_DEVICEID_KRAKATOA_10BT_COMBO 0x9005#define TC_DEVICEID_KRAKATOA_10BT_TPC 0x9006#define TC_DEVICEID_CYCLONE_10FL 0x900A#define TC_DEVICEID_HURRICANE_10_100BT 0x9055#define TC_DEVICEID_CYCLONE_10_100BT4 0x9056#define TC_DEVICEID_CYCLONE_10_100_COMBO 0x9058#define TC_DEVICEID_CYCLONE_10_100FX 0x905A#define TC_DEVICEID_TORNADO_10_100BT 0x9200#define TC_DEVICEID_TORNADO_10_100BT_920B 0x9201#define TC_DEVICEID_HURRICANE_10_100BT_SERV 0x9800#define TC_DEVICEID_TORNADO_10_100BT_SERV 0x9805#define TC_DEVICEID_HURRICANE_SOHO100TX 0x7646#define TC_DEVICEID_TORNADO_HOMECONNECT 0x4500#define TC_DEVICEID_HURRICANE_555 0x5055#define TC_DEVICEID_HURRICANE_556 0x6055#define TC_DEVICEID_HURRICANE_556B 0x6056#define TC_DEVICEID_HURRICANE_575A 0x5057#define TC_DEVICEID_HURRICANE_575B 0x5157#define TC_DEVICEID_HURRICANE_575C 0x5257#define TC_DEVICEID_HURRICANE_656 0x6560#define TC_DEVICEID_HURRICANE_656B 0x6562#define TC_DEVICEID_TORNADO_656C 0x6564#define XL_RXSTAT_LENMASK 0x00001FFF#define XL_RXSTAT_UP_ERROR 0x00004000#define XL_RXSTAT_UP_CMPLT 0x00008000#define XL_RXSTAT_UP_OVERRUN 0x00010000#define XL_RXSTAT_RUNT 0x00020000#define XL_RXSTAT_ALIGN 0x00040000#define XL_RXSTAT_CRC 0x00080000#define XL_RXSTAT_OVERSIZE 0x00100000#define XL_RXSTAT_DRIBBLE 0x00800000#define XL_RXSTAT_UP_OFLOW 0x01000000#define XL_RXSTAT_IPCKERR 0x02000000 /* 3c905B only */#define XL_RXSTAT_TCPCKERR 0x04000000 /* 3c905B only */#define XL_RXSTAT_UDPCKERR 0x08000000 /* 3c905B only */#define XL_RXSTAT_BUFEN 0x10000000 /* 3c905B only */#define XL_RXSTAT_IPCKOK 0x20000000 /* 3c905B only */#define XL_RXSTAT_TCPCOK 0x40000000 /* 3c905B only */#define XL_RXSTAT_UDPCKOK 0x80000000 /* 3c905B only */#define XL_TXSTAT_LENMASK 0x00001FFF#define XL_TXSTAT_CRCDIS 0x00002000#define XL_TXSTAT_TX_INTR 0x00008000#define XL_TXSTAT_DL_COMPLETE 0x00010000#define XL_TXSTAT_IPCKSUM 0x02000000 /* 3c905B only */#define XL_TXSTAT_TCPCKSUM 0x04000000 /* 3c905B only */#define XL_TXSTAT_UDPCKSUM 0x08000000 /* 3c905B only */#define XL_TXSTAT_RND_DEFEAT 0x10000000 /* 3c905B only */#define XL_TXSTAT_EMPTY 0x20000000 /* 3c905B only */#define XL_TXSTAT_DL_INTR 0x80000000#define XL_FLAG_FUNCREG 0x0001#define XL_FLAG_PHYOK 0x0002#define XL_FLAG_EEPROM_OFFSET_30 0x0004#define XL_FLAG_WEIRDRESET 0x0008#define XL_FLAG_8BITROM 0x0010#define XL_FLAG_INVERT_LED_PWR 0x0020#define XL_FLAG_INVERT_MII_PWR 0x0040#define XL_FLAG_NO_XCVR_PWR 0x0080#define XL_FLAG_USE_MMIO 0x0100#define XL_EE_READ 0x0080 /* read, 5 bit address */#define XL_EE_WRITE 0x0040 /* write, 5 bit address */#define XL_EE_ERASE 0x00c0 /* erase, 5 bit address */#define XL_EE_EWEN 0x0030 /* erase, no data needed */#define XL_EE_8BIT_READ 0x0200 /* read, 8 bit address */#define XL_EE_BUSY 0x8000#define XL_EE_EADDR0 0x00 /* station address, first word */#define XL_EE_EADDR1 0x01 /* station address, next word, */#define XL_EE_EADDR2 0x02 /* station address, last word */#define XL_EE_PRODID 0x03 /* product ID code */#define XL_EE_MDATA_DATE 0x04 /* manufacturing data, date */#define XL_EE_MDATA_DIV 0x05 /* manufacturing data, division */#define XL_EE_MDATA_PCODE 0x06 /* manufacturing data, product code */#define XL_EE_MFG_ID 0x07#define XL_EE_PCI_PARM 0x08#define XL_EE_ROM_ONFO 0x09#define XL_EE_OEM_ADR0 0x0A#define XL_EE_OEM_ADR1 0x0B#define XL_EE_OEM_ADR2 0x0C#define XL_EE_SOFTINFO1 0x0D#define XL_EE_COMPAT 0x0E#define XL_EE_SOFTINFO2 0x0F#define XL_EE_CAPS 0x10 /* capabilities word */#define XL_EE_RSVD0 0x11#define XL_EE_ICFG_0 0x12#define XL_EE_ICFG_1 0x13#define XL_EE_RSVD1 0x14#define XL_EE_SOFTINFO3 0x15#define XL_EE_RSVD_2 0x16/* * Bits in the capabilities word */#define XL_CAPS_PNP 0x0001#define XL_CAPS_FULL_DUPLEX 0x0002#define XL_CAPS_LARGE_PKTS 0x0004#define XL_CAPS_SLAVE_DMA 0x0008#define XL_CAPS_SECOND_DMA 0x0010#define XL_CAPS_FULL_BM 0x0020#define XL_CAPS_FRAG_BM 0x0040#define XL_CAPS_CRC_PASSTHRU 0x0080#define XL_CAPS_TXDONE 0x0100#define XL_CAPS_NO_TXLENGTH 0x0200#define XL_CAPS_RX_REPEAT 0x0400#define XL_CAPS_SNOOPING 0x0800#define XL_CAPS_100MBPS 0x1000#define XL_CAPS_PWRMGMT 0x2000/* * Window 0 registers */#define XL_W0_EE_DATA 0x0C#define XL_W0_EE_CMD 0x0A#define XL_W0_RSRC_CFG 0x08#define XL_W0_ADDR_CFG 0x06#define XL_W0_CFG_CTRL 0x04#define XL_W0_PROD_ID 0x02
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -