📄 at91eth.c
字号:
{ 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); goto cleanRXD; } END_ERR_ADD (&dev->endObj, MIB2_IN_UCAST, +1); /* Note: we rely on the hardware to pad 2 bytes so we don't need to copy to * a new buffer to solve alignment problems */ /* Join the cluster to the MBlock */ if (netClBlkJoin (pClBlk, pNewCluster, SIZE_ETH_MDMA, NULL, 0, 0, 0) == NULL) { DEBUG_LOG (DRV_DEBUG_RX, "at91EndRecv: netClBlkJoin failed\n", 0,0,0,0,0,0); dev->lastError.errCode = END_ERR_NO_BUF; muxError(&dev->endObj,&dev->lastError); goto cleanRXD; } if (netMblkClJoin (pMblk, pClBlk) == NULL) { DEBUG_LOG (DRV_DEBUG_RX, "at91EndRecv: netMblkClJoin failed\n", 0,0,0,0,0,0); dev->lastError.errCode = END_ERR_NO_BUF; muxError(&dev->endObj, &dev->lastError); goto cleanRXD; } /* The ip structure is 14 bytes from the beginning of the valid frame data * yet it must be aligned on a word boundary. We have told the ethernet * controller to insert 2 bytes of garbage at the beginning of each frame * so now all we need to do is move our pointer to the frame data to the * real start of the frame causing the frame to be half-word aligned but * not word aligned. By counting 14 bytes from the beginning of the frame * to the ip, we arrive on a word boundary. */ pMblk->mBlkHdr.mData += SIZE_ETH_WA; pMblk->mBlkHdr.mData+=2; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mLen = len; pMblk->mBlkPktHdr.len = len; /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&dev->endObj, pMblk); /* pRxD->rxFrameData.frameDataPtr = (UINT32)pNewCluster;*/ /* Free the used RBD. */ at91EthRbdFree(dev, pRbd); index = dev->priv->rxBuffIndex; } return;cleanRXD: /* Free the used RBD. */ at91EthRbdFree(dev, pRbd); if (pClBlk != NULL) { netClBlkFree (dev->endObj.pNetPool, pClBlk); }/* if (pNewCluster != NULL) { netClFree (dev->endObj.pNetPool, pNewCluster); pNewCluster = NULL; }*/ if (pMblk != NULL) { netMblkFree (dev->endObj.pNetPool, pMblk); } END_ERR_ADD (&dev->endObj, MIB2_IN_ERRS, +1); #if 0 ULONG length; int index = dev->priv->rxBuffIndex; unsigned char* pBuf = pRbd->recv_buf[index]; /* length = at91EthRbdCheck(dev, pRbd);*/ length = pRbd->descriptors[index].size & 0x7ff; if (length == 0) { /* Up-date statistics. */// dev->MIB2TBL.ifInErrors++; END_ERR_ADD (&dev->endObj, MIB2_IN_ERRS, +1); } else {#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; }*/ /* Add one to our unicast data. */ END_ERR_ADD (&dev->endObj, MIB2_IN_UCAST, +1); if (dev->pClPool) { M_BLK_ID pMblk; CL_BLK_ID pClBlk; char *pBuf; if (dev->pClPool->clNumFree > (NUM_TBD_ETH / 8)) { pMblk = netMblkGet(dev->endObj.pNetPool, M_DONTWAIT, MT_DATA); pClBlk = netClBlkGet(dev->endObj.pNetPool, M_DONTWAIT); END_TX_SEM_TAKE(&dev->endObj, WAIT_FOREVER); pBuf = netClusterGet(dev->endObj.pNetPool, dev->pClPool); END_TX_SEM_GIVE(&dev->endObj); } else {#ifdef DEBUG_TRACE printf("at91Eth Error: no cluster buffer for the Rx\n");#endif /* DEBUG_TRACE */ pMblk = NULL; pClBlk = NULL; pBuf = NULL; } if ((!pMblk) || (!pClBlk) || (!pBuf)) { /* Up-date statistics. */ dev->MIB2TBL.ifInDiscards++; if (pMblk) { netMblkFree(dev->endObj.pNetPool, pMblk); }#ifdef DEBUG_TRACE else { printf("eth%d Error: failed to allocate M_BLK\n", dev->unit); }#endif /* DEBUG_TRACE */ if (pClBlk) { netClBlkFree(dev->endObj.pNetPool, pClBlk); }#ifdef DEBUG_TRACE else { printf("eth%d Error: failed to allocate CL_BLK\n", dev->unit); }#endif /* DEBUG_TRACE */ if (pBuf) { netClFree(dev->endObj.pNetPool, pBuf); }#ifdef DEBUG_TRACE else { printf("eth%d Error: failed to allocate cluster buffer\n", dev->unit); }#endif /* DEBUG_TRACE */ } else { netClBlkJoin(pClBlk, (char *)(pBuf - (SIZE_ETH_FB_HDR - 4)), SIZE_ETH_MDMA, NULL, 0, 0, 0); netMblkClJoin(pMblk, pClBlk); /* Set up the mBlk properly. */ pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mData = (char *)(pBuf + SIZE_ETH_WA); pMblk->mBlkHdr.mLen = length; pMblk->mBlkPktHdr.len = length; /* Swap the buffer. */ pBuf = (pBuf + (SIZE_ETH_FB_HDR - 4)); /* Call END receive routine. */ END_RCV_RTN_CALL(&dev->endObj, pMblk); } } else if (dev->receiveRtn) { dev->receiveRtn(dev, (char *)(pBuf + SIZE_ETH_WA), length); } } /* Free the used RBD. */ at91EthRbdFree(dev, pRbd);#endif }/********************************************************************************* at91EthTbdProcess - porcess a TBD** RETURNS : N/A*/void at91EthTbdProcess( ETH_DRV_CTRL *dev, /* pointer to driver structure */ unsigned char* pBuf /* pointer to the TBD */ ){ struct at91_private *lp = (struct at91_private *) dev->priv; if (at91EthTbdCheck(dev, pBuf) == ERROR) { /* Up-date statistics. */ dev->MIB2TBL.ifOutErrors++; } else { /* Up-date statistics. */ dev->MIB2TBL.ifOutOctets += (ULONG)lp->skb_length; if (((UINT8 *)(pBuf + SIZE_ETH_WA))[0] & 0x01) { dev->MIB2TBL.ifOutNUcastPkts += 1; } else { dev->MIB2TBL.ifOutUcastPkts += 1; } } END_TX_SEM_TAKE(&dev->endObj, WAIT_FOREVER); /*pci_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, PCI_DMA_TODEVICE);*/ /* Free the used TBD. */ at91EthTbdFree(dev, lp->skb); END_TX_SEM_GIVE(&dev->endObj);}/********************************************************************************* at91EthRxHandler - Rx interrupt handler** RETURNS : N/A*/void at91EthRxHandler( ETH_DRV_CTRL *dev /* pointer to driver structure */ ){ struct at91_private *lp = (struct at91_private *) dev->priv; PETHRBD pRbd; dev->bRxHandler = FALSE; pRbd = lp->dlist; /* while (pRbd->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE)*/ { /* Get the first available RBD. */ /*pRbd = at91EthRbdGet(dev);*/ /* if (pRbd == NULL) { break; }*/ at91EthRbdProcess(dev, pRbd); } }/********************************************************************************* at91EthTxHandler - Tx interrupt handler** RETURNS : N/A*/void at91EthTxHandler( ETH_DRV_CTRL *dev /* pointer to driver structure */ ){ dev->bTxHandler = FALSE; do { END_TX_SEM_TAKE(&dev->endObj, WAIT_FOREVER); at91EthTbdProcess(dev, 0); END_TX_SEM_GIVE(&dev->endObj); } while (0); /* Restart Tx if it was blocked. */ if (dev->bTxBlocked) {#ifdef DEBUG_TRACE printf("eth%d Restart Tx\n", dev->unit);#endif /* DEBUG_TRACE */ muxTxRestart(&dev->endObj); dev->bTxBlocked = FALSE; }}/********************************************************************************* at91EthShow - display driver statstics.** RETURNS : N/A*/STATUS at91EthShow(int unit){ return OK;}/********************************************************************************* at91EthMiiShow - display MII registers.** RETURNS : N/A*/STATUS at91EthMiiShow(int unit){#if 0 ETH_DRV_CTRL *dev = (ETH_DRV_CTRL *)endFindByName(ETH_DEV_NAME, unit); UINT8 phyAddr; if (!dev) { return -1; } phyAddr = dev->phyInfo.phyAddr; at91EthMiiRead(dev, phyAddr, MII_CTRL_REG, &dev->PHYREGS.phyCtrl); at91EthMiiRead(dev, phyAddr, MII_STAT_REG, &dev->PHYREGS.phyStatus); at91EthMiiRead(dev, phyAddr, MII_PHY_ID1_REG, &dev->PHYREGS.phyId1); at91EthMiiRead(dev, phyAddr, MII_PHY_ID2_REG, &dev->PHYREGS.phyId2); at91EthMiiRead(dev, phyAddr, MII_AN_ADS_REG, &dev->PHYREGS.phyAds); at91EthMiiRead(dev, phyAddr, MII_AN_PRTN_REG, &dev->PHYREGS.phyPrtn); at91EthMiiRead(dev, phyAddr, MII_AN_EXP_REG, &dev->PHYREGS.phyExp); at91EthMiiRead(dev, phyAddr, MII_AN_NEXT_REG, &dev->PHYREGS.phyNext); at91EthMiiRead(dev, phyAddr, MII_LPA, &dev->l80225Status); printf("Standard MII register\n"); printf(" MII_CTRL_REG: 0x%04X\n", dev->PHYREGS.phyCtrl); printf(" MII_STAT_REG: 0x%04X\n", dev->PHYREGS.phyStatus); printf(" MII_PHY_ID1_REG: 0x%04X\n", dev->PHYREGS.phyId1); printf(" MII_PHY_ID2_REG: 0x%04X\n", dev->PHYREGS.phyId2); printf(" MII_AN_ADS_REG: 0x%04X\n", dev->PHYREGS.phyAds); printf(" MII_AN_PRTN_REG: 0x%04X\n", dev->PHYREGS.phyPrtn); printf(" MII_AN_EXP_REG: 0x%04X\n", dev->PHYREGS.phyExp); printf(" MII_AN_NEXT_REG: 0x%04X\n", dev->PHYREGS.phyNext); printf("PHY specific register\n"); printf(" L80225_STAT_REG: 0x%04X\n", dev->l80225Status);#endif return OK;}#ifdef DEBUG_TRACE/********************************************************************************* at91EthHexDump - dump buffer.** RETURNS : N/A*/void at91EthHexDump(UCHAR *p, ULONG l){ ULONG i; while (l) { printf("%08X: ", (UINT32)p); for (i=0; i<16; i++) { printf("%02X ", *p++); if (--l == 0) { break; } } printf("\n"); }}#endif /* DEBUG_TRACE */#ifdef INCLUDE_SEC_END#include "end/secEnd.c"#endif /* INCLUDE_SEC_END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -