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

📄 hw_api.c

📁 在freescale 的ne64上开发的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/***********************************************************
 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, &regVal);
				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, &regVal);
				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, &regVal);

				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, &regVal);
				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, &regVal);

	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, &regVal);
			if(regVal & MII_CTRL_AE)
			{
				*an = AUTO_ENABLE;
				MIIread(EXTL_PHY_ADDRESS, MII_ANA_REG, &regVal);
				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, &regVal);

	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, &regVal);
		regVal &= (~QD_RATECTRL_LMT_MODEf);
		MIIwrite(phyAddr, QD_REG_EGRESS_RATE_CTRL, regVal);
	}
	else
		regAddr = QD_REG_EGRESS_RATE_CTRL;

	MIIread(phyAddr, regAddr, &regVal);
	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, &regVal);
 	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, &regVal);
	regVal &= (~QD_RATECTRL_LMT_MODEf);
	if(type == STORM_TYPE_BCAST)

⌨️ 快捷键说明

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