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

📄 at91eth.c

📁 ARM板驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* at91Eth.c - AT91RM9200 Ethernet controller driver  */#include "vxWorks.h"#include "intLib.h"#include "netLib.h"#include "end.h"#include "endLib.h"#include "cacheLib.h"#include "miiLib.h"#include "errno.h"#include "stdio.h"#include "logLib.h"#include "taskLib.h"#include "config.h"#include "drv/intrCtl/at91Intr.h"#include "at91_ether.h"#define DRV_DEBUG_RX        0x0001#define DRV_DEBUG_TX        0x0002#define END_CACHE_PHYS_TO_VIRT(x) x#undef  DEBUG_TRACE#define RX_WAIT_MAX                     (CPLL_FREQ * 1000)  /* Rx completion timeout */#define TX_WAIT_MAX                     (CPLL_FREQ * 1000)  /* Tx completion timeout */#define MII_WAIT_MAX                    (CPLL_FREQ * 1000)  /* max delay for the MII operation */#ifndef NSDELAY#define NSDELAY(nsec)                                           \{                                                               \    volatile int nx;                                            \    volatile int loop = (int)(((CPLL_FREQ * nsec) / 1000) + 1); \                                                                \    for (nx=0; nx<loop; nx++);                                  \}#endif  /* NSDELAY *//* External */IMPORT STATUS   sysSecEnetAddrGet(int unit, UCHAR* address);static    int unit = 0;/* Forward Function Declarations */LOCAL STATUS    at91EthAnRestart(ETH_DRV_CTRL *dev);LOCAL void      at91EthRxHandler(ETH_DRV_CTRL *dev);LOCAL void      at91EthTxHandler(ETH_DRV_CTRL *dev);#ifdef  DEBUG_TRACELOCAL void      at91EthHexDump(UCHAR *p, ULONG l);#endif  /* DEBUG_TRACE */#include "at91_ether.c"LOCAL void at91EthMiiRead(ETH_DRV_CTRL* dev, unsigned char phy_addr, unsigned char address, unsigned short *value){	unsigned int l;	read_phy(dev->base_addr, phy_addr,address, &l);	*value = (unsigned short) l;}LOCAL void at91EthMiiWrite(ETH_DRV_CTRL* dev, unsigned char phy_addr, unsigned char address, unsigned short value){	unsigned int l=value;	write_phy(dev->base_addr, phy_addr,address, l);	}/********************************************************************************* at91EthInit - initialize S3C2510 Ethernet controller** RETURNS: OK, or ERROR.*/STATUS at91EthInit(    ETH_DRV_CTRL *dev     ){    at91ether_probe(dev);    /* Initialize flags. */    dev->bPolling   = FALSE;    dev->bTxBlocked = FALSE;    dev->bRxHandler = FALSE;    dev->bTxHandler = FALSE;    return OK;}/********************************************************************************* at91EthAnRestart - restart auto negotiation** RETURNS: OK, or ERROR.*/STATUS at91EthAnRestart(    ETH_DRV_CTRL *dev                           ){    UINT16 phyAddr = dev->phyInfo.phyAddr;    int timeout = MII_WAIT_MAX;     /* Perserve selector. */    dev->PHYREGS.phyAds &= MII_ADS_SEL_MASK;    /* Set appropriate options. */    dev->PHYREGS.phyAds |=#ifdef  ETH_10BT                                MII_TECH_10BASE_T |         /* 10T half-duplex capable */#endif  /* ETH_10BT */#ifdef  ETH_FULL_DUPLEX                                MII_TECH_100BASE_TX_FD |    /* 100TX-FX full-duplex capable */#ifdef  ETH_10BT                                MII_TECH_10BASE_FD |        /* 10T full-duplex capable */#endif  /* ETH_10BT */#endif  /* ETH_FULL_DUPLEX */                                MII_TECH_100BASE_TX;        /* 100TX-FX half-duplex capable */    /* Initialize Auto Negotiation Advertisement Register. */    at91EthMiiWrite(dev, phyAddr, MII_AN_ADS_REG, dev->PHYREGS.phyAds);    /* Enable and Start Auto Negotiation. */    dev->PHYREGS.phyCtrl |= MII_CR_AUTO_EN |           /* Auto-Negotiation Enable */                                 MII_CR_RESTART;            /* Restart Auto Negotiation */    /* Start auto negotiation. */    at91EthMiiWrite(dev, phyAddr, MII_CTRL_REG, dev->PHYREGS.phyCtrl);    /* Wait until start auto negotiation. */    while (1)    {        at91EthMiiRead(dev, phyAddr, MII_CTRL_REG, &dev->PHYREGS.phyCtrl);        if (!(dev->PHYREGS.phyCtrl & MII_CR_RESTART))        {            break;        }    }    /* Wait until complete auto negotiation. */    while (1)    {        at91EthMiiRead(dev, phyAddr, MII_STAT_REG, &dev->PHYREGS.phyStatus);        if (dev->PHYREGS.phyStatus & MII_SR_AUTO_NEG)        {            break;        }        if (--timeout == 0)        {            printf("eth%d Error: MII auto negotiation timeout\n", dev->unit);            return ERROR;        }    }    return OK;}/********************************************************************************* at91EthFlagsSet - set device flags** RETURNS: OK, or ERROR.*/STATUS at91EthFlagsSet(    ETH_DRV_CTRL *dev      ){    long flags;#ifdef  DEBUG_TRACE    printf("eth%d FlagsSet, %08X\n", unit, (UINT32)dev->endObj.flags);#endif  /* DEBUG_TRACE */    flags = END_FLAGS_GET(&dev->endObj);    if (flags & IFF_UP)    {        /* Config down. */        END_FLAGS_CLR(&dev->endObj, IFF_UP | IFF_RUNNING);    }    dev->flags = flags;    at91ether_set_rx_mode(dev);      if (flags & IFF_UP)    {        /* Config up. */        END_FLAGS_SET(&dev->endObj, IFF_UP | IFF_RUNNING);    }    return OK;}/********************************************************************************* at91EthLoopSet - set loop mode** RETURNS: OK, or ERROR.*/void at91EthLoopSet(    ETH_DRV_CTRL *dev,           int mode                          ){}/********************************************************************************* at91EthMCastAdd - add multicast address** RETURNS: OK, or ERROR.*/  STATUS at91EthMCastAdd(    ETH_DRV_CTRL *dev,         UCHAR *pAddr                    ){	unsigned char mc_filter[2];	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;	unsigned int i, bitnr;	mc_filter[0] = mc_filter[1] = 0;	bitnr = ether_crc(ETH_ALEN, pAddr) >> 26;	mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);	regs->EMAC_HSH |= mc_filter[1];	regs->EMAC_HSL |= mc_filter[0];    return ERROR;}/********************************************************************************* at91EthMCastDel - remove multicast address** RETURNS: OK, or ERROR.*/STATUS at91EthMCastDel(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    UCHAR *pAddr                                            /* pointer to the multicast address */    ){	unsigned char mc_filter[2];	unsigned int i, bitnr;AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;	mc_filter[0] = mc_filter[1] = 0;	bitnr = ether_crc(ETH_ALEN, pAddr) >> 26;	mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);	regs->EMAC_HSH &= ~mc_filter[1];	regs->EMAC_HSL &= ~mc_filter[0];    return ERROR;}/********************************************************************************* at91EthStart - start S3C2510 Ethernet controller** RETURNS: OK, or ERROR.*/STATUS at91EthStart(    ETH_DRV_CTRL *dev                                  /* pointer to driver structure */    ){    return at91ether_open(dev);    return OK;}/********************************************************************************* at91EthStop - stop S3C2510 Ethernet controller** RETURNS: OK, or ERROR.*/STATUS at91EthStop(    ETH_DRV_CTRL *dev                                  /* pointer to driver structure */    ){	return at91ether_close(dev);    return OK;}/********************************************************************************* at91EthPlllStart - start polling mode** RETURNS: OK, or ERROR.*/STATUS at91EthPollStart(    ETH_DRV_CTRL *dev                                  /* pointer to driver structure */    ){	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;#ifdef  DEBUG_TRACE        printf("eth%d PollStart\n", unit);#endif  /* DEBUG_TRACE */    /* Disable interrupt. */    intDisable(dev->irq);    regs->EMAC_IDR = AT91C_EMAC_RCOM | AT91C_EMAC_TCOM ;						    dev->bPolling = TRUE;    return OK;}/********************************************************************************* at91EthPollStop - stop polling mode** RETURNS: OK, or ERROR.*/STATUS at91EthPollStop(    ETH_DRV_CTRL *dev                                  /* pointer to driver structure */    ){ /*   int unit = dev->unit;*/	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;#ifdef  DEBUG_TRACE        printf("eth%d PollStop\n", unit);#endif  /* DEBUG_TRACE */    regs->EMAC_IER = AT91C_EMAC_RCOM | AT91C_EMAC_TCOM ;    dev->bPolling = FALSE;    /* Enable interrupt. */    intEnable(dev->irq);    return OK;}/********************************************************************************* at91EthRbdFree - free RBD** RETURNS: N/A.*/void at91EthRbdFree(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    PETHRBD pRbd                                            /* pointer to the RBD to be freed */    ){	struct at91_private *lp = (struct at91_private *) dev->priv;#ifdef  DEBUG_TRACE    printf("eth%d RbdFree\n", dev->unit);#endif  /* DEBUG_TRACE */   	pRbd->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE;	/* reset ownership bit */	if (lp->rxBuffIndex == MAX_RX_DESCR-1)				/* wrap after last buffer */		lp->rxBuffIndex = 0;	else		lp->rxBuffIndex++;        }/*    ** at91EthRbdCheck - check RBD** RETURNS: length of frame received.*/ULONG at91EthRbdCheck(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    PETHRBD pRbd                                            /* pointer to the RBD to be checked */    ){    int length = pRbd->descriptors[dev->priv->rxBuffIndex].size & 0x7ff;    return (length);}/********************************************************************************* at91EthTbdGet - allocate TBD** RETURNS: pointer to the TBD.*/unsigned char* at91EthTbdGet(    ETH_DRV_CTRL *dev                                  /* pointer to driver structure */    ){	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;        char *pBuf=0;#ifdef  DEBUG_TRACE    printf("eth%d TbdGet\n", dev->unit);#endif  /* DEBUG_TRACE */    /* Get the first available TBD. *//*    pTbd = (PETHTBD)(dev->tbdBase + dev->tbdFree * SIZE_BD);*//*  if (dev->pClPool) */    {          if (!(regs->EMAC_TSR & AT91C_EMAC_BNQ))        {            return NULL;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -