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

📄 lan91c111end.c

📁 LAN91C111驱动源码,使用C语言写成
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 + -