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

📄 at91eth.c

📁 ARM板驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Allocate cluster buffer. */        pBuf = netClusterGet(dev->endObj.pNetPool, dev->endObj.pNetPool->clTbl[0]);        if (!pBuf)        {#ifdef  DEBUG_TRACE            printf("eth%d Error: Failed to allocate cluster buffer\n", dev->unit);#endif  /* DEBUG_TRACE */            return NULL;        }       /* pBuf =(pBuf + (SIZE_ETH_FB_HDR - 4));*/    }      return (pBuf);}/********************************************************************************* at91EthTbdFree - free TBD** RETURNS: N/A.*/void at91EthTbdFree(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    unsigned char* pBuf                                             /* pointer to the TBD to be freed */    ){#ifdef  DEBUG_TRACE    printf("eth%d TbdFree\n", dev->unit);#endif  /* DEBUG_TRACE */    /* Free cluster buffer if necessary. */   /* if (dev->pClPool)*/    {        /*netClFree(dev->endObj.pNetPool, (UCHAR *)(pBuf - (SIZE_ETH_FB_HDR - 4)));*/        netClFree(dev->endObj.pNetPool, (UCHAR *)(pBuf));    }    /* Free the used TBD. */    /* Advance to next RBD. *//*   dev->tbdIndex++;    if (dev->tbdIndex == NUM_TBD_ETH)    {        dev->tbdIndex = 0;    }*/}/********************************************************************************* at91EthTbdStart - start transmit** RETURNS: N/A.*/void at91EthTbdStart(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    unsigned char* data ,                                   /* pointer to the TBD to be freed */    ULONG length                                            /* length of data */    ){	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;	struct at91_private *lp = (struct at91_private *) dev->priv;	if(regs->EMAC_TSR & AT91C_EMAC_BNQ){	/* Store packet information (to free when Tx completed) */	lp->skb = data;	lp->skb_length = length;	cacheFlush(DATA_CACHE,data, length); /* clean_dcache_range(data, length);*/	lp->skb_physaddr = (unsigned long) data ;       /*cacheDrvVirtToPhys( )*/	lp->stats.tx_bytes += length;	/* Set address of the data in the Transmit Address register */	regs->EMAC_TSR |= AT91C_EMAC_COMP;	regs->EMAC_TAR = lp->skb_physaddr ;	/* Set length of the packet in the Transmit Control register */	regs->EMAC_TCR = length;	}}/********************************************************************************* at91EthTbdCheck - check TBD** RETURNS: OK, or ERROR.*/STATUS at91EthTbdCheck(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    unsigned char* pTbd                                            /* pointer to the TBD to be checked */    ){ 	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;	struct at91_private *lp = (struct at91_private *) dev->priv;    int timeout = TX_WAIT_MAX;    int retry = 3;#ifdef  DEBUG_TRACE    printf("eth%d TbdCheck\n", dev->unit);#endif  /* DEBUG_TRACE */    /* Check if completed. */    while ( !(regs->EMAC_TSR & AT91C_EMAC_BNQ))    {        if (--timeout == 0)        {            if (--retry == 0)            {                printf("eth%d Error: Tx timeout\n", dev->unit);                return ERROR;            }            timeout = TX_WAIT_MAX;         }    }    return ERROR;}/********************************************************************************* at91EthSend - send packet in interrupt mode** RETURNS: OK, or END_ERR_BLOCK.*/STATUS at91EthSend(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    M_BLK_ID pMblk                                          /* pointer to the mBlk/cluster pair */    ){    ULONG length;    unsigned char* pBuf=0;	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;    if (!(regs->EMAC_TSR & AT91C_EMAC_BNQ)) return ERROR;#ifdef  DEBUG_TRACE    printf("eth%d Send, 0x%08X\n", unit, (UINT32)pMblk->mBlkHdr.mData);#endif  /* DEBUG_TRACE */    if (dev->bTxBlocked)    {        /* Retry later. */        return END_ERR_BLOCK;    }    if (dev->bPolling)    {        return ERROR;    }    	    length = pMblk->mBlkPktHdr.len;    /* Check frame length. */    if ((length <= SIZE_ETH_HDR) || (length > SIZE_ETH_MFLR))    {        /* Up-date statistics. */        dev->MIB2TBL.ifOutErrors++;        return ERROR;    }      pBuf = at91EthTbdGet(dev);#if 0    if ((pMblk->mBlkHdr.mData >= (char *)SYS_MEM_TOP) && (pMblk->mBlkHdr.mNext == NULL))    {        char *pBuf1 = pMblk->pClBlk->clNode.pClBuf;        length = pMblk->mBlkPktHdr.len;        /* Swap buffer. */        pMblk->pClBlk->clNode.pClBuf = (char *)(pBuf - (SIZE_ETH_FB_HDR - 4));        pBuf = (pBuf1 + (SIZE_ETH_FB_HDR - 4));        pMblk->mBlkHdr.mData = (char *)(pBuf + SIZE_ETH_WA);    }    else#endif        {        /* Copy data. */        length = netMblkToBufCopy(pMblk, (char *)(pBuf + SIZE_ETH_WA), NULL);    }    /* Bump the statistic counter. */    END_ERR_ADD (&dev->endObj, MIB2_OUT_UCAST, +1);    /* Free the Mblk. */    netMblkClChainFree(pMblk);#ifdef  DEBUG_TRACE    at91EthHexDump((UCHAR *)(pBuf + SIZE_ETH_WA), length);#endif  /* DEBUG_TRACE */    /* Start transmit. */    at91EthTbdStart(dev, pBuf, length);    return OK;}/********************************************************************************* at91EthPollReceive - receive packet in polled mode** RETURNS: OK, or EAGAIN.*/STATUS at91EthPollReceive(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    M_BLK_ID pMblk                                          /* pointer to the mBlk/cluster pair */    ){    		struct at91_private *lp = (struct at91_private *) dev->priv;	PETHRBD pRbd = lp->dlist;	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;	int index = lp->rxBuffIndex;	char* pBuf =(char*)( pRbd->descriptors[index].addr&0xfffffffc);    /* Get the first available RBD. */    /*pRbd = at91EthRbdGet(dev);*/    			    /* If no RBD is available, retry it later. */    if (pRbd == NULL)    {        return EAGAIN;    }    do    {        ULONG length =  pRbd->descriptors[index].size & 0x7ff;         if (length == 0)        {            break;        }        /* If buffer is not large enough, we do not copy the received buffer. */        if ((ULONG)pMblk->mBlkHdr.mLen < length)        {            printf("eth%d Error: Too small Rx mBlk, %d\n", dev->unit, pMblk->mBlkHdr.mLen);            break;        }#ifdef  DEBUG_TRACE        at91EthHexDump((UCHAR *)(pBuf + SIZE_ETH_WA), length);#endif  /* DEBUG_TRACE */        /* Up-date statistics. */        dev->MIB2TBL.ifInOctets += length;        if (((UINT8 *)(pBuf + SIZE_ETH_WA))[0] & 0x01)        {            dev->MIB2TBL.ifInNUcastPkts += 1;        }        else        {            dev->MIB2TBL.ifInUcastPkts += 1;        }        /* Set up the mBlk properly. */        pMblk->mBlkHdr.mFlags  |= M_PKTHDR;        pMblk->mBlkHdr.mLen     = length;        pMblk->mBlkPktHdr.len   = length;        /* Copy data. */        bcopy((char *)(pBuf + SIZE_ETH_WA), (char *)pMblk->mBlkHdr.mData, length);        /* Free the used RBD. */        at91EthRbdFree(dev, pRbd);        return OK;    } while (FALSE);    /* Up-date statistics. */    dev->MIB2TBL.ifInErrors++;    /* Free the used RBD. */    at91EthRbdFree(dev, pRbd);    return EAGAIN;}/********************************************************************************* at91EthPollSend - send packet in polled mode** RETURNS: OK, or EAGAIN.*/STATUS at91EthPollSend(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    M_BLK_ID pMblk                                          /* pointer to the mBlk/cluster pair */    ){    ULONG length;    unsigned char* pBuf = 0;	AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;	struct at91_private *lp = (struct at91_private *) dev->priv;	    if (!(regs->EMAC_TSR & AT91C_EMAC_BNQ)) return ERROR;    #ifdef  DEBUG_TRACE        printf("eth%d PollSend, 0x%08X\n", unit, (UINT32)pMblk->mBlkHdr.mData);#endif  /* DEBUG_TRACE */    length = pMblk->mBlkPktHdr.len;    /* Check frame length. */    if ((length <= SIZE_ETH_HDR) || (length > SIZE_ETH_MFLR))    {        /* Up-date statistics. */        dev->MIB2TBL.ifOutErrors++;        return ERROR;    }    pBuf = at91EthTbdGet(dev);    do    {        /* Copy data but do not free the Mblk. */        length = (ULONG)netMblkToBufCopy(pMblk, (char *)(pBuf + SIZE_ETH_WA), NULL);#ifdef  DEBUG_TRACE        at91EthHexDump((UCHAR *)(pBuf + SIZE_ETH_WA), length);#endif  /* DEBUG_TRACE */        /* Start transmit. */        at91EthTbdStart(dev, pBuf, length);        /* Check if completed. */        if (at91EthTbdCheck(dev, pBuf) == OK)        {            /* Up-date statistics. */            dev->MIB2TBL.ifOutOctets += (ULONG)length;            if (((UINT8 *)(pBuf + SIZE_ETH_WA))[0] & 0x01)            {                dev->MIB2TBL.ifOutNUcastPkts += 1;            }            else            {                dev->MIB2TBL.ifOutUcastPkts += 1;            }            /* Free the used TBD. */            at91EthTbdFree(dev, pBuf);            return OK;        }    } while (FALSE);    /* Up-date statistics. */    dev->MIB2TBL.ifOutErrors++;    /* Free the used TBD. */    at91EthTbdFree(dev, pBuf);    return EAGAIN;}/********************************************************************************* at91EthRbdProcess - porcess a RBD** RETURNS : N/A*/void at91EthRbdProcess(    ETH_DRV_CTRL *dev,                                 /* pointer to driver structure */    PETHRBD pRbd                                            /* pointer to the RBD */    ){    M_BLK_ID     pMblk = NULL;    char        *pNewCluster = NULL;     int index = dev->priv->rxBuffIndex;    CL_BLK_ID    pClBlk = NULL;    char        *pData ;    UINT32       len   ;    while ( (pRbd->descriptors[index].addr & EMAC_DESC_DONE))    {#ifdef  DEBUG_TRACE    printf(" RxHandler, index = %d, addr=%x \n", index,pRbd->descriptors[index].addr);#endif  /* DEBUG_TRACE */	pData  = (char*)(pRbd->descriptors[index].addr&0xfffffffc);   	len  =  (pRbd->descriptors[index].size & 0x7ff);#ifdef  DEBUG_TRACE        at91EthHexDump((UCHAR *)(pData + SIZE_ETH_WA), len);#endif  	   	if (dev->endObj.pNetPool == NULL)   	 {  	  DEBUG_LOG (DRV_DEBUG_RX, "at91EndRecv: Illegal pNetPool on entry!\n",             0,0,0,0,0,0);  	 END_ERR_ADD (&dev->endObj, MIB2_IN_ERRS, +1);  	  goto cleanRXD; 	   }    /* Add one to our unicast data. */    END_ERR_ADD (&dev->endObj, MIB2_IN_UCAST, +1);    if ((pMblk = mBlkGet (dev->endObj.pNetPool, M_DONTWAIT, MT_DATA))        == NULL)        {        DEBUG_LOG (DRV_DEBUG_RX, "at91EndRecv: Out of M Blocks!\n",                 0,0,0,0,0,0);        END_ERR_ADD (&dev->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    pNewCluster = netClusterGet (dev->endObj.pNetPool,                                 dev->endObj.pNetPool->clTbl[0]);    if (pNewCluster == NULL)        {        DEBUG_LOG (DRV_DEBUG_RX, "sngks32cEndRecv: Cannot loan!\n",                 0,0,0,0,0,0);        dev->lastError.errCode = END_ERR_NO_BUF;        muxError(&dev->endObj, &dev->lastError);        goto cleanRXD;        }        	memcpy(pNewCluster+2,pData,len);    /* Grab a cluster block to marry to the cluster we received. */    if ((pClBlk = netClBlkGet (dev->endObj.pNetPool, M_DONTWAIT)) == NULL)

⌨️ 快捷键说明

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