⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qdinit.c

📁 Mavell AP32 无线模块驱动。VxWorks BSP BootRom源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************* 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 + -