📄 lan91c111end.c
字号:
/* lan91c111End.c - SMSCs LAN91C111 10/100 Non-PCI Ethernet Single Chip MAC + PHY */
/*
modification history
--------------------
01a,10apr00, rgk written.
*/
/*
DESCRIPTION: LAN91C111 10/100 Non-PCI Ethernet Single Chip MAC + PHY
The LAN91C111 is designed to facilitate the implementation of a third generation
of Fast Ethernet connectivity solutions for embedded applications. For this third
generation of products, flexibility and integration dominate the design requirements.
The LAN91C111 is a mixed signal analog/digital device that implements the MAC and
PHY portion of the CSMA/CD protocol at 10 and 100 Mbps. The design will also minimize
data throughput constraints utilizing a 32-bit, 16-bit or 8-bit bus Host interface
in embedded applications.
The total internal memory FIFO buffer size is 8 Kbytes, which is the total chip
storage for transmit and receive operations.
The SMSC LAN91C111 is software compatible with the LAN9000 family of product and the
chip supports Early TX, Early RX Functions which can be enabled by the ioctl()
function.
Memory management is handled using a patented optimized MMU (Memory Management Unit)
architecture and a 32-bit wide internal data path. It also dynamically allocates
buffer memory in an efficient buffer utilization scheme, reducing software tasks
and relieving the host CPU from performing these housekeeping functions.
Two different interfaces are supported on the network side. The first Interface is a
standard Magnetics transmit/receive pair interfacing to 10/100Base-T utilizing the
internal physical layer block. The second interface follows the MII (Media Independent
Interface) specification standard, consisting of 4 bit wide data transfers at the
nibble rate. This interface is applicable to 10 Mbps standard Ethernet or 100 Mbps
Ethernet networks.
The LAN91C111 can automatically configure itself for 100 or 10 Mbps and Full or Half
Duplex operation with the on-chip Auto-Negotiation algorithm. The VxWorks driver sets
this in the LOAD_STRING passed to the driver.
BOARD LAYOUT
The board resides on a ISA slot and it can be configured with the following jumpers
and DIP-switches.
I. Jumper Description:
S.No: Jumper Function REF Pin Settings Description
-----------------------------------------------------------------------------------
1. Serial EEPROM J5 1-2 512 X 16
Memory configuration 2-3 1K X 8
-----------------------------------------------------------------------------------
2. MII Volatage J3 1-2 +3.3
Selection 2-3 +5.0
-----------------------------------------------------------------------------------
3. LNK#/GPO J2 Pin1:Groung Used for General
purpose to indicate
Status of LINK
Pin2: LNK#
-----------------------------------------------------------------------------------
4. Interrupt Routing JP1 1-2 INT1
2-3 INT10
3-4 INT9
-----------------------------------------------------------------------------------
II. DIP-Switches Description:
S.No: Switch Function REF Description
-----------------------------------------------------------------------------------
1. EEPROM Control S1 Switch 1-3 Applies to 3 Bit EEPROM
addressin order.
Switch 4 is the EEPROM Enable control.
-----------------------------------------------------------------------------------
EXTERNAL INTERFACE
The driver provides two external interfaces to the card. The first is the END driver
interface, which exposes only the smsc91c111Load() routine. This routine expects the
<initString> parameter as input. This parameter passes in a colon-delimited string
of the format:
"<unit>:<IOBase>:<interruptVector>:<interruptLevel>:<offset>:<configValue>
The lan91c111Load() function uses strtok() to parse the string.
TARGET-SPECIFIC PARAMETERS
.IP <unit>
Device unit number.
.IP <IOBase>
Base address of the IO port on the ISA bus.
.IP <interruptVector>
Interrupt Vector.
.IP <interruptLeve>
Interrupt Level.
.IP <offsent>
offset int cluster
IP <config value>
Configuration Parameter value for 100Mbps, 10Mbps, Hafl Duplex, Full Duplex,
Early Tx and early rx.
EXTERNAL SUPPORT REQUIREMENTS
This driver requires several external support functions, defined as macros:
.CS
SYS_INT_CONNECT(pDrvCtrl, routine, arg)
SYS_INT_DISCONNECT (pDrvCtrl, routine, arg)
SYS_INT_ENABLE(pDrvCtrl)
SYS_INT_DISABLE(pDrvCtrl)
SYS_OUT_BYTE(pDrvCtrl, reg, data)
SYS_IN_BYTE(pDrvCtrl, reg, data)
SYS_OUT_WORD(pDrvCtrl, reg, data)
SYS_IN_WORD(pDrvCtrl, reg, data)
.CE
There are default values in the source code for these macros.The first argument to
each is the device controller structure. Thus, each has access back to all the
device-specific information. Having the pointer in the macro facilitates the
addition of new features to this driver.
The macros SYS_INT_CONNECT, SYS_INT_DISCONNECT, SYS_INT_ENABLE, and SYS_INT_DISABLE
allow the driver to be customized for BSPs that use special versions of these
routines.
The macro SYS_INT_CONNECT is used to connect the interrupt handler to the
appropriate vector. By default it is the routine intConnect().
The macro SYS_INT_DISCONNECT is used to disconnect the interrupt handler prior to
unloading the module. By default this is a dummy routine that returns OK.
The macro SYS_INT_ENABLE is used to enable the interrupt level for the end device.
It is called once during initialization. It calls an external board level routine
intEnable() that is usually defined in the BSP.
The macro SYS_INT_DISABLE is used to disable the interrupt level for the end device.
It is called during stop. It calls an external board level routine intDisable()
that is usually defined in the BSP.
The macro SYS_OUT_BYTE is used to write 8 bits to the device. Many BSP's implement
some type of sysOutByte() call to write a byte to whatever the architecture defines
as I/O space. SYS_OUT_BYTE should call a system-dependent routine that delivers its
8-bit argument to the address indicated by the <reg> argument. This address will be
based on the <IOBase> set by the LOAD_STRING argument passed to lan91c111Load.
The macro SYS_IN_BYTE is used to read 8 bits from the device. Many BSP's implement
some type of sysInByte() call to read a byte from whatever the architecture defines
as I/O space. SYS_IN_BYTE should call a system-dependent routine that reads an 8-bit
value from the address indicated by the <reg> argument. This address will be based
on the <IOBase> set by the LOAD_STRING argument passed to lan91c111Load.
The macro SYS_OUT_WORD is used to write 16 bits to the device. Many BSP's implement
some type of sysOutWord() call to write a byte to whatever the architecture defines
as I/O space. SYS_OUT_WORD should call a system-dependent routine that delivers its
16-bit argument to the address indicated by the <reg> argument. This address will
be based on the <IOBase> set by the LOAD_STRING argument passed to lan91c111Load.
The macro SYS_IN_WORD is used to read 16 bits from the device. Many BSP's implement
some type of sysInWord() call to read a byte from whatever the architecture defines
as I/O space. SYS_IN_WORD should call a system-dependent routine that reads an 16-bit
value from the address indicated by the <reg> argument. This address will be based
on the <IOBase> set by the LOAD_STRING argument passed to lan91c111Load.
SYSTEM RESOURCE USAGE
When implemented, this driver requires the following system resources:
- one interrupt vector
- I/O space for the ISA card
Multicast addresses are handled by adding and deleting them from a list maintined
on-board the card, with a maximum of 10 entries.
The driver requires 1520 bytes of preallocation for Transmit Buffer and 1520*nRxFrames
of receive buffers. The default value of nRxFrames is 64 therefore total
pre-allocation is (64 + 1)*1520.
INCLUDES:
end.h endLib.h etherMultiLib.h lan91c111.h
SEE ALSO: muxLib, endLib
.I "Writing an 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 "wdLib.h"
#include "iv.h"
#include "semLib.h"
#include "etherLib.h"
#include "logLib.h"
#include "netLib.h"
#include "netBufLib.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 "end.h"
#include "muxLib.h"
#include "etherLib.h"
#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/in.h"
#include "sys/socket.h"
#include "sys/ioctl.h"
#include "sys/times.h"
#include "arpLib.h"
#include "lan91C111End.h"
#define LAN91C111_BUFSIZE (ETHERMTU + ENET_HDR_REAL_SIZ + 6)
#define ETHER_ZLEN 60
#define EH_SIZE (14) /* Header size (bytes */
#define ENET_ADDR_LEN 6 /* 6 byte IEEE address */
#define LAN91C111_SPEED 10000000
#define LAN91C111_DEV_NAME "lnc"
#define LAN91C111_DEV_NAME_LEN strlen(LAN91C111_DEV_NAME)
#define FLAG_PROMISC 0x01
#define LAN91C111_MIN_FBUF (1536) /* min first buffer size */
/* 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)
#ifndef SYS_BUS_INT_ACK
#define SYS_BUS_INT_ACK(pDrvCtrl) \
{ \
IMPORT int sysBusIntAck(); \
sysBusIntAck (pDrvCtrl->ilevel); \
}
#endif /*SYS_BUS_INT_ACK*/
/* Macro to get the ethernet address from the BSP */
#ifndef SYS_ENET_ADDR_GET
#define SYS_ENET_ADDR_GET(pDevice) \
{ \
bcopy ((char *)(&pDevice->CurrentAddress), (char *)(&pDevice->enetAddr), 6); \
}
#endif
#ifdef SYS_INT_CONNECT
#undef SYS_INT_CONNECT
#endif
/* INUM_TO_IVEC expects Interrupt Vector Arguement. Normally it is taken from
the init string which is defined in confignet.h file which defines the ivector
to be INT_VEC_LAN91C111 which is actually INT_VEC_GET(INT_LVL_LAN91C111). this
ultimately evaluates to (0x20 + INT_LVL_LAN91C111 */
/* IMPORT STATUS sysIntConnect(); */
#define SYS_INT_CONNECT(pDrvCtrl,rtn,arg,pResult) \
{ \
IMPORT STATUS intConnect(); \
*pResult = intConnect ((VOIDFUNCPTR *) (INUM_TO_IVEC(pDrvCtrl->ivec)), \
rtn, (int)arg); \
}
#ifndef SYS_INT_DISCONNECT
#define SYS_INT_DISCONNECT(pDrvCtrl,rtn,arg,pResult) \
{ \
*pResult = OK; /* HELP: need a real routine */ \
}
#endif /*SYS_INT_DISCONNECT*/
#ifdef SYS_INT_ENABLE
#undef SYS_INT_ENABLE
#endif
#define SYS_INT_ENABLE(pDrvCtrl) sysIntEnablePIC(pDrvCtrl->ilevel)
void lan91c111Delay();
#ifdef SYS_OUT_SHORT
#undef SYS_OUT_SHORT
#endif /*SYS_OUT_SHORT*/
#define SYS_OUT_SHORT(addr,value) sysOutWord(addr, value);lan91c111Delay()
#ifndef SYS_OUT_LONG
#undef SYS_OUT_LONG
#endif
#define SYS_OUT_LONG(addr, value) sysOutLong(addr, value);lan91c111Delay()
#ifndef SYS_IN_SHORT
#undef SYS_IN_SHORT
#endif /*SYS_IN_SHORT*/
#define SYS_IN_SHORT(port, value_addr) (*value_addr = sysInWord(port))
#ifndef SYS_IN_LONG
#undef SYS_IN_LONG
#endif
#define SYS_IN_LONG(port, value_addr) (*value_addr = sysInLong(port))
#ifndef SYS_ENET_ADDR_GET
#define SYS_ENET_ADDR_GET(pAddress) \
{ \
IMPORT unsigned char lnEnetAddr[]; \
bcopy ((char *)lnEnetAddr, (char *)(pAddress), 6); \
}
#endif /* SYS_ENET_ADDR_GET */
/* 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)
#define END_FLAGS_ISSET(pEnd, setBits) \
((pEnd)->flags & (setBits))
#define PING_DEBUG 1
#if PING_DEBUG
UINT RxBuff[25],TxBuff[25];
char* debugTxBuf;
#endif
/* typedefs */
/* The definition of the driver control structure */
typedef struct lan_device
{
END_OBJ endObj; /* The class we inherit from. */
int unit; /* unit number */
int ivec; /* interrupt vector */
int ilevel; /* interrupt level */
char* memBase; /* LANCE memory pool base */
char* memAdrs; /* LANCE memory pool base */
int memSize; /* LANCE memory pool size */
int memWidth; /* width of data port */
int offset;
long flags; /* Our local flags. */
UCHAR enetAddr[6]; /* ethernet address */
CACHE_FUNCS cacheFuncs; /* cache function pointers */
CL_POOL_ID pClPoolId;
END_ERR lastError; /* Last error passed to muxError */
BOOL errorHandling; /* task level error handling */
u_short errorStat; /* error status */
UINT InitConfigVal;
BOOL AllocPending;
UCHAR *sendBuf;
USHORT sendDatalen;
NETWORK_ADDRESS userNetAddr;
BOOLEAN userNetAddrOverRide;
int numFrames; /* Number of frames to allocate */
BOOL rxHandling;
RX_PKT *pRxBase; /* Rx ring buffer base */
RX_PKT *pRxReadIndex;
RX_PKT *pRxWriteIndex;
BOOL txHandling; /* tx task scheduled */
TX_PKT *pTxBase; /* Tx ring buffer base */
TX_PKT *pTxReadIndex;
TX_PKT *pTxWriteIndex;
BOOLEAN Sqet; /* Enable/disable SQET monitoring */
BOOLEAN Speed100; /* 100mb set (Smc91c100) */
USHORT Rcr; /* Updated Receive Control Register. */
USHORT EphStatus; /* Last status read. */
USHORT LinkStatusChange;
UINT TempPhyAddr; /* Store PHY addr 07/26/00 pg */
UINT PhyType; /* Strore PHY type 10/23/00 PG */
UINT IOBase; /* Base port */
USHORT ConfigReg; /* Config register to be output */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -