📄 at91eth.c
字号:
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);#if 0 printf(" RxHandler, index = %d, addr=%x \n", index,pRbd->descriptors[index].addr);#endif /* DEBUG_TRACE */ /* pRxD->rxFrameData.frameDataPtr = (UINT32)pNewCluster;*/ /* Free the used RBD. */ at91EthRbdFree(dev, pRbd); index = dev->priv->rxBuffIndex;#if 0 netMblkClChainFree(pMblk);/* netMblkClFree(pMblk); //OK*/ if (pNewCluster) { netClFree (dev->endObj.pNetPool, pNewCluster); pNewCluster = NULL; }#endif } return;cleanRXD: /* Free the used RBD. */ at91EthRbdFree(dev, pRbd); if (pClBlk != NULL) { netClBlkFree (dev->endObj.pNetPool, pClBlk); } if (pMblk != NULL) { netMblkFree (dev->endObj.pNetPool, pMblk); }/* if (pNewCluster) { netClFree (dev->endObj.pNetPool, pNewCluster); pNewCluster = NULL; }*/ END_ERR_ADD (&dev->endObj, MIB2_IN_ERRS, +1); }#if 0/********************************************************************************* AT91Recv - process the next incoming packet** RETURNS: OK/ERROR*/LOCAL STATUS AT91Recv ( AT91_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { int len; M_BLK_ID pMblk; char * pCluster; char * pBuf; CL_BLK_ID pClBlk; int rmdIndex; int oldlevel; /* current interrupt level mask */ int i; if (*AT91C_EMAC_RSR & AT91C_EMAC_RROVR) { (*AT91C_EMAC_RSR)|=AT91C_EMAC_RROVR; oldlevel = intLock (); for (i = 0; i < AT91_N_RX_BUF; i++) { tableList[i].addr &= ~0x01; } intUnlock (oldlevel); } if (*AT91C_EMAC_RSR & AT91C_EMAC_BNA) { (*AT91C_EMAC_RSR)|=AT91C_EMAC_BNA; oldlevel = intLock (); for (i = 0; i < AT91_N_RX_BUF; i++) { tableList[i].addr &= ~0x01; } intUnlock (oldlevel); } if (*AT91C_EMAC_RSR & AT91C_EMAC_REC){ for (i = 0; i < AT91_N_RX_BUF; i++) { if(tableList[i].addr & 0x1) { /* Extract packet particulators */ rmdIndex = i ;/*pDrvCtrl->rmdIndex;*/ len = tableList[rmdIndex].size ; /* get packet length */ pBuf = (char *)(tableList[rmdIndex].addr & 0xFFFFFFFC); /* If error flag OR if packet is not completely in one buffer */ if (!len) { /* DRV_LOG (DRV_DEBUG_RX, "RMD error!\n", 1, 2, 3, 4, 5, 6);*/ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); goto cleanRXD; /* skip to clean up */ } /* If we cannot get a buffer to loan then bail out. */ pCluster = netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId); if (pCluster == NULL) { DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError); goto cleanRXD; } if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL) { netClFree (pDrvCtrl->endObj.pNetPool, pCluster); /* DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);*/ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError); goto cleanRXD; } /* * OK we've got a spare, let's get an M_BLK_ID and marry it to the * one in the ring. */ if ((pMblk = mBlkGet(pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk); netClFree (pDrvCtrl->endObj.pNetPool, pCluster);/* DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);*/ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError); goto cleanRXD; } END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); CACHE_DMA_INVALIDATE(pCluster + pDrvCtrl->offset, len); bcopy (pBuf, pCluster + pDrvCtrl->offset, len); CACHE_DMA_FLUSH(pCluster + pDrvCtrl->offset, len); /* Join the cluster to the MBlock */ netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0); netMblkClJoin (pMblk, pClBlk); pMblk->mBlkHdr.mData += pDrvCtrl->offset; pMblk->mBlkHdr.mLen = len; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = len; tableList[rmdIndex].addr &= ~0x01; /* SYS_WB_FLUSH();*/ /* Advance our management index */ DRV_LOG (DRV_DEBUG_RX, "AT91Recv clean index %d %08x\n", rmdIndex, 0, 0, 0, 0, 0); /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk); } } (*AT91C_EMAC_RSR) |= AT91C_EMAC_REC; }return (OK); cleanRXD: (*AT91C_EMAC_RSR)|=AT91C_EMAC_OVR; (*AT91C_EMAC_RSR)|=AT91C_EMAC_BNA; /* SYS_WB_FLUSH();*/ (*AT91C_EMAC_RSR) |= AT91C_EMAC_REC; DRV_LOG (DRV_DEBUG_RX, "AT91Recv clean index %d \n", rmdIndex, 0, 0, 0, 0, 0); return (OK); }#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) { /* logMsg("\n",0,0,0,0,0,0);*/ /* 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); } }#if 0/********************************************************************************* 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); dev->bTxHandler = FALSE; /* Restart Tx if it was blocked. */ if (dev->bTxBlocked) { printf("eth%d Restart Tx\n", dev->unit); muxTxRestart(&dev->endObj); dev->bTxBlocked = FALSE; }}#endif/********************************************************************************* 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 "src/drv/end/secEnd.c"#endif /* INCLUDE_SEC_END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -