📄 at91eth.c
字号:
*/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 */#if 0 /* 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)); }#else if (pBuf == NULL) { printf("\nat91EthTbdFree pBuf :NULL\n"); return; /*netClFree(dev->endObj.pNetPool, (UCHAR *)(pBuf - (SIZE_ETH_FB_HDR - 4)));*/ } netClFree(dev->endObj.pNetPool, (UCHAR *)(pBuf));#endif /* 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* gpBuf=0;*/ UINT8 dev_TxBuffIndex = 0; AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr; if (!(regs->EMAC_TSR & AT91C_EMAC_BNQ)) { printf("\neth%d Tx NO BNQ",dev->unit); return ERROR; }#ifdef DEBUG_TRACE printf("eth%d Send, 0x%08X\n", unit, (UINT32)pMblk->mBlkHdr.mData);#endif /* DEBUG_TRACE */ if (dev->bTxBlocked) { printf("\neth%d TxBlocked",dev->unit); /* Retry later. */ return END_ERR_BLOCK; } if (dev->bPolling) { printf("\neth%d bPolling",dev->unit); return ERROR; } length = pMblk->mBlkPktHdr.len; /* Check frame length. */ if ((length <= SIZE_ETH_HDR) || (length > SIZE_ETH_MFLR)) { printf("\neth%d frame length ERROR",dev->unit); /* Up-date statistics. */ dev->MIB2TBL.ifOutErrors++; netMblkClChainFree(pMblk); return ERROR; }#if 0 if(gpBuf == NULL) { /*pBuf = at91EthTbdGet(dev);*/ if((gpBuf = at91EthTbdGet(dev)) == NULL) {#if 0 logMsg("\nat91EthTbdGet the NULL pBuf",0,0,0,0,0,0);#else printf("@");#endif netMblkClChainFree(pMblk); return ERROR; } }#endif#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 dev_TxBuffIndex = ((dev->TxBuffIndex) < MAX_TX_DESCR - 1)?((dev->TxBuffIndex) + 1):(0);/*DEBUG_END_TRACE*/ if(dev_TxBuffIndex != (dev->TxBuffLastIndex)) { /* Copy data. */ /*dev->bTxHandler = TRUE;*/ if((dev->pTxBuffAddr[dev->TxBuffIndex]) == NULL) { printf("\npTxBuffAddr[%d]:null",dev->TxBuffIndex); netMblkClChainFree(pMblk); return ERROR; }#ifdef DEBUG_END_TRACE printf("\nEthSend:dev->pTxBuffAddr[%d]:%x",dev->TxBuffIndex,(UINT32)dev->pTxBuffAddr[dev->TxBuffIndex]);#endif length = netMblkToBufCopy(pMblk, (char *)(dev->pTxBuffAddr[dev->TxBuffIndex] + SIZE_ETH_WA), NULL); } else { printf("\ndev->TxBuffIndex + 1 == dev->TxBuffLastIndex"); netMblkClChainFree(pMblk); return ERROR; } /* Bump the statistic counter. */ END_ERR_ADD (&dev->endObj, MIB2_OUT_UCAST, +1); /* Free the Mblk. */ netMblkClChainFree(pMblk);#ifdef DEBUG_TRACE at91EthHexDump((UCHAR *)(dev->pTxBuffAddr[dev->TxBuffIndex] + SIZE_ETH_WA), length);#endif /* DEBUG_TRACE */ /* Start transmit. */ at91EthTbdStart(dev, dev->pTxBuffAddr[dev->TxBuffIndex], length); dev->TxBuffIndex = ((dev->TxBuffIndex) < (MAX_TX_DESCR - 1))?((dev->TxBuffIndex) + 1):(0);/*DEBUG_END_TRACE*/ 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; } CACHE_DMA_INVALIDATE(pNewCluster+2, len); memcpy(pNewCluster+2,pData,len); CACHE_DMA_FLUSH(pNewCluster+2, len); /* Grab a cluster block to marry to the cluster we received. */ if ((pClBlk = netClBlkGet (dev->endObj.pNetPool, M_DONTWAIT)) == NULL) { DEBUG_LOG (DRV_DEBUG_RX, "at91EndRecv: Out of Cluster Blocks!\n", 0,0,0,0,0,0); dev->lastError.errCode = END_ERR_NO_BUF; muxError(&dev->endObj, &dev->lastError);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -