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

📄 esmcend.c

📁 基于嵌入式操作系统VxWorks的lan91c111的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 + -