📄 at91emacend.c
字号:
/* at91EmacEnd.c - AT91RM9200 Enhanced Network Driver (END) */
/* Copyright 1984-2004 Wind River Systems, Inc. */
/*
modification history
--------------------
01a,24sep04,pdr written.
*/
/*
DESCRIPTION
This module implements a AT91 Ethernet MAC Controller (EMAC) network
interface driver. The EMAC is fully compliant with the IEEE 802.3
10Base-T and 100Base-T specifications. Hardware support of
the Media Independent Interface (MII) is built-in in the chip.
BOARD LAYOUT
This device is on-board. No jumpering diagram is necessary.
EXTERNAL INTERFACE
The driver provides the standard external interface, at91EmacEndLoad(), which
takes a string of colon-separated parameters. The parameters should be
specified in decimal, excepted the last parameter which is in hexadecimal
optionally preceeded by "0x" or a minus sign "-".
The format of the parameter string is:
"<ivec>:<ilevel>::<txNum>:<rxNum>:<userFlags>"
TARGET-SPECIFIC PARAMETERS
.IP <ivec>
This parameter is the vector associated with the device interrupt.
.IP <ilevel>
This parameter is the interrupt level associated with the interrupt controller.
.IP <txNum>
This parameter specifies the number of transmit buffers and transmit buffer
descriptors.
Each buffer descriptor resides in 12 bytes of the processor's external
RAM space, and each one points to a rounded 1600-byte buffer again in external
RAM. If this parameter is less than a minimum number specified in the
macro EMAC_END_TX_MIN, or if it is "NULL", a default value of 32 is used.
This parameter should always equal a even number.
.IP <rxNum>
This parameter specifies the number of receive buffers and receive buffer
descriptors.
Each buffer descriptor resides in 8 bytes of the processor's internal
RAM space at offset 0x200, and each one points to a rounded 1600-byte buffer
in external RAM.
If this parameter is less than a minimum number specified in the
macro EMAC_END_RX_MIN, or if it is "NULL", a default value of 32 is used.
This parameter should always equal a even number.
.IP <userFlags>
This field enables the user to give some degree of customization to the
driver, especially as regards the physical layer interface.
This parameter is not used for the moment and is reserved for futur extension.
.LP
EXTERNAL SUPPORT REQUIREMENTS
This driver requires three external support functions:
.IP sysEmacIntEnable()
.CS
STATUS sysEmacIntEnable (int level);
.CE
This routine is expected to enable the interrups coming from the EMAC.
This routine is expected to return OK on success, or ERROR.
.IP sysEmacIntDisable()
.CS
STATUS sysEmacIntDisable (int level);
.CE
This routine is expected to disable the interrups coming from the EMAC.
This routine is expected to return OK on success, or ERROR.
.IP sysEmacIntConnect()
.CS
STATUS sysEmacIntConnect(int ivec, VOIDFUNCPTR isr, int argument);
.CE
This routine is expected to connect the interrupt handler for the EMAC.
This routine is expected to return OK on success, or ERROR.
.IP sysEnetAddrGet()
.CS
STATUS sysEnetAddrGet (int unit, UCHAR * enetAddr);
.CE
The driver expects this routine to provide the six-byte Ethernet hardware
address that is used by this device. This routine must copy the six-byte
address to the space provided by <enetAddr>. This routine is expected to
return OK on success, or ERROR.
.LP
SYSTEM RESOURCE USAGE
The driver use the SRAM at offset 0x100 for the receive buffer header and
receive buffers. Maximal 10 packets can be received.
TUNING HINTS
The relative priority of the netTask and of the other tasks in the system
may heavily affect performance of this driver. Usually the best performance
is achieved when the netTask priority equals that of the other
applications using the driver.
INTERNAL
This driver contains conditional compilation switch EMAC_END_DBG.
If defined, adds debug output routines. Output is further
selectable at run-time via the at91EmacEndDebug global variable.
SEE ALSO: muxLib, endLib
.I "Writing and Enhanced Network Driver"
*/
/* includes */
#include "vxWorks.h"
#include "stdlib.h"
#include "cacheLib.h"
#include "intLib.h"
#include "end.h" /* Common END structures. */
#include "endLib.h"
#include "lstLib.h" /* Needed to maintain protocol list. */
#include "iv.h"
#include "semLib.h"
#include "logLib.h"
#include "netLib.h"
#include "stdio.h"
#include "sysLib.h"
#include "errno.h"
#include "errnoLib.h"
#include "memLib.h"
#include "iosLib.h"
#undef ETHER_MAP_IP_MULTICAST
#include "etherMultiLib.h" /* multicast stuff. */
#include "net/mbuf.h"
#include "net/unixLib.h"
#include "net/protosw.h"
#include "net/systm.h"
#include "net/if_subr.h"
#include "net/route.h"
#include "netinet/if_ether.h"
#include "sys/socket.h"
#include "sys/ioctl.h"
#include "sys/times.h"
#include "at91EmacEnd.h"
IMPORT int endMultiLstCnt (END_OBJ* pEnd);
#ifdef INCLUDE_NET_SHOW
IMPORT void netPoolShow (NET_POOL_ID pNetPool);
#endif /* INCLUDE_NET_SHOW */
/* defines */
#undef EMAC_RX_BUFFER_IN_SRAM /* use SRAM for RX descriptor and buffers */
#ifdef EMAC_RX_BUFFER_IN_SRAM
#define RX_BUFFER_SIZE 1600 /* buffer size for receiving packets (must be multiple of 64 bytes errata #11) */
#define NUM_RXBDS 8 /* 8 is the maximal number for 16 KB SRAM */
#endif /* EMAC_RX_BUFFER_IN_SRAM */
#ifdef TARGET_CSB337
/* Bit defines for the LED configuration register (0x14) */
#define LXT971_LED1(_x_) ((_x_ & 0xf) << 12) /* macros to set the led fields. they use the same settings */
#define LXT971_LED2(_x_) ((_x_ & 0xf) << 8)
#define LXT971_LED3(_x_) ((_x_ & 0xf) << 4)
#define LXT971_LED_SPEED 0x0 /* Display Speed Status (Continuous, Default) */
#define LXT971_LED_TX 0x1 /* Display Transmit Status (Stretched) */
#define LXT971_LED_RX 0x2 /* Display Receive Status (Stretched) */
#define LXT971_LED_COL 0x3 /* Display Collision Status (Stretched) */
#define LXT971_LED_LINK 0x4 /* Display Link Status (Continuous) */
#define LXT971_LED_DX 0x5 /* Display Duplex Status (Continuous) */
#define LXT971_LED_RX_TX 0x7 /* Display Receive or Transmit Activity (Stretched) */
#define LXT971_LED_ON 0x8 /* Test mode- turn LED on (Continuous) */
#define LXT971_LED_OFF 0x9 /* Test mode- turn LED off (Continuous) */
#define LXT971_LED_BLINK_FAST 0xa /* Test mode- blink LED fast (Continuous) */
#define LXT971_LED_BLINK_SLOW 0xb /* Test mode- blink LED slow (Continuous) */
#define LXT971_LED_LINK_RX 0xc /* Display Link and Receive Status combined 2 (Stretched) */
#define LXT971_LED_LINK_RX_TX 0xd /* Display Link and Activity Status combined 2 (Stretched) */
#define LXT971_LED_DX_COL 0xe /* Display Duplex and Collision Status combined 4 (Stretched) */
#define LXT971_LED_STRETCH_30MS (0 << 2)
#define LXT971_LED_STRETCH_60MS (1 << 2)
#define LXT971_LED_STRETCH_100MS (2 << 2)
#define LXT971_LED_STRETCH_ON BIT1
#endif /* TARGET_CSB337 */
/* Configuration items */
#define EH_SIZE (14)
#define END_SPEED_10M 10000000 /* 10Mbs */
#define END_SPEED_100M 100000000 /* 100Mbs */
#define END_SPEED END_SPEED_100M
/* initial divisor and final XOR value for reflected CRC */
#define INIT_REFLECTED 0xFFFFFFFF
#define XOROT INIT_REFLECTED
/* CRC for logical address filter */
#define EMAC_CRC_TO_FILTER_INDEX(crc) ((crc) >> 26) /* get 6 MSBits */
/*
* the total is rounded to 0x640 and it accounts for the required alignment
* of receive data buffers, and the cluster overhead.
*/
#define EMAC_END_MAX_CL_LEN ((EMAC_END_MAX_PCK_SZ + (12) \
+ (EMAC_END_BD_ALIGN - 1) \
+ (CL_OVERHEAD - 1)) \
& (~ (CL_OVERHEAD - 1)))
#define EMAC_END_MAX_RX_BUF ((EMAC_END_MAX_PCK_SZ + EMAC_END_BD_ALIGN - 1) \
& (~(EMAC_END_BD_ALIGN - 1)))
#define NET_TO_EMAC_END_BUF(netBuf) \
(((UINT32) (netBuf) + EMAC_END_BD_ALIGN - 1) \
& ~(EMAC_END_BD_ALIGN - 1))
/* Cache macros */
#if 0
#define END_CACHE_INVALIDATE(address, len)
#define END_CACHE_FLUSH(address, len)
#endif
#define END_CACHE_INVALIDATE(address, len) \
CACHE_DRV_INVALIDATE (pDrvCtrl->pCacheFuncs, (address), (len))
#define END_CACHE_FLUSH(address, len) \
CACHE_DRV_FLUSH (pDrvCtrl->pCacheFuncs, (address), (len))
/*
* Default macro definitions for BSP interface.
* These macros can be redefined in a wrapper file, to generate
* a new module with an optimized interface.
*/
/* Macro to connect interrupt handler to vector */
#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \
do { \
IMPORT STATUS sysEmacIntConnect(int, VOIDFUNCPTR, int); \
*pResult = sysEmacIntConnect ((int) INUM_TO_IVEC (pDrvCtrl->ivec), \
rtn, (int)arg); \
} while (0)
/* Macro to enable the appropriate interrupt level */
#define SYS_INT_ENABLE(pDrvCtrl) \
do { \
IMPORT STATUS sysEmacIntEnable(int); \
sysEmacIntEnable (pDrvCtrl->ilevel); \
} while (0)
/* Macro to disable the appropriate interrupt level */
#define SYS_INT_DISABLE(pDrvCtrl) \
do { \
IMPORT STATUS sysEmacIntDisable(int); \
sysEmacIntDisable (pDrvCtrl->ilevel); \
} while (0)
/* Macro to get the ethernet address from the BSP */
#define SYS_ENET_ADDR_GET(pDevice) \
do { \
IMPORT STATUS sysEnetAddrGet (int, UINT8*); \
sysEnetAddrGet (pDevice->unit, (char *)&pDevice->enetAddr); \
} while (0)
/* A shortcut for getting the hardware address from the MIB II stuff. */
#define END_HADDR(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
#define END_HADDR_LEN(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
/* intermediate remainders for table-driven CRC calculations */
LOCAL UINT32 crc32table[256] =
{
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
};
/*
* This will only work if there is only a single unit, for multiple
* unit device drivers these should be integrated into the EMAC_END_DEVICE
* structure.
*/
M_CL_CONFIG at91EmacEndMclBlkConfig = /* network mbuf configuration table */
{
/*
no. mBlks no. clBlks memArea memSize
----------- ---------- ------- -------
*/
0, 0, NULL, 0
};
CL_DESC at91EmacEndClDescTbl [] = /* network cluster pool configuration table */
{
/*
clusterSize num memArea memSize
----------- ---- ------- -------
*/
{EMAC_END_MAX_CL_LEN, 0, NULL, 0}
};
int at91EmacEndClDescTblNumEnt = (NELEMENTS(at91EmacEndClDescTbl));
/* Definitions for the flags field */
#define EMAC_PROMISCUOUS 0x1
#define EMAC_POLLING 0x2
#define EMAC_MIN_FBUF (1536) /* min first buffer size */
/* DEBUG MACROS */
#define EMAC_END_DBG
#ifdef EMAC_END_DBG
#define EMAC_END_DBG_OFF 0x0000
#define EMAC_END_DBG_RX 0x0001
#define EMAC_END_DBG_TX 0x0002
#define EMAC_END_DBG_INT 0x0004
#define EMAC_END_DBG_POLL (EMAC_END_DBG_POLL_RX | EMAC_END_DBG_POLL_TX)
#define EMAC_END_DBG_POLL_RX 0x0008
#define EMAC_END_DBG_POLL_TX 0x0010
#define EMAC_END_DBG_LOAD 0x0020
#define EMAC_END_DBG_IOCTL 0x0040
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -