📄 hw_api.c
字号:
/***********************************************************
hw_api.c
For OL100CR-X4X-V5, marvell witch chip 88E6095 and GE phy
88E1111
The 88E6095's port8 is fixed fiber port
port9 is connected to mcu
port10 connect to GE phy or to fiber port
************************************************************/
#include <stdio.h>
#include "MC9S12NE64.h"
#include "datatypes.h"
#include "debug.h"
#include "cli_lib.h"
#include "switchRegs.h"
#include "phy.h"
#include "timers.h"
#include "hw_api.h"
typedef struct
{
unsigned char num_components; /* # of object id components */
/* Note: this is the number of */
/* components in the object id, */
/* which is one more than the # */
/* of subidentifiers in an */
/* encoded object id.*/
unsigned long component_list[16];
}OBJ_ID_T;
extern tU08 MIIread(tU08 _mpadr, tU08 _mradr, tU16 * _mrdata);
extern tU08 MIIwrite(tU08 _mpadr, tU08 _mradr, tU16 _mwdata);
extern UINT8 hard_addr[6];
extern UINT8 localOAMPort;
extern UINT8 remoteTPLink;
extern UINT8 remoteDTEExist;
#if 1
extern UINT8 sysRunYear;
extern UINT16 sysRunDay;
extern UINT8 sysRunHour;
extern UINT8 sysRunMin;
extern UINT8 sysRunSec;
UINT8 sysLogCurrent = 0;
UINT8 sysLog[SYS_LOG_MAX][24];
#endif
UINT8 localDTEType;
UINT8 localNoamPortLnkStat;
UINT8 localOamPortLnkFault;
UINT8 locAutoCfg[MAX_PORT];
UINT8 locDuplexCfg[MAX_PORT];
UINT16 locSpeedCfg[MAX_PORT];
UINT8 locLink[MAX_PORT];
UINT8 locDuplexStat[MAX_PORT];
UINT16 locSpeedStat[MAX_PORT];
UINT8 locPortStat[MAX_PORT];
UINT8 locPwrUpFlag = 1;
UINT8 localHWVersion;
UINT8 locLFPen;
UINT8 locLFPChkDone=0;
UINT8 locLFPChkPoint;
UINT8 locFEFen;
UINT8 locLfpTimer;
UINT8 locRunLedTimer;
UINT8 locRunLedStat=0;
UINT8 trapPort1LinkUp=0;
UINT8 trapPort1LinkDown=0;
UINT8 trapPort2LinkUp=0;
UINT8 trapPort2LinkDown=0;
UINT8 gSnmpRebootFlag=0;
UINT8 gSnmpPort1Flag = 0;
UINT8 gSnmpPort2Flag = 0;
UINT8 gSnmpFlowCtrlFlag1 = 0;
UINT8 gSnmpFlowCtrlFlag2 = 0;
UINT8 bSnmpFlowCtrl1 = 0;
UINT8 bSnmpFlowCtrl2 = 0;
#if 0
/*mac addr*/
logging
active/passive
show remote time out
oam stop after remote up
link chang triger tlv, n times send
if local FR config, remote config invalid:OK
debug:OK
fix dot3ah enable/disable bug:ok
show SYSTEM:OK
port mode config:OK
statistics,rx64_127 include tx and rx:ok
run/fef led:ok
dot3ah add device type:OK
#endif
void delay(UINT16 time)
{
UINT16 i,j = 0;
for(i=0; i<time; i++)
j++;
}
/*
* Function:
* disPPU()
* Purpose:
* Disable phy polling unit
* Parameters:
* phyAddr -- mii read/write phy address
* Returns:
* Node.
* Notes:
* None.
*/
void disPPU(UINT8 phyAddr)
{
UINT16 val;
MIIread(phyAddr, QD_REG_PORT_CONTROL, &val);
val= (val & (~0x4000));
MIIwrite(phyAddr, QD_REG_PORT_CONTROL, val);
delay(400);
}
/*
* Function:
* enPPU()
* Purpose:
* Enable phy polling unit
* Parameters:
* phyAddr -- mii read/write phy address
* Returns:
* Node.
* Notes:
* None.
*/
void enPPU(UINT8 phyAddr)
{
UINT16 val;
delay(20);
MIIread(phyAddr, QD_REG_PORT_CONTROL, &val);
val = (val | (0x4000));
MIIwrite(phyAddr, QD_REG_PORT_CONTROL, val);
}
/*
* Function:
* portInvalid()
* Purpose:
* Check if the port is valid
* Parameters:
* portSrc -- port number,1-2
* portDes -- port number,8-10
* Returns:
* 1-invalid, 0-valid.
* Notes:
* None.
*/
UINT8 portInvalid(UINT8 portSrc, UINT8 *portDes)
{
switch(portSrc)
{
case 1:
*portDes = 10; /*port 10 is GMII*/
break;
case 2:
*portDes = 8; /*port 8 fixed serdes for FX*/
break;
case 3:
*portDes = 9; /*port 8 fixed serdes for FX*/
break;
default:
return 1;
break;
}
return 0;
}
/*
* Function:
* hwSetPortCfg()
* Purpose:
* Set the port auto/dplx/speed config
* Parameters:
* port -- port number,1-2
* an -- auto-negotiation, 1-enable;0-disable
* dplx -- duplex, 1-full;0-half
* spd -- speed, 1000/100/10
* Returns:
* OK or ERROR.
* Notes:
* None.
*/
UINT8 hwSetPortCfg(UINT8 port, UINT8 an, UINT8 dplx, UINT16 spd)
{
UINT8 phyAddr,portTmp;
UINT16 regVal, mii_gb_ctrl;
if(portInvalid(port,&portTmp))
return ERROR;
if(localDTEType == OL100CR_X4X_V5)
{
if(portTmp == PORT_NUM_TP)
{
disPPU(SWITCH_GLOBAL1_ADDRESS);
/*auto enable*/
if(an)
{
MIIread(EXTL_PHY_ADDRESS, MII_ANA_REG, ®Val);
MIIread(EXTL_PHY_ADDRESS, MII_GB_CTRL_REG, &mii_gb_ctrl);
if(dplx)
{
if(spd == 1000)
{
regVal |= (MII_ANA_HD_10 | MII_ANA_FD_10 | MII_ANA_HD_100 | MII_ANA_FD_100);
mii_gb_ctrl |= (MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_ADV_1000HD);
}
else if(spd == 100)
{
regVal |= (MII_ANA_HD_10 | MII_ANA_FD_10 | MII_ANA_HD_100 | MII_ANA_FD_100);
mii_gb_ctrl &= (~(MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_ADV_1000HD));
}
else
{
regVal &= (~(MII_ANA_HD_100 | MII_ANA_FD_100));
regVal |= (MII_ANA_HD_10 | MII_ANA_FD_10);
mii_gb_ctrl &= (~(MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_ADV_1000HD));
}
}
else
{
if(spd == 1000)
{
regVal |= (MII_ANA_HD_10 | MII_ANA_FD_10 | MII_ANA_HD_100 | MII_ANA_FD_100);
mii_gb_ctrl &= (~MII_GB_CTRL_ADV_1000FD);
mii_gb_ctrl |= MII_GB_CTRL_ADV_1000HD;
}
else if(spd == 100)
{
regVal &= (~MII_ANA_FD_100);
regVal |= (MII_ANA_HD_10 | MII_ANA_FD_10 | MII_ANA_HD_100);
mii_gb_ctrl &= (~(MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_ADV_1000HD));
}
else
{
regVal &= (~(MII_ANA_FD_100 | MII_ANA_FD_10 | MII_ANA_HD_100));
regVal |= MII_ANA_HD_10;
mii_gb_ctrl &= (~(MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_ADV_1000HD));
}
}
MIIwrite(EXTL_PHY_ADDRESS, MII_ANA_REG, regVal);
MIIwrite(EXTL_PHY_ADDRESS, MII_GB_CTRL_REG, mii_gb_ctrl);
/*restart auto-negotiation*/
(void)MIIread(EXTL_PHY_ADDRESS, MII_CTRL_REG, ®Val);
regVal |= (MII_CTRL_AE | MII_CTRL_RAN);
MIIwrite(EXTL_PHY_ADDRESS, MII_CTRL_REG, regVal);
}
/*auto disable*/
else
{
MIIread(EXTL_PHY_ADDRESS, MII_CTRL_REG, ®Val);
regVal &= (~MII_CTRL_AE);
regVal &= (~MII_CTRL_SS_MASK);
if(spd == 1000)
regVal |= MII_CTRL_SS_1000;
else if(spd == 100)
regVal |= MII_CTRL_SS_100;
else
regVal |= MII_CTRL_SS_10;
if(dplx)
regVal |= MII_CTRL_FD;
else
regVal &= (~MII_CTRL_FD);
MIIwrite(EXTL_PHY_ADDRESS, MII_CTRL_REG, regVal);
/*reset the phy to update the link duplex*/
MIIread(EXTL_PHY_ADDRESS, MII_CTRL_REG, ®Val);
regVal |= MII_CTRL_RESET;
MIIwrite(EXTL_PHY_ADDRESS, MII_CTRL_REG, regVal);
}
enPPU(SWITCH_GLOBAL1_ADDRESS);
locAutoCfg[port-1] = an;
locDuplexCfg[port-1] = dplx;
locSpeedCfg[port-1] = spd;
return OK;
}
}
if((dplx!= 1) || (spd!=1000))
return ERROR;
phyAddr = portTmp + 0x10;
MIIread(phyAddr, QD_REG_PCS_CONTROL, ®Val);
if(an)
regVal |= (QD_PCS_AN_ENABLE | QD_PCS_AN_RESTART);
else
regVal &= (~QD_PCS_AN_ENABLE);
MIIwrite(phyAddr, QD_REG_PCS_CONTROL, regVal);
locAutoCfg[port-1] = an;
locDuplexCfg[port-1] = dplx;
locSpeedCfg[port-1] = spd;
return OK;
}
/*
* Function:
* hwGetPortCfg()
* Purpose:
* Get the port auto/dplx/speed config
* Parameters:
* port -- port number,1-2
* an -- auto-negotiation, 1-enable;0-disable
* dplx -- duplex, 1-full;0-half
* spd -- speed, 1000/100/10
* Returns:
* OK or ERROR.
* Notes:
* None.
*/
UINT8 hwGetPortCfg(UINT8 port, UINT8 *an, UINT8 *dplx, UINT16 *spd)
{
UINT8 phyAddr, portTmp;
UINT16 regVal, mii_gb_ctrl;
if(portInvalid(port,&portTmp))
return ERROR;
if(localDTEType == OL100CR_X4X_V5)
{
if(portTmp == PORT_NUM_TP)
{
disPPU(SWITCH_GLOBAL1_ADDRESS);
MIIread(EXTL_PHY_ADDRESS, MII_CTRL_REG, ®Val);
if(regVal & MII_CTRL_AE)
{
*an = AUTO_ENABLE;
MIIread(EXTL_PHY_ADDRESS, MII_ANA_REG, ®Val);
MIIread(EXTL_PHY_ADDRESS, MII_GB_CTRL_REG, &mii_gb_ctrl);
if(mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD)
{
*dplx = DPLX_FULL;
*spd = SPEED_1000;
}
else if(mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD)
{
*dplx = DPLX_HALF;
*spd = SPEED_1000;
}
else if(regVal & MII_ANA_FD_100)
{
*dplx = DPLX_FULL;
*spd = SPEED_100;
}
else if(regVal & MII_ANA_HD_100)
{
*dplx = DPLX_HALF;
*spd = SPEED_100;
}
else if(regVal & MII_ANA_FD_10)
{
*dplx = DPLX_FULL;
*spd = SPEED_10;
}
else
{
*dplx = DPLX_HALF;
*spd = SPEED_10;
}
}
else
{
*an = AUTO_DISABLE;
if(regVal & MII_CTRL_FD)
*dplx = DPLX_FULL;
else
*dplx = DPLX_HALF;
if((regVal & MII_CTRL_SS_MASK) == MII_CTRL_SS_1000)
*spd = SPEED_1000;
else if((regVal & MII_CTRL_SS_MASK) == MII_CTRL_SS_100)
*spd = SPEED_100;
else
*spd = SPEED_10;
}
enPPU(SWITCH_GLOBAL1_ADDRESS);
return OK;
}
}
phyAddr = portTmp + 0x10;
MIIread(phyAddr, QD_REG_PCS_CONTROL, ®Val);
if(regVal & QD_PCS_AN_ENABLE)
*an = AUTO_ENABLE;
else
*an = AUTO_DISABLE;
*dplx = DPLX_FULL;
*spd = SPEED_1000;
return OK;
}
UINT32 hwRateLmtValGet(UINT32 val)
{
UINT32 tmp;
if(val!=0)
{
tmp = ((8000000 / (32 * (val))) + ((8000000 % (32 * (val)))?1:0));
return tmp;
}
else
{
return 0;
}
}
/*
* Function:
* hwSetPortRate()
* Purpose:
* Set the port TX or RX rate limit
* Parameters:
* port -- port number,1-2
* type -- rate limit type, 0-RX limit; 1-TX limit
* rate -- rate value, 0 to disable, n*64K
* Returns:
* OK or ERROR.
* Notes:
* None.
*/
UINT8 hwSetPortRate(UINT8 port, UINT8 type, UINT16 rate)
{
UINT8 phyAddr,regAddr,portTmp;
UINT16 regVal;
UINT32 rateTmp;
if(portInvalid(port,&portTmp))
return ERROR;
phyAddr = portTmp + 0x10;
rateTmp = rate;
rateTmp *= 64;
if(type == RATE_TYPE_INGRESS)
{
regAddr = QD_REG_INGRESS_RATE_CTRL;
/*set the ingress limit mode to limit all frames*/
MIIread(phyAddr, QD_REG_EGRESS_RATE_CTRL, ®Val);
regVal &= (~QD_RATECTRL_LMT_MODEf);
MIIwrite(phyAddr, QD_REG_EGRESS_RATE_CTRL, regVal);
}
else
regAddr = QD_REG_EGRESS_RATE_CTRL;
MIIread(phyAddr, regAddr, ®Val);
regVal &= (~QD_RATECTRL_LMT_RATEf);
regVal += (UINT16)(hwRateLmtValGet(rateTmp));
MIIwrite(phyAddr, regAddr, regVal);
return OK;
}
/*
* Function:
* hwGetPortRate()
* Purpose:
* Get the port TX or RX rate limit value
* Parameters:
* port -- port number,1-2
* type -- rate limit type, 0-RX limit; 1-TX limit
* rate -- rate value, 0 to disable, n*64K
* Returns:
* OK or ERROR.
* Notes:
* None.
*/
UINT8 hwGetPortRate(UINT8 port, UINT8 type, UINT16 *rate)
{
UINT8 phyAddr, regAddr, portTmp;
UINT16 regVal;
UINT32 rateTmp;
if(portInvalid(port,&portTmp))
return ERROR;
phyAddr = portTmp + 0x10;
if(type == RATE_TYPE_INGRESS)
regAddr = QD_REG_INGRESS_RATE_CTRL;
else
regAddr = QD_REG_EGRESS_RATE_CTRL;
MIIread(phyAddr, regAddr, ®Val);
if((regVal & QD_RATECTRL_LMT_RATEf) == 0)
*rate = 0;
else
{
rateTmp = (regVal & QD_RATECTRL_LMT_RATEf);
rateTmp = hwRateLmtValGet(rateTmp);
rateTmp = (rateTmp/64 + ((rateTmp%64)?1:0));
*rate = (UINT16)rateTmp;
}
return OK;
}
/*
* Function:
* hwSetPortStorm()
* Purpose:
* Set the port RX storm control limit
* Parameters:
* port -- port number,1-2
* type -- storm limit type, 0:Bcast;1:M-Bcast;2:M-B-DlfCast
* rate -- rate value, 0 to disable, n*64K
* Returns:
* OK or ERROR.
* Notes:
* None.
*/
UINT8 hwSetPortStorm(UINT8 port, UINT8 type, UINT16 rate)
{
UINT8 phyAddr,portTmp;
UINT16 regVal;
UINT32 rateTmp;
if(portInvalid(port,&portTmp))
return ERROR;
phyAddr = portTmp + 0x10;
rateTmp = rate;
rateTmp *= 64;
MIIread(phyAddr, QD_REG_EGRESS_RATE_CTRL, ®Val);
regVal &= (~QD_RATECTRL_LMT_MODEf);
if(type == STORM_TYPE_BCAST)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -