📄 ethernet.c
字号:
PORT_REG_READ(PORT_CONFIG_REG, ðConfigReg); ethConfigReg &= ~value; PORT_REG_WRITE(PORT_CONFIG_REG, ethConfigReg); return;}/****************************************************************************** * bool ethReadMibCounters (ETH_MIB_COUNTERS* mibCountersSt* ,unsigned int portNumber)* * Description* This function will read the MIB counters.* Inputs* portNumber - one of the 2 possiable Ethernet ports (0-1).* Outputs* mibCountersSt - pointer to struct with all the MIB counters.* Returns Value* true if success.*/ETH_STATUS ethReadMibCounters (ETH_PORT_INFO *pEthPortCtrl, ETH_MIB_COUNTERS *mibCounters){ int i = 0; for(; i < (MIB_COUNTER_END - MIB_COUNTER_BASE); i += sizeof(unsigned int) ) { PORT_REG_READ ((pEthPortCtrl->portBaseAddr + MIB_COUNTER_BASE + i), (unsigned int*)(mibCounters + i)); } return ETH_OK;}/******************************************************************************* bool phyReadReg (unsigned int portNumber , unsigned int MIIReg,* unsigned int* value)** Description* This function will access the MII registers and will read the value of* the MII register , and will retrieve the value in the pointer.* Inputs* portNumber - one of the 2 possiable Ethernet ports (0-1).* MIIReg - the MII register offset.* Outputs* value - pointer to unsigned int which will receive the value.* Returns Value* true if success.* false if fail to make the assignment.* Error types (and exceptions if exist)*/ETH_STATUS phyReadReg (ETH_PORT_NUM portNum, int phyAddr, int phyReg, short *retVal){ unsigned int regData; int ix; /* first check that it is not busy */ for(ix = 0 ; ix < SMI_TIMEOUT ; ix++) { ETH_REG_READ(ETH_SMI_REG, ®Data); if(!(regData & SMI_BUSY)) /* Phy not busy, break */ break; } if(ix == SMI_TIMEOUT) { DRV_PRINT (DRV_DEBUG_START, ("TimeOut Passed Phy is busy\n")); return ETH_ERROR; } /* Phase 1: Write the read commend */ /* Prepare the SMI register data that performs the read */ regData = (phyAddr << 16) | (phyReg << 21) | SMI_READ_OPCODE; /* Perform write to SMI */ ETH_REG_WRITE(ETH_SMI_REG, regData); /* Phase 2: Read the SMI results */ for(ix = 0 ; ix < SMI_TIMEOUT ; ix++) { ETH_REG_READ(ETH_SMI_REG, ®Data); if(regData & SMI_READ_VALID) /* Phy data ready, break */ break; } if(ix == SMI_TIMEOUT) { DRV_PRINT (DRV_DEBUG_START, ("TimeOut. Read is not valid\n")); return ETH_ERROR; } *retVal = (short)regData; return ETH_OK;}/****************************************************************************** * bool phyWriteReg (unsigned int portNumber , unsigned int MIIReg,* unsigned int value)* * Description* This function will access the MII registers and will write the value* to the MII register.* Inputs* portNumber - one of the 2 possiable Ethernet ports (0-1).* MIIReg - the MII register offset.* value -the value that will be written.* Outputs* Returns Value* true if success.* false if fail to make the assignment.* Error types (and exceptions if exist)*/ETH_STATUS phyWriteReg (ETH_PORT_NUM portNum, int phyAddr, int phyReg, short value){ unsigned int regData; int ix; /* first check that it is not busy */ for(ix = 0 ; ix < SMI_TIMEOUT ; ix++) { ETH_REG_READ(ETH_SMI_REG, ®Data); if(!(regData & SMI_BUSY)) /* Phy not busy, break */ break; } if(ix == SMI_TIMEOUT) { DRV_PRINT (DRV_DEBUG_START, ("TimeOut Passed Phy is busy\n")); return ETH_ERROR; } /* Prepare the SMI register data that performs the read */ regData = (phyAddr << 16) | (phyReg << 21) | SMI_WRITE_OPCODE | value; ETH_REG_WRITE(ETH_SMI_REG, regData); return ETH_OK;}/******************************************************************************** etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.** DESCRIPTION:* This function prepares a Rx chained list of descriptors and packet * buffers in a form of a ring. The routine must be called after port * initialization routine and before port start routine. * The Ethernet SDMA engine uses CPU bus addresses to access the various * devices in the system (i.e. DRAM). This function uses the ethernet * struct 'virtual to physical' routine (set by the user) to set the ring * with physical addresses.** INPUT:* ETH_PORT_INFO *pEthPortCtrl Ethernet Port Control srtuct. * ETH_QUEUE rxQueue Number of Rx queue.* int rxDescNum Number of Rx descriptors* int rxBuffSize Size of Rx buffer* unsigned int rxDescBaseAddr Rx descriptors memory area base addr.* unsigned int rxBuffBaseAddr Rx buffer memory area base addr.** OUTPUT:* The routine updates the Ethernet port control struct with information * regarding the Rx descriptors and buffers.** RETURN:* false if the given descriptors memory area is not aligned according to* Ethernet SDMA specifications.* true otherwise.********************************************************************************/ETH_STATUS etherInitRxDescRing(ETH_PORT_INFO *pEthPortCtrl, ETH_PORT_RX_QUEUE rxQueue, int rxDescNum, int rxBuffSize, unsigned int rxDescBaseAddr, unsigned int rxBuffBaseAddr){ ETH_RX_DESC *pRxDesc; ETH_RX_DESC *pRxPrevDesc; /* pointer to link with the last descriptor */ unsigned int bufferAddr; int ix; /* a counter */ pRxDesc = (ETH_RX_DESC*)rxDescBaseAddr; pRxPrevDesc = pRxDesc; bufferAddr = rxBuffBaseAddr; /* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */ if (rxBuffBaseAddr & 0xF) return ETH_ERROR; /* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes */ if ((rxBuffSize < 8) || (rxBuffSize > RX_BUFFER_MAX_SIZE)) return ETH_ERROR; /* Rx buffers must be 64-bit aligned. */ if ((rxBuffBaseAddr + rxBuffSize) & 0x7) return ETH_ERROR; /* initialize the Rx descriptors ring */ for (ix = 0; ix < rxDescNum; ix++) { pRxDesc->bufSize = rxBuffSize; pRxDesc->byteCnt = 0x0000; pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_ENABLE_INTERRUPT; pRxDesc->nextDescPtr = pEthPortCtrl->portVirtToPhys((unsigned int)pRxDesc) + RX_DESC_ALIGNED_SIZE; pRxDesc->bufPtr = pEthPortCtrl->portVirtToPhys(bufferAddr); pRxDesc->returnInfo = 0x00000000; D_CACHE_FLUSH_LINE (pRxDesc, 0); bufferAddr += rxBuffSize; pRxPrevDesc = pRxDesc; pRxDesc = (ETH_RX_DESC*)((unsigned int)pRxDesc + RX_DESC_ALIGNED_SIZE); } /* Closing Tx descriptors ring */ pRxPrevDesc->nextDescPtr = pEthPortCtrl->portVirtToPhys(rxDescBaseAddr); D_CACHE_FLUSH_LINE (pRxPrevDesc, 0); /* Save Rx desc pointer to driver struct. */ CURR_RFD_SET ((ETH_RX_DESC*)rxDescBaseAddr, rxQueue); USED_RFD_SET ((ETH_RX_DESC*)rxDescBaseAddr, rxQueue); pEthPortCtrl->pRxDescAreaBase[rxQueue] = (ETH_RX_DESC*)rxDescBaseAddr; pEthPortCtrl->rxDescAreaSize[rxQueue] = rxDescNum * RX_DESC_ALIGNED_SIZE; return ETH_OK;}/******************************************************************************** etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.** DESCRIPTION:* This function prepares a Tx chained list of descriptors and packet * buffers in a form of a ring. The routine must be called after port * initialization routine and before port start routine. * The Ethernet SDMA engine uses CPU bus addresses to access the various * devices in the system (i.e. DRAM). This function uses the ethernet * struct 'virtual to physical' routine (set by the user) to set the ring * with physical addresses.** INPUT:* ETH_PORT_INFO *pEthPortCtrl Ethernet Port Control srtuct. * ETH_QUEUE txQueue Number of Tx queue.* int txDescNum Number of Tx descriptors* int txBuffSize Size of Tx buffer* unsigned int txDescBaseAddr Tx descriptors memory area base addr.* unsigned int txBuffBaseAddr Tx buffer memory area base addr.** OUTPUT:* The routine updates the Ethernet port control struct with information * regarding the Tx descriptors and buffers.** RETURN:* false if the given descriptors memory area is not aligned according to* Ethernet SDMA specifications.* true otherwise.********************************************************************************/ETH_STATUS etherInitTxDescRing(ETH_PORT_INFO *pEthPortCtrl, ETH_PORT_TX_QUEUE txQueue, int txDescNum, int txBuffSize, unsigned int txDescBaseAddr, unsigned int txBuffBaseAddr){ ETH_TX_DESC *pTxDesc; ETH_TX_DESC *pTxPrevDesc; unsigned int bufferAddr; int ix; /* a counter */ /* save the first desc pointer to link with the last descriptor */ pTxDesc = (ETH_TX_DESC*)txDescBaseAddr; pTxPrevDesc = pTxDesc; bufferAddr = txBuffBaseAddr; /* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */ if (txBuffBaseAddr & 0xF) return ETH_ERROR; /* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes */ if (txBuffSize > TX_BUFFER_MAX_SIZE) return ETH_ERROR; /* Initialize the Tx descriptors ring */ for (ix = 0; ix < txDescNum; ix++) { pTxDesc->byteCnt = 0x0000; pTxDesc->shadow = 0x0000; pTxDesc->cmdSts = 0x00000000; pTxDesc->nextDescPtr = pEthPortCtrl->portVirtToPhys((unsigned int)pTxDesc) + TX_DESC_ALIGNED_SIZE; pTxDesc->bufPtr = pEthPortCtrl->portVirtToPhys(bufferAddr); pTxDesc->returnInfo = 0x00000000; D_CACHE_FLUSH_LINE (pTxDesc, 0); bufferAddr += txBuffSize; pTxPrevDesc = pTxDesc; pTxDesc = (ETH_TX_DESC*)((unsigned int)pTxDesc + TX_DESC_ALIGNED_SIZE); } /* Closing Tx descriptors ring */ pTxPrevDesc->nextDescPtr = pEthPortCtrl->portVirtToPhys(txDescBaseAddr); D_CACHE_FLUSH_LINE (pTxPrevDesc, 0); /* Set Tx desc pointer in driver struct. */ CURR_TFD_SET ((ETH_TX_DESC*)txDescBaseAddr, txQueue); USED_TFD_SET ((ETH_TX_DESC*)txDescBaseAddr, txQueue); /* Init Tx ring base and size parameters */ pEthPortCtrl->pTxDescAreaBase[txQueue] = (ETH_TX_DESC*)txDescBaseAddr; pEthPortCtrl->txDescAreaSize[txQueue] = (txDescNum * TX_DESC_ALIGNED_SIZE); return ETH_OK; }/******************************************************************************** ethPortSend - Send an Ethernet packet** DESCRIPTION:* This routine send a given packet described by pPktinfo parameter. It * supports transmitting of a packet spaned over multiple buffers. The * routine updates 'curr' and 'first' indexes according to the packet * segment passed to the routine. In case the packet segment is first, * the 'first' index is update. In any case, the 'curr' index is updated. * If the routine get into Tx resource error it assigns 'curr' index as * 'first'. This way the function can abort Tx process of multiple * descriptors per packet.** INPUT:* ETH_PORT_INFO *pEthPortCtrl Ethernet Port Control srtuct. * ETH_QUEUE txQueue Number of Tx queue.* PKT_INFO *pPktInfo User packet buffer.** OUTPUT:* Tx ring 'curr' and 'first' indexes are updated. ** RETURN:* ETH_QUEUE_FULL in case of Tx resource error.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -