?? esmcend.c
字號:
/* esmcEnd.c - SMSC 91cxx END network interface driver *//* Copyright 1984-2004 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,17jan04,jch Modified to load esmcEnd.h and smsc83c180.h locally for Mainstone. Various modifications to accomodate several (undocumented) restrictions imposed by the Mainstone design on access to the LAN91C111's register set. Added optional support for emptying and releasing internal FIFO pages in ISR context.01g,28mar03,bjn Problem with mdioRead01f,18feb03,bjn Fix esmcPollSend routine01e,31jan03,bjn Fix compiler warning01d,15jan03,bjn Added support for LAN91C111 device.01c,08oct02,bjn Fixed problems found with vxRegression tests01b,15jul02,dnb removed all byte accesses to simplify port to Kanis board01a,07jun02,dnb written from templateEnd.c and if_emsc.c*//*DESCRIPTIONThis module implements the SMSC 91CXX network interface driver.EXTERNAL SUPPORT REQUIREMENTSThis driver requires several external support functions, defined as macros:.CS SYS_INT_CONNECT(pDev, routine, arg) SYS_INT_DISCONNECT (pDev, routine, arg) SYS_INT_ENABLE(pDev) SYS_INT_DISABLE(pDev) data = READ_WORD(pDev, reg) WRITE_WORD(pDev, reg, data) ESMC_SWITCH_BANK(pDev, newBank).CEThese macros allow the driver to be customized for BSPs that usespecial versions of these routines.The macro SYS_INT_CONNECT is used to connect the interrupt handler tothe appropriate vector. By default it is the routine intConnect().The macro SYS_INT_DISCONNECT is used to disconnect the interrupt handler priorto unloading the module. By default this is a dummy routine thatreturns OK.The macro SYS_INT_ENABLE is used to enable the interrupt level for theend device. It is called once during initialization. It calls anexternal board level routine sysSmc91cxxIntEnable().The macro SYS_INT_DISABLE is used to disable the interrupt level for theend device. It is called once during shutdown. It calls anexternal board level routine sysSmc91cxxIntDisable().The macros READ_WORD and WRITE_WORD are used for accessing theesmc device. The default macros map these operations ontosysInWord() and sysOutWord().The macro ESMC_SWITCH_BANK selects the register bank. The default macrouses WRITE_WORD to do this.The HI_BYTE and LO_BYTE macros return the high and low bytes, respectively,of the word-length registers.ON_EXIT_ISR and SWAP_BYTES_IF_NECESSARY are (hopefully self-explanatory) macrosused to aid porting.INCLUDES: end.h endLib.h etherMultiLib.hSEE ALSO: muxLib, endLib, .I "Writing an Enhanced Network Driver"*//* * Disable "statement not found" warnings from the Diab compiler so that the * WRITE_WORD macro works as designed. The GNU compiler doesn't need this. */#ifdef _DIAB_TOOL#pragma option -Xlint=0x80#endif /* _DIAB_TOOL *//* includes */#include "vxWorks.h"#include "stdlib.h"#include "logLib.h"#include "sysLib.h"#include "stdio.h"#include "taskLib.h"#include "iv.h"#include "intLib.h"#include "netLib.h"#include "etherMultiLib.h"#include "end.h" /* Common END structures. */#include "endLib.h"#include "net/mbuf.h"#include "esmcEnd.h"#include "smsc83c180.h"#include "netinet/if_ether.h"#ifdef ESMC_USE_ISR_COPY#include "lstLib.h"#endif /* ESMC_USE_ISR_COPY *//* defines */#undef DRV_DEBUG/* Configuration items *//* Auto Negotiation */ #define ENET_AUTO 0 /* 0:Enable Auto-Negotiation */ /* 1:Disable Auto-Negotiation *//* Ethernet Speed */#define ENET_SPEED_10 10000000 /* 10 Mbit/sec interface */#define ENET_SPEED_100 100000000 /* 100 Mbit/sec interface *//* Duplex Mode */#define ENET_DUPLEX_HALF 0#define ENET_DUPLEX_FULL 1#define ATTACHMENT_DEFAULT 0 /* use card as configured */#define ATTACHMENT_AUI 1 /* AUI (thick, DIX, DB-15) */#define ATTACHMENT_BNC 2 /* BNC (thin, 10BASE-2) */#define ATTACHMENT_RJ45 3 /* RJ-45 (twisted pair, TPE, 10BASE-T)*//* Definitions for the flags field */#define END_POLLING 0x01#define ESMC_RCV_HANDLING_FLAG 0x02/* Debug macros */#ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_INT 0x0004#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0008#define DRV_DEBUG_POLL_TX 0x0010#define DRV_DEBUG_LOAD 0x0020#define DRV_DEBUG_IOCTL 0x0040#define DRV_DEBUG_ERR 0x0080#define DRV_DEBUG_MEM_INIT 0x0100#define DRV_DEBUG_CONFIG 0x0200#define DRV_DEBUG_ASSERT 0x0400#define DRV_DEBUG_91C100FD 0x0800/*#define DRV_DEBUG_MEM_INIT 0x1000#define DRV_DEBUG_MEM_INIT 0x2000#define DRV_DEBUG_MEM_INIT 0x4000*/#define DRV_ASSERT(arg) \ do{ \ if(esmcDebug & DRV_DEBUG_ASSERT) \ { \ if(!(arg)) \ { \ logMsg("Assertion failed: %s, %s, %d", \ (int) #arg,(int)__FILE__, __LINE__,4,5,6); \ } \ } \ } while(0)#define DRV_DEBUG_FN_TRACE 0x8000#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ do \ { \ if (esmcDebug & (FLG)) \ logMsg (X0, X1, X2, X3, X4, X5, X6); \ } \ while (0)#else /* DRV_DEBUG */#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) do {} while (0)#define DRV_ASSERT(arg) ((void)0)#endif /* DRV_DEBUG *//* * 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 */#ifndef SYS_INT_CONNECT#define SYS_INT_CONNECT(pDev,rtn,arg,pResult) \ { \ *(pResult) = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC ((pDev)->ivec), \ rtn, (int)(arg)); \ }#endif/* Macro to disconnect interrupt handler from vector */#ifndef SYS_INT_DISCONNECTLOCAL VOID dummyIsr (void) { };#define SYS_INT_DISCONNECT(pDev,rtn,arg,pResult) \ { \ IMPORT STATUS intConnect(); \ *(pResult) = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC ((pDev)->ivec), \ dummyIsr, (int)(arg)); \ }#endif/* Macro to enable the appropriate interrupt level */#ifndef SYS_INT_ENABLE#define SYS_INT_ENABLE(pDev) \ { \ IMPORT STATUS s3c2410IntLvlEnable(); \ s3c2410IntLvlEnable ((pDev)->ilevel); \ }#endif/* Macro to disable the appropriate interrupt level */#ifndef SYS_INT_DISABLE#define SYS_INT_DISABLE(pDev) \ { \ IMPORT STATUS s3c2410IntLvlDisable(); \ sysEsmcIntDisable ((pDev)->ilevel); \ }#endif/* * Macros to do word access to the chip. Default assumes an * I/O mapped device accessed in the x86 fashion. */#ifndef WRITE_WORD#define WRITE_WORD(pDev, addr, value) \ (sysOutWord ((pDev)->base+(addr), value))#endif#ifndef READ_WORD#define READ_WORD(pDev, addr) \ sysInWord ((pDev)->base+(addr))#endif#ifndef ESMC_SWITCH_BANK#define ESMC_SWITCH_BANK(pDev, newBank) \ WRITE_WORD(pDev, ESMC_BANK_SELECT, newBank);#endifIMPORT STATUS s3c2410IntLvlAck(int,int);#ifndef ON_EXIT_ISR#define ON_EXIT_ISR(pDev) (( STATUS )s3c2410IntLvlAck(pDev,0));#endif#ifndef SWAP_BYTES_IF_NECESSARY#define SWAP_BYTES_IF_NECESSARY(x) (x)#endif#ifndef LO_BYTE#define LO_BYTE(x) (x & 0xff)#endif#ifndef HI_BYTE#define HI_BYTE(x) (x >> 8)#endif/* cache macros */#ifndef ESMC_CACHE_INVALIDATE#define ESMC_CACHE_INVALIDATE(address, len) (void(0))#endif#ifndef CACHE_PIPE_FLUSH#define CACHE_PIPE_FLUSH() (void(0))#endif/* 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)#ifdef ESMC_USE_ISR_COPY/* Cluster preallocation for received frame copy within ISR */#define ESMC_CLUSTER_PREALLOC (16) /* pool clusters to preallocate */#endif /* ESMC_USE_ISR_COPY *//* The definition of the driver control structure */typedef struct esmc_device { END_OBJ endObj; /* The class we inherit from. */ END_ERR lastError; /* Last error passed to muxError */ int unit; /* unit number */ unsigned long base; /* device I/O base address */ int ilevel; /* h/w interrupt level */ int ivec; /* interrupt vector */ int config; /* configuration flags */ char enetAddr[6]; /* ethernet address */ char mcastFilter[8]; /* multicast filter */ int offset; /* packet data offset */ volatile int flags; volatile unsigned short imask; unsigned char chipId; unsigned char chipRev; unsigned short duplex; unsigned short speed; int phyAddr; unsigned int rxOverrun; unsigned int lateCollisions; unsigned int _16Collisions; unsigned int fifoTxUnderrun; unsigned int sqet; unsigned int lostCarrier; unsigned int alignErr; unsigned int badCrc; unsigned int tooLong; unsigned int tooShort;#ifdef ESMC_USE_ISR_COPY LIST freeClusters; /* free preallocated cluster list */ LIST busyClusters; /* busy preallocated cluster list */#endif /* ESMC_USE_ISR_COPY */ CL_POOL_ID clPoolId; /* cluster pool */ } ESMC_DEVICE;#ifdef ESMC_USE_ISR_COPY/* Cluster list node */typedef struct { NODE links; /* list links */ char *pCluster; /* cluster pointer */ int length; /* packet length */ UINT16 packetNo; /* packet number */ UINT16 statusRx; /* receiver status */ } CLUSTER_NODE;#endif /* ESMC_USE_ISR_COPY *//* globals */#ifdef DRV_DEBUGunsigned int esmcDebug = 0; /* 0xffffffff; */ /* DRV_DEBUG_LOAD | DRV_DEBUG_ASSERT; *///unsigned int esmcDebug = 0xffffffff; /* 0xffffffff; */ /* DRV_DEBUG_LOAD | DRV_DEBUG_ASSERT; */#endif /* DRV_DEBUG *//* locals */LOCAL char * pName[12] = { NULL, NULL, NULL, "LAN91C94", "LAN91C95", "LAN91C96", "LAN91C100", "LAN91C100FD", "LAN91C110" "LAN91C111" };typedef struct { char irq; char reg; } IRQ_TABLE;LOCAL NET_FUNCS esmcFuncTable;/* forward declarations */IMPORT int endMultiLstCnt (END_OBJ* pEnd);LOCAL void phyResetLAN91C111 (ESMC_DEVICE *);/* This is the only externally visible interface. */END_OBJ* esmcEndLoad (char* initString);/********************************************************************************* fsmcClkMDIO - Set up FEAST to communicate with PHY** RETURNS: N/A*/LOCAL void esmcClkMDIO ( ESMC_DEVICE * pDev, unsigned int MII_MGMTData ) {#ifdef ESMC_LAN91C111 WRITE_WORD(pDev, ESMC_MGMT, MII_MGMTData);#endif WRITE_WORD(pDev, ESMC_MGMT, MII_MGMTData | ESMC_MGMT_MCLK); WRITE_WORD(pDev, ESMC_MGMT, MII_MGMTData); }/********************************************************************************* mdioRead - Read the MDI pin of the ESMC_MGMT register** RETURNS: N/A*/LOCAL unsigned short mdioRead ( ESMC_DEVICE * pDev, unsigned char RegAdd ) { int i; unsigned short wData; unsigned short MII_MGMTval; ESMC_SWITCH_BANK(pDev, 3); MII_MGMTval = READ_WORD(pDev, ESMC_MGMT); MII_MGMTval &= 0xfff0; /* masking off lowest nibble */ /* Output Preamble (32 '1's) */ for (i=0;i<32;i++) esmcClkMDIO(pDev, MII_MGMTval | ESMC_MGMT_MDOE | ESMC_MGMT_MDO); /* Output Start of Frame ('01') */ for (i=0;i<2;i++) esmcClkMDIO(pDev, MII_MGMTval | ESMC_MGMT_MDOE | i); /* Output OPCode ('01' for write or '10' for Read) */ esmcClkMDIO(pDev, MII_MGMTval | ESMC_MGMT_MDOE | 1 ); esmcClkMDIO(pDev, MII_MGMTval | ESMC_MGMT_MDOE | 0 ); /* Output PHY Address */ for (i=4;i>=0;i--) esmcClkMDIO(pDev, MII_MGMTval | ESMC_MGMT_MDOE | ((pDev->phyAddr>>i) & 0x01) );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -