📄 qdinit.c_orig
字号:
/********************************************************************************
* 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 + -