📄 auend.c
字号:
/* handle some user-to-physical flags */ if (!(DRV_PHY_FLAGS_ISSET (AU_USR_MII_NO_AN))) MII_PHY_FLAGS_SET (MII_PHY_AUTO); else MII_PHY_FLAGS_CLEAR (MII_PHY_AUTO); if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_AN_TBL)) MII_PHY_FLAGS_SET (MII_PHY_TBL); else MII_PHY_FLAGS_CLEAR (MII_PHY_TBL); if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_100MB)) MII_PHY_FLAGS_SET (MII_PHY_100); else MII_PHY_FLAGS_CLEAR (MII_PHY_100); if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_FD)) MII_PHY_FLAGS_SET (MII_PHY_FD); else MII_PHY_FLAGS_CLEAR (MII_PHY_FD); if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_10MB)) MII_PHY_FLAGS_SET (MII_PHY_10); else MII_PHY_FLAGS_CLEAR (MII_PHY_10); if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_HD)) MII_PHY_FLAGS_SET (MII_PHY_HD); else MII_PHY_FLAGS_CLEAR (MII_PHY_HD); if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_BUS_MON)) MII_PHY_FLAGS_SET (MII_PHY_MONITOR); else MII_PHY_FLAGS_CLEAR (MII_PHY_MONITOR); MII_PHY_FLAGS_SET (MII_PHY_PRE_INIT); DRV_LOG (DRV_DEBUG_LOAD, ("auPhyPreInit pPhyInfo = 0x%x read=0x%x write=0x%x tbl=0x%x addr=0x%x flags=0x%x \n"), (int) pDrvCtrl->pPhyInfo, (int) pDrvCtrl->pPhyInfo->phyReadRtn, (int) pDrvCtrl->pPhyInfo->phyWriteRtn, (int) pDrvCtrl->pPhyInfo->phyAnOrderTbl, (int) pDrvCtrl->pPhyInfo->phyAddr, (int) pDrvCtrl->pPhyInfo->phyFlags); return (OK); }/**************************************************************************** * auMiiRead - read a PHY device register via MII* * RETURNS: the contents of a PHY device register in retVal arg, OK always*/LOCAL STATUS auMiiRead ( AU_DRV_CTRL * pDrvCtrl, UINT8 phyAdrs, /* PHY address to access */ UINT8 phyReg, /* PHY register to read */ UINT16 * pRetVal ) { int timeout; AU_MII_CONTROL = (phyAdrs << 11) | (phyReg << 6); timeout = 20; while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY) { taskDelay (1); if (--timeout == 0) { DRV_LOG (DRV_DEBUG_MII, "PHY access timeout\n", 0, 0, 0, 0, 0, 0); return (ERROR); } } *pRetVal = AU_MII_DATA; DRV_LOG (DRV_DEBUG_MII, "auMiiRead adr=%02x reg=%02x data=%04x\n", phyAdrs, phyReg, *pRetVal, 0, 0, 0); return (OK); }/***************************************************************************** auMiiWrite - write to a PHY device register via MII** RETURNS: OK or ERROR*/LOCAL STATUS auMiiWrite ( AU_DRV_CTRL * pDrvCtrl, UINT8 phyAdrs, /* PHY address to access */ UINT8 phyReg, /* PHY register to write */ UINT16 data /* Data to write */ ) { int timeout; DRV_LOG (DRV_DEBUG_MII, "auMiiWrite adr=%02x reg=%02x data=%04x\n", phyAdrs, phyReg, data, 0, 0, 0); timeout = 20; while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY) { taskDelay (1); if (--timeout == 0) { DRV_LOG (DRV_DEBUG_MII, "PHY access timeout\n", 0, 0, 0, 0, 0, 0); return (ERROR); } } AU_MII_DATA = data; AU_MII_CONTROL = ((phyAdrs << 11) | (phyReg << 6) | AU_MII_CONTROL_WRITE); timeout = 20; while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY) { taskDelay (1); if (--timeout == 0) { DRV_LOG (DRV_DEBUG_MII, "PHY access timeout\n", 0, 0, 0, 0, 0, 0); return (ERROR); } } return (OK); }/***************************************************************************** auPhyFind - Find the first PHY.** RETURNS: Address of PHY or 0xFF if not found.*/LOCAL UINT8 auPhyFind ( AU_DRV_CTRL *pDrvCtrl ) { UINT16 miiData; UINT8 phyAddr; DRV_LOG (DRV_DEBUG_MII, "auMiiPhyFind\n", 0, 0, 0, 0, 0, 0); for (phyAddr = 0; phyAddr < (UINT8)AU_MAX_PHY; phyAddr++) { auMiiRead (pDrvCtrl, phyAddr, MII_PHY_ID0, &miiData); /* Verify PHY address read */ if ((miiData != 0xFFFF) && (miiData != 0)) /* Found PHY */ { DRV_LOG (DRV_DEBUG_MII, "PHY @ %x\n", phyAddr, 0,0,0,0,0); return (phyAddr); } } DRV_LOG (DRV_DEBUG_LOAD, "No PHY found\n", 0,0,0,0,0,0); return (0xFF); }/********************************************************************************* auStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR*/LOCAL STATUS auStart ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { STATUS result; pDrvCtrl->txCleaning = FALSE; pDrvCtrl->txBlocked = FALSE; if (auMiiInit (pDrvCtrl) == ERROR) return (ERROR); SYS_INT_CONNECT (pDrvCtrl, auInt, (int)pDrvCtrl, &result); if (result == ERROR) return ERROR; /* mark the interface as up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6); SYS_INT_ENABLE (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* auInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void auInt ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { int i; int txDone = FALSE; int rxDone = FALSE; DRV_LOG (DRV_DEBUG_INT, "auInt control=%08x rising=%08x, req0 %08x\n", AU_MAC_CONTROL, AU_INTC_RISING_EDGE_CLEAR(0), AU_INTC_REQUEST0_INT(0), 0, 0, 0); /* Acknowledge interrupt */ SYS_INT_DISABLE(pDrvCtrl); SYS_WB_FLUSH(); /* Examine receive buffers */ for (i = 0; i < pDrvCtrl->rringSize; ++i) { if (AU_RX_ADDRESS(i) & (1 << 1)) rxDone = TRUE; } /* Examine transmit buffers */ for (i = 0; i < pDrvCtrl->tringSize; ++i) { if (AU_TX_ADDRESS(i) & (1 << 1)) txDone = TRUE; } /* Have netTask handle all packets */ if (rxDone || txDone) { netJobAdd ((FUNCPTR)auHandleInt,(int)pDrvCtrl, 0, 0, 0, 0); } if (pDrvCtrl->txBlocked) { pDrvCtrl->txBlocked = FALSE; netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj, 0, 0, 0, 0); } }/********************************************************************************* auHandleInt - task level interrupt service for all packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.*/LOCAL void auHandleInt ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { /* * Handle zero or more previously transmitted frames */ while (AU_TX_ADDRESS(pDrvCtrl->tmdLastIndex) & (1<<1)) { AU_TX_ADDRESS(pDrvCtrl->tmdLastIndex) = 0; pDrvCtrl->tmdLastIndex = (pDrvCtrl->tmdLastIndex + 1) & (pDrvCtrl->tringSize - 1); } SYS_WB_FLUSH(); /* * Handle zero or more newly received frames */ while (AU_RX_ADDRESS(pDrvCtrl->rmdIndex) & (1<<1)) auRecv (pDrvCtrl); /* * Re-enable interrupts */ SYS_INT_ENABLE(pDrvCtrl); SYS_WB_FLUSH(); }/********************************************************************************* auRecv - process the next incoming packet** RETURNS: OK/ERROR*/LOCAL STATUS auRecv ( AU_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { int len; M_BLK_ID pMblk; char * pCluster; char * pBuf; CL_BLK_ID pClBlk; UINT32 status; int rmdIndex; /* Extract packet particulators */ rmdIndex = pDrvCtrl->rmdIndex; status = AU_RX_STATUS(rmdIndex); len = AU_RX_STATUS (rmdIndex) & 0x3fff; /* get packet length */ pBuf = pDrvCtrl->pRxMem[rmdIndex]; DRV_LOG (DRV_DEBUG_RX, "auRecv index = %d status = %08x len=%d\n", rmdIndex, status, len, 0, 0, 0); DRV_LOG (DRV_DEBUG_RX, "auRecv dst=%02x:%02x:%02x:%02x:%02x:%02x\n", pBuf[0]&0xff, pBuf[1]&0xff, pBuf[2]&0xff, pBuf[3]&0xff, pBuf[4]&0xff, pBuf[5]&0xff); DRV_LOG (DRV_DEBUG_RX, "auRecv src=%02x:%02x:%02x:%02x:%02x:%02x\n", pBuf[6]&0xff, pBuf[7]&0xff, pBuf[8]&0xff, pBuf[9]&0xff, pBuf[10]&0xff, pBuf[11]&0xff); /* 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); bcopy (pBuf, 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; AU_RX_STATUS(rmdIndex) = 0; AU_RX_ADDRESS(rmdIndex) = ((UINT32) AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRxMem[rmdIndex])) | 1; SYS_WB_FLUSH(); /* Advance our management index */ pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1); DRV_LOG (DRV_DEBUG_RX, "auRecv clean index %d %08x\n", rmdIndex, AU_RX_ADDRESS(rmdIndex) & 0x1f, 0, 0, 0, 0); /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk); return (OK);cleanRXD: /* Restore the receiver buffer */ AU_RX_STATUS(rmdIndex) = 0; AU_RX_ADDRESS(rmdIndex) = ((UINT32) AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRxMem[rmdIndex])) | 1; SYS_WB_FLUSH(); DRV_LOG (DRV_DEBUG_RX, "auRecv clean index %d %08x\n", rmdIndex, AU_RX_ADDRESS(rmdIndex) & 0x1f, 0, 0, 0, 0); /* Advance our management index */ pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1); return (OK); }/********************************************************************************* auSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer. The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine. ** RETURNS: OK or ERROR.*/LOCAL STATUS auSend ( AU_DRV_CTRL * pDrvCtrl, /* device to be initialized */ M_BLK_ID pMblk /* data to send */ ) { char * pBuf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -