?? ethernet.c
字號:
/******************************************************************************** Copyright 2002, GALILEO TECHNOLOGY, LTD. ** THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. ** NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT ** OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE ** DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. ** THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, ** IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. ** ** MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, ** MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL ** SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. ** (MJKK), GALILEO TECHNOLOGY LTD. (GTL) AND GALILEO TECHNOLOGY, INC. (GTI). *********************************************************************************** ethernet.c - Marvell Fast Ethernte Controller driver** DESCRIPTION:* This file introduce low level API to Marvell's Fast Ethernet * Controller. This Fast Ethernet Controller driver API controls* 1) Operations (i.e. port init, start, reset etc').* 2) Data flow (i.e. port send, receive etc').* This driver is designed to support multiple Fast Ethernet Controllers.* The Fast Ethernet port is controlled via ETH_PORT_INFO struct.* This struct includes user configuration information as well as driver * internal data needed for its operations.* * Supported Features: * - This low level driver is OS independent. Allocating memory for the * descriptor rings and buffers are not within the scope of this driver.* - The user is free from Rx/Tx queue managing.* - This low level driver introduce functionality API that enable the * to operate Marvell's Fast Ethernet Controller in a convenient way.* - Simple Fast Ethernet port operation API.* - Simple Fast Ethernet port data flow API.* - Support cached descriptors for better performance.* - Phy access and control API.* - Port control register configuration API.* - Full control over Unicast and Multicast MAC configurations.* * Operation flow:** Initialization phase* This phase complete the initialization of the ETH_PORT_INFO struct. * User information regarding port configuration has to be set prior to * calling the port initialization routine. For example, the user has to * assign the portPhyAddr field which is board depended parameter.* In this phase any port Tx/Rx activity is halted, MIB counters are * cleared, PHY address is set according to user parameter and access to* DRAM and internal SRAM memory spaces.** Driver ring initialization* Allocating memory for the descriptor rings and buffers is not * within the scope of this driver. Thus, the user is required to allocate * memory for the descriptors ring and buffers. Those memory parameters * are used by the Rx and Tx ring initialization routines in order to * curve the descriptor linked list in a form of a ring. * Note: Pay special attention to alignment issues when using cached * descriptors/buffers. In this phase the driver stores information in the * ETH_PORT_INFO struct regarding each queue ring.** Driver start * This phase prepares the Ethernet port for Rx and Tx activity. It uses * the information stored in the ETH_PORT_INFO struct to initialize the * various port registers.** Data flow:* All packet references to/from the driver are done using PKT_INFO struct.* This struct is a unified struct used with Rx and Tx operations. * This way the user is not required to be fully familiar with neither Tx * nor Rx descriptors structures.* The driver's descriptors rings are management by indexes. Those indexes* controls the ring resources and used to indicate a SW resource error:* 'current' * This index points to the current available resource for use. For * example in Rx process this index will point to the descriptor * that will be passed to the user upon calling the receive routine.* In Tx process, this index will point to the descriptor* that will be assigned with the user packet info and transmitted.* 'used' * This index points to the descriptor that need to restore its * resources. For example in Rx process, using the Rx buffer return* API will attach the buffer returned in packet info to the descriptor * pointed by 'used'. In Tx process, using the Tx descriptor return * will merely return the user packet info with the command status of * the transmitted buffer pointed by the 'used' index. Nevertheless, it * is essential to use this routine to update the 'used' index.* 'first'* This index supports Tx Scatter-Gather. It points to the first * descriptor of a packet assembled of multiple buffers. For example * when in middle of such packet we have a Tx resource error the * 'curr' index get the value of 'first' to indicate that the ring * returned to its state before trying to transmit this packet.* * Receive operation:* The ethPortReceive API set the packet information struct, passed by the * caller, with received information from the 'current' SDMA descriptor. * It is the user responsibility to return this resource back to the Rx * descriptor ring to enable the reuse of this source. Return Rx resource * is done using the ethRxReturnBuff API.* * Transmit operation:* The ethPortSend API supports Scatter-Gather which enables to send a * packet spanned over multiple buffers. This means that for each * packet info structure given by the user and put into the Tx descriptors * ring, will be transmitted only if the 'LAST' bit will be set in the * packet info command status field. This API also consider restriction * regarding buffer alignments and sizes.* The user must return a Tx resource after ensuring the buffer has been * transmitted to enable the Tx ring indexes to update.* * BOARD LAYOUT * This device is on-board. No jumper diagram is necessary. * * EXTERNAL INTERFACE * * Prior to calling the initialization routine ethPortInit() the user must* set the following fields under ETH_PORT_INFO struct: * portNum User Ethernet port number.* portBaseAddr User PHY address of Ethernet port.* portPhyAddr User PHY address of Ethernet port.* portMacAddr[6] User defined port MAC address.* portConfig User port configuration value.* portConfigExtend User port config extend value.* portSdmaConfig User port SDMA config value.* *portVirtToPhys () User function to cast virtual addr to CPU bus addr.* *portPrivate User scratch pad for user specific data structures.* * This driver introduce a set of default values to use prior to calling* the port initialization routine:* PORT_CONFIG_VALUE Default port configuration value* PORT_CONFIG_EXTEND_VALUE Default port extend configuration value* PORT_SDMA_CONFIG_VALUE Default sdma control value** This driver data flow is done using the PKT_INFO struct which is a * unified struct for Rx and Tx operations:* byteCnt Tx/Rx descriptor buffer byte count.* cmdSts Tx/Rx descriptor command status.* bufPtr Tx/Rx descriptor buffer pointer.* returnInfo Tx/Rx user resource return information.* ** EXTERNAL SUPPORT REQUIREMENTS * * This driver requires the following external support:* * D_CACHE_FLUSH_LINE (address, address offset)* * This macro applies assembly code to flush and invalidate cache line.* address - address base. * address offset - address offset * * * CPU_PIPE_FLUSH* * This macro applies assembly code to flush the CPU pipeline.* *******************************************************************************//* includes */#include "platformTools.h"#include "ethernet.h"#include "addressTable.h"/* defines */#undef DRV_DEBUG/* Driver debug control *//* Driver debug control */#ifdef DRV_DEBUG#include <vxWorks.h>#include "private/funcBindP.h"#include "logLib.h"#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_POLL (DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define DRV_DEBUG_POLL_RX 0x0004#define DRV_DEBUG_POLL_TX 0x0008#define DRV_DEBUG_IOCTL 0x0020#define DRV_DEBUG_INT 0x0040#define DRV_DEBUG_START 0x0080#define DRV_DEBUG_DUMP 0x0100#define DRV_DEBUG_MEM 0x0200#define DRV_DEBUG_RX_ERR 0x0400#define DRV_DEBUG_ALL 0xffffint ethPortDebug = DRV_DEBUG_OFF; #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ { \ if (ethPortDebug & FLG) \ if (_func_logMsg != NULL) \ _func_logMsg (X0, X1, X2, X3, X4, X5, X6); \}#define DRV_PRINT(FLG, X) \ { \ if (ethPortDebug & FLG) printf X; \ }#else /* DRV_DEBUG */#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(FLG, X)#endif /* DRV_DEBUG *//* SDMA command macros */#define ETH_SDMA_START_TX(txQueue) \ PORT_REG_WRITE(SDMA_COMMAND_REGISTER, (1 << (23 + txQueue))) #define ETH_SDMA_STOP_TX(txQueue) \ PORT_REG_WRITE(SDMA_COMMAND_REGISTER, (1 << (16 + txQueue))) #define ETH_SDMA_ABORT_TX() \ PORT_REG_WRITE(SDMA_COMMAND_REGISTER, (1 << 31)) #define ETH_SDMA_ENABLE_RX() \ PORT_REG_WRITE(SDMA_COMMAND_REGISTER, (1 << 7)) #define ETH_SDMA_ABORT_RX() \ PORT_REG_WRITE(SDMA_COMMAND_REGISTER, (1 << 15)) #define CURR_RFD_GET(pCurrDesc, queue) \ ((pCurrDesc) = pEthPortCtrl->pRxCurrDescQ[queue])#define CURR_RFD_SET(pCurrDesc, queue) \ (pEthPortCtrl->pRxCurrDescQ[queue] = (pCurrDesc))#define USED_RFD_GET(pUsedDesc, queue) \ ((pUsedDesc) = pEthPortCtrl->pRxUsedDescQ[queue])#define USED_RFD_SET(pUsedDesc, queue) \ (pEthPortCtrl->pRxUsedDescQ[queue] = (pUsedDesc))#define CURR_TFD_GET(pCurrDesc, queue) \ ((pCurrDesc) = pEthPortCtrl->pTxCurrDescQ[queue])#define CURR_TFD_SET(pCurrDesc, queue) \ (pEthPortCtrl->pTxCurrDescQ[queue] = (pCurrDesc))#define USED_TFD_GET(pUsedDesc, queue) \ ((pUsedDesc) = pEthPortCtrl->pTxUsedDescQ[queue])#define USED_TFD_SET(pUsedDesc, queue) \ (pEthPortCtrl->pTxUsedDescQ[queue] = (pUsedDesc))#define FIRST_TFD_GET(pFirstDesc, queue) \ ((pFirstDesc) = pEthPortCtrl->pTxFirstDescQ[queue]) #define FIRST_TFD_SET(pFirstDesc, queue) \ (pEthPortCtrl->pTxFirstDescQ[queue] = (pFirstDesc)) /* Macros that save access to desc in order to find next desc pointer */#define RX_NEXT_DESC_PTR(pRxDesc, queue) \ (ETH_RX_DESC*)(((((unsigned int)pRxDesc - \ (unsigned int)pEthPortCtrl->pRxDescAreaBase[queue]) + RX_DESC_ALIGNED_SIZE)\ % pEthPortCtrl->rxDescAreaSize[queue]) + \ (unsigned int)pEthPortCtrl->pRxDescAreaBase[queue])#define TX_NEXT_DESC_PTR(pTxDesc, queue) \ (ETH_TX_DESC*)(((((unsigned int)pTxDesc - \ (unsigned int)pEthPortCtrl->pTxDescAreaBase[queue]) + TX_DESC_ALIGNED_SIZE)\ % pEthPortCtrl->txDescAreaSize[queue]) + \ (unsigned int)pEthPortCtrl->pTxDescAreaBase[queue])#define SMI_TIMEOUT 1000 /* in 100MS units *//* locals *//* Phy routines */static ETH_STATUS ethernetPhyInit(ETH_PORT_INFO *pEthPortCtrl);/* Ethernet Port routines */static ETH_STATUS ethernetAddrTableInit(ETH_PORT_INFO *pEthPortCtrl);void ethBCopy(unsigned int srcAddr, unsigned int dstAddr, int byteCount);void ethDbg(ETH_PORT_INFO *pEthPortCtrl);/******************************************************************************** ethPortInit - Initialize the Ethernet port driver** DESCRIPTION:* This function prepares the ethernet port to start its activity:* 1) Completes the ethernet port driver struct initialization toward port* start routine.* 2) Resets the device to a quiescent state in case of warm reboot.* 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.* 4) Clean MAC tables. The reset status of those tables is unknown.* 5) Set PHY address. * Note: Call this routine prior to ethPortStart routine and after setting* user values in the user fields of Ethernet port control struct (i.e.* portPhyAddr).** INPUT:* ETH_PORT_INFO *pEthPortCtrl Ethernet port control struct** OUTPUT:* See description.** RETURN:* None.********************************************************************************/void ethPortInit(ETH_PORT_INFO *pEthPortCtrl){ int queue; DRV_PRINT (DRV_DEBUG_START, ("In ethPortInit\n")); /* Zero out SW structs */ for(queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) { CURR_RFD_SET ((ETH_RX_DESC*)0x00000000, queue); USED_RFD_SET ((ETH_RX_DESC*)0x00000000, queue); pEthPortCtrl->rxResourceErr[queue] = 0; } for(queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) { CURR_TFD_SET ((ETH_TX_DESC*)0x00000000, queue); USED_TFD_SET ((ETH_TX_DESC*)0x00000000, queue); FIRST_TFD_SET((ETH_TX_DESC*)0x00000000, queue); pEthPortCtrl->txResourceErr[queue] = 0; } ethPortReset(pEthPortCtrl); DRV_PRINT (DRV_DEBUG_START, ("ethPortReset OK...\n")); ethernetAddrTableInit(pEthPortCtrl); DRV_PRINT (DRV_DEBUG_START, ("ethernetAddrTableInit OK...\n")); if(ethernetPhyInit(pEthPortCtrl) == ETH_ERROR) DRV_PRINT (DRV_DEBUG_START, ("Unknown Phy device. Default interface set to RMII\n")); DRV_PRINT (DRV_DEBUG_START, ("ethPortInit OK...\n")); return;}/******************************************************************************** ethPortStart - Start the Ethernet port activity.** DESCRIPTION:* This routine prepares the Ethernet port for Rx and Tx activity:* 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that* has been initialized a descriptor's ring (using etherInitTxDescRing * for Tx and etherInitRxDescRing for Rx)* 2. Initialize and enable the Ethernet configuration port by writing to
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -