?? qdinit.c
字號:
/********************************************************************************* qdInit.c** DESCRIPTION:* QD initialization module** DEPENDENCIES: Platform** FILE REVISION NUMBER:********************************************************************************/#include "qd.h"#include "armboot.h"#include <stdarg.h>#define PORTS_COUNT 7#define SMI_OP_CODE_BIT_READ 1#define SMI_OP_CODE_BIT_WRITE 0#define SMI_BUSY (1<<28)#define READ_VALID (1<<27)#define SMI_TIMEOUT_COUNTER 10000#define ETHER_SMI_REG 0x80008010typedef unsigned int SMI_REG;#define GT_LPORT_2_PORT(lport) (GT_U8)(lport & 0xff)#define GT_PORT_2_LPORT(port) (GT_32)(port & 0xff)/* Start address of ports related register. */#define PORT_REGS_START_ADDR 0x8/* Start address of global register. */#define GLOBAL_REGS_START_ADDR 0xF#define QD_REG_SWITCH_ID 0x3#define QD_REG_PORT_CONTROL 0x4#define QD_REG_PORT_VLAN_MAP 0x6#define QD_REG_PVID 0x7#define QD_REG_GLOBAL_CONTROL 0x4#define DEV_MC_RATE_PERCENT \ ( DEV_88E6021 | DEV_88E6051 | DEV_88E6052 )#define DEV_QoS \ ( DEV_88E6021 | DEV_FF_XP | DEV_FF_HG | \ DEV_88E6051 | DEV_88E6052 | DEV_88E6061 | \ DEV_88E6062 | DEV_88E6063 | DEV_FH_VPN )/* This macro is used to calculate the register's SMI *//* device address, according to the baseAddr *//* field in the Switch configuration struct. */#define CALC_SMI_DEV_ADDR(_baseAddr,_smiDevAddr) \ ((_baseAddr) + (_smiDevAddr))#define CALC_MASK(fieldOffset,fieldLen,mask) \ if((fieldLen + fieldOffset) >= 16) \ mask = (0 - (1 << fieldOffset)); \ else \ mask = (((1 << (fieldLen + fieldOffset))) - (1 << fieldOffset))/* need to check port number(_hwPort) later */#define IS_VALID_API_CALL(dev,_hwPort, _devName) \ (( (!(dev->devName & (_devName))) \ ) ? GT_NOT_SUPPORTED : GT_OK)#define SMI_READ(pData) \*pData = *(volatile unsigned int *) (ETHER_SMI_REG); \*pData = WORD_SWAP(*pData)#define SMI_WRITE(data) \*(volatile unsigned int *)(ETHER_SMI_REG) = WORD_SWAP(data)#define CPU_PORT_NUM 5//GT_SYS_CONFIG cfg;GT_QD_DEV qddev;GT_QD_DEV *qd_dev = &qddev;/******************************************************************************* bool etherReadMIIReg (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)*/GT_STATUS evFFReadMii (GT_QD_DEV* dev, unsigned int portNumber , unsigned int MIIReg, unsigned int* value){ SMI_REG smiReg; unsigned int phyAddr; unsigned int timeOut = 100; /* in 100MS units */ int i; /* first check that it is not busy */ SMI_READ (&smiReg); if (smiReg & SMI_BUSY) { for(i = 0 ; i < SMI_TIMEOUT_COUNTER; i++); do { SMI_READ (&smiReg); if (timeOut-- < 1) { return GT_FAIL; } } while (smiReg & SMI_BUSY); } /* not busy */ phyAddr = portNumber; smiReg = (phyAddr << 16) | (SMI_OP_CODE_BIT_READ << 26) | (MIIReg << 21) | SMI_OP_CODE_BIT_READ << 26; SMI_WRITE (smiReg); timeOut = 100; /* initialize the time out var again */ SMI_READ (&smiReg); if (!(smiReg & READ_VALID)) { i = 0; while (i < SMI_TIMEOUT_COUNTER) { i++; } do { SMI_READ (&smiReg); if (timeOut-- < 1 ) { return GT_FAIL; } } while (!(smiReg & READ_VALID)); } *value = (unsigned int)(smiReg & 0xffff); return GT_OK;}/****************************************************************************** * bool etherWriteMIIReg (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)*/GT_STATUS evFFWriteMii (GT_QD_DEV* dev, unsigned int portNumber , unsigned int MIIReg, unsigned int value){ SMI_REG smiReg; unsigned int phyAddr; unsigned int timeOut = 10; /* in 100MS units */ int i; /* first check that it is not busy */ SMI_READ (&smiReg); if (smiReg & SMI_BUSY) { for (i = 0 ; i < SMI_TIMEOUT_COUNTER; i++); do { SMI_READ (&smiReg); if (timeOut-- < 1) { return GT_FAIL; } } while (smiReg & SMI_BUSY); } /* not busy */ phyAddr = portNumber; smiReg = 0; /* make sure no garbage value in reserved bits */ smiReg = smiReg | (phyAddr << 16) | (SMI_OP_CODE_BIT_WRITE << 26) | (MIIReg << 21) | (value & 0xffff); SMI_WRITE (smiReg); return (GT_OK);}/******************************************************************************** hwReadPortReg** DESCRIPTION:* This function reads a switch's port register.** INPUTS:* portNum - Port number to read the register for.* regAddr - The register's address.** OUTPUTS:* data - The read register's data.** RETURNS:* GT_OK on success, or* GT_FAIL otherwise.** COMMENTS:* None.********************************************************************************/GT_STATUS hwReadPortReg( IN GT_QD_DEV *dev, IN GT_U8 portNum, IN GT_U8 regAddr, OUT GT_U16 *pData){ GT_U8 phyAddr; GT_STATUS retVal; GT_U32 u32Data; phyAddr = CALC_SMI_DEV_ADDR(dev->baseRegAddr, portNum + PORT_REGS_START_ADDR); //evFFReadMii(dev, phyAddr, regAddr,(GT_U32*) pData); retVal = evFFReadMii(dev, (unsigned int) phyAddr, (unsigned int) regAddr, (unsigned int*)&u32Data); DBG_INFO("hwReadPortReg:retVal= 0x%x.\n",retVal); DBG_INFO("Read from port(%d) register:",portNum); DBG_INFO("phyAddr 0x%x",phyAddr); DBG_INFO("regAddr 0x%x",regAddr); DBG_INFO("data 0x%x.\n",u32Data); *pData = (GT_U16)u32Data; DBG_INFO("data 0x%x.\n",*pData); return retVal;}/******************************************************************************** hwWritePortReg** DESCRIPTION:* This function writes to a switch's port register.** INPUTS:* portNum - Port number to write the register for.* regAddr - The register's address.* data - The data to be written.** OUTPUTS:* None.** RETURNS:* GT_OK on success, or* GT_FAIL otherwise.** COMMENTS:* None.********************************************************************************/GT_STATUS hwWritePortReg( IN GT_QD_DEV *dev, IN GT_U8 portNum, IN GT_U8 regAddr, IN GT_U16 data){ GT_U8 phyAddr; phyAddr = CALC_SMI_DEV_ADDR(dev->baseRegAddr, portNum + PORT_REGS_START_ADDR); DBG_INFO("Write to port(%d) register: phyAddr 0x%x, regAddr 0x%x, ", portNum,phyAddr,regAddr); DBG_INFO("data 0x%x.\n",data); return evFFWriteMii(dev,phyAddr,regAddr,data);}GT_STATUS phyPatch(GT_QD_DEV *dev){ GT_U32 u32Data; /* * Set Bit2 of Register 29 of any phy */ if(evFFReadMii(dev, (unsigned int)dev->baseRegAddr,(unsigned int)29,(unsigned int*)&u32Data) != GT_OK) { return GT_FAIL; } if(evFFWriteMii(dev,(unsigned int)dev->baseRegAddr,(unsigned int)29,(GT_U16)u32Data|0x4) != GT_OK) { return GT_FAIL; } /* * ReSet Bit6 of Register 30 of any phy */ if(evFFReadMii(dev,(unsigned int)dev->baseRegAddr,(unsigned int)30,(unsigned int*)&u32Data) != GT_OK) { return GT_FAIL; } if(evFFWriteMii(dev,(unsigned int)dev->baseRegAddr,(unsigned int)30,(GT_U16)u32Data&(~0x40)) != GT_OK) { return GT_FAIL; } return GT_OK;}/******************************************************************************** hwSetPortRegField** DESCRIPTION:* This function writes to specified field in a switch's port register.** INPUTS:* portNum - Port number to write the register for.* regAddr - The register's address.* fieldOffset - The field start bit index. (0 - 15)* fieldLength - Number of bits to write.* data - Data to be written.** OUTPUTS:* None.** RETURNS:* GT_OK on success, or* GT_FAIL otherwise.** COMMENTS:* 1. The sum of fieldOffset & fieldLength parameters must be smaller-* equal to 16.********************************************************************************/GT_STATUS hwSetPortRegField( IN GT_QD_DEV *dev, IN GT_U8 portNum, IN GT_U8 regAddr, IN GT_U8 fieldOffset, IN GT_U8 fieldLength, IN GT_U16 data){ GT_U16 mask; GT_U16 tmpData; if(hwReadPortReg(dev,portNum,regAddr,&tmpData) != GT_OK) return GT_FAIL; CALC_MASK(fieldOffset,fieldLength,mask); /* Set the desired bits to 0. */ tmpData &= ~mask; /* Set the given data into the above reset bits. */ tmpData |= ((data << fieldOffset) & mask); DBG_INFO("Write to port(%d) register: regAddr 0x%x, ", portNum,regAddr); DBG_INFO("fieldOff %d, fieldLen %d, data 0x%x.\n",fieldOffset, fieldLength,data); return hwWritePortReg(dev,portNum,regAddr,tmpData);}/******************************************************************************** gstpSetPortState** DESCRIPTION:* This routine set the port state.** INPUTS:* port - the logical port number.* state - the port state to set.** OUTPUTS:* None.** RETURNS:* GT_OK - on success* GT_FAIL - on error** COMMENTS:*** GalTis:********************************************************************************/GT_STATUS gstpSetPortState( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_PORT_STP_STATE state){ GT_U8 phyPort; /* Physical port */ GT_U16 data; /* Data to write to register. */ GT_STATUS retVal; /* Functions return value. */ DBG_INFO("gstpSetPortState Called.\n"); phyPort = GT_LPORT_2_PORT(port); data = state; /* Set the port state bits. */ retVal= hwSetPortRegField(dev,phyPort, QD_REG_PORT_CONTROL,0,2,data); if(retVal != GT_OK) { DBG_INFO("Failed.\n"); return retVal; } DBG_INFO("OK.\n"); return GT_OK;}/******************************************************************************** qdLoadDriver** DESCRIPTION:* QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck* device. This pointer (*dev) is then used for all the API functions. ** INPUTS:* cfg - Holds device configuration parameters provided by system software.** OUTPUTS:* dev - Holds device information to be used for each API call.** RETURNS:* GT_OK - on success* GT_FAIL - on error* GT_ALREADY_EXIST - if device already started* GT_BAD_PARAM - on bad parameters** COMMENTS:* qdUnloadDriver is also provided to do driver cleanup.********************************************************************************/GT_STATUS qdLoadDriver( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev){ GT_STATUS retVal; GT_U16 deviceId; //GT_BOOL highSmiDevAddr; //GT_U32 portsCount; DBG_INFO("qdLoadDriver Called.\n"); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO("Failed.\n"); return GT_BAD_PARAM; } /* Check for parameters validity */ /* The initialization was already done. */ /* Initialize the driver */ //retVal = driverConfig(dev); //////////driverConfig(dev); //DBG_INFO("highSmiDevAddr=%x\n",highSmiDevAddr); dev->baseRegAddr = 0x10;//(highSmiDevAddr)?0x10:0; if(hwReadPortReg(dev,1,QD_REG_SWITCH_ID,&deviceId) != GT_OK) { return GT_FAIL; }; /* Init the device's config struct. */ dev->deviceId = deviceId >> 4; dev->revision = (GT_U8)deviceId & 0xF; DBG_INFO("driverConfig:Device ID = %x\n", dev->deviceId); /* Get the number of active ports */ dev->numOfPorts = PORTS_COUNT;//(GT_U8)portsCount; DBG_INFO("Device ID = %x\n", dev->deviceId); /* Initialize dev fields. */ //dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; /* Assign Device Name */ switch(dev->deviceId) { case GT_88E6021: case GT_88E6051: case GT_88E6052: case GT_88E6060: case GT_88E6061: case GT_88E6062: case GT_88E6063: case GT_FH_VPN_L: case GT_FH_VPN: case GT_FF_XP: case GT_FF_EG: case GT_FF_HG: break; default: DBG_INFO("Unknown Device. Initialization failed\n"); dev = NULL; return GT_FAIL; } /* Initialize the ATU semaphore. */ /* Initialize the ports states. */ //if(cfg->initPorts == GT_TRUE) //{ //retVal = gstpSetMode(dev,GT_FALSE); /////////////////////gstpSetMode{ GT_U8 i; DBG_INFO("gstpSetMode Called.\n"); /* Set the STP state in the relevant register. */ for(i = 0; i < MAX_SWITCH_PORTS; i++) { retVal = gstpSetPortState(dev,i,GT_PORT_FORWARDING); if(retVal != GT_OK) { DBG_INFO("Failed.\n"); return retVal; } } dev->stpMode = 2; if(retVal == GT_OK) DBG_INFO("OK.\n"); else DBG_INFO("Failed.\n"); return retVal; retVal = GT_OK;}/////////////////////gstpSetMode //}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -