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

📄 qdinit.c_orig

📁 Mavell AP32 无线模块驱动。VxWorks BSP BootRom源代码
💻 C_ORIG
📖 第 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			  0x80008010
typedef 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)
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -