dot3ah.c
来自「在freescale 的ne64上开发的源代码」· C语言 代码 · 共 1,260 行 · 第 1/3 页
C
1,260 行
#include <string.h>
#include <stdio.h>
#include <stdlib.h> /*atoi*/
#include "System.h"
#include "debug.h"
#include "ethernet.h"
#include "dot3ah.h"
#include "timers.h"
#include "mBuf.h"
#include "ne64debug.h"
/*variables need other place support*/
extern UINT8 localNoamPortLnkStat; /*1-link up*/
extern UINT8 localOamPortLnkFault; /*1-link fault*/
extern UINT8 localDTEType; /*local device type*/
extern MBUF* pCurrentMBuf;
extern UINT8 localHWVersion; /*local hardware version*/
extern UINT8 locPwrUpFlag;
#if 0
extern UINT8 remoteFXLink; /*1-link up*/
extern UINT8 remoteHWVer; /*remote hardware version*/
extern UINT8 remoteSWVer; /*remote software version*/
extern UINT8 localSWVersion; /*local software version*/
#else
UINT8 remoteFXLink; /*1-link up*/
UINT8 remoteHWVer; /*remote hardware version*/
UINT8 remoteSWVer; /*remote software version*/
UINT8 localSWVersion=2; /*local software version*/
#endif
UINT8 localOAMEnable; /*remote control enable 1-enable, 0-disable*/
UINT8 localOAMMode; /*1-active, 0-passive*/
UINT8 localOAMPort; /*8-FX or FX2 port, 10-TP or FX1 port*/
UINT8 localPdu;
UINT8 localSatisfied;
UINT8 localStable;
UINT8 localUnidirectional;
UINT8 remoteStable;
UINT8 remoteStateValid;
UINT8 oamDiscoveryState;
UINT8 oamPduCnt;
UINT8 otherSlowProtocolDetected;
UINT8 oamPduCntDefault;
UINT8 dot3ahOAMInited = 0;
UINT8 oamPacketFirst;
UINT8 remoteTPLink; /*1-link up*/
UINT8 remotePwrUpFlg;
UINT8 remoteDTEExist; /*remote device exist flag, 1-exist*/
UINT8 pduTimer; /*second decreace*/
UINT8 locLstLnkTimer; /*second decreace*/
UINT32 pduTmrPrd;
UINT32 locLstLnkTmrPrd;
UINT8 remoteDTEType;
UINT16 dot3ahTxInfoPkts;
UINT16 dot3ahTxSpecPkts;
UINT16 dot3ahRxPkts;
UINT16 dot3ahRxSlowPkts;
UINT16 dot3ahRxInfoPkts;
UINT16 dot3ahRxSpecPkts;
UNION_OAM_FLAG_FIELD localOAMFlagField;
UNION_OAM_FLAG_FIELD rmtOAMFlagField;
const UINT8 dot3ah_addr[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02};
UINT8 rmtDTEAddr[6];
UINT8 localInfoTLV[16];
UINT8 remoteInfoTLV[16];
tINFO_TLV *tLocalInfoTLV = (tINFO_TLV *)localInfoTLV;
tINFO_TLV *tRemoteInfoTLV = (tINFO_TLV *)remoteInfoTLV;
extern void hwLfpRecover(void);
/*
* Function:
* dot3ah_init()
* Purpose:
* Init the dot3ah used variables.
* Parameters:
* oamMode -- DTE_OAM_ACTIVE or DTE_OAM_PASSIVE
* oamPort -- The tx or rx OAM packet port, 10 or 8
* Returns:
* None.
*/
void dot3ah_init(void)
{
if(dot3ahOAMInited)
return;
/*init variables*/
localOAMEnable = 1;
localOAMMode = DTE_OAM_PASSIVE;
localPdu = LOCAL_PDU_LF_INFO;
localSatisfied = 0;
localStable = 0;
localUnidirectional = 0;
remoteDTEExist = 0;
remoteStable = 0;
remoteStateValid = 0;
oamDiscoveryState = DISC_FAULT;
otherSlowProtocolDetected = 0;
oamPacketFirst = 1;
remoteDTEType = DTE_TYPE_UNKNOWN;
pduTmrPrd = PDU_TIME;
locLstLnkTmrPrd = LOCAL_LOST_LINK_TIME;
oamPduCntDefault = OAMPDU_COUNT_PER_SECOND;
oamPduCnt = oamPduCntDefault;
dot3ahTxInfoPkts = 0;
dot3ahTxSpecPkts = 0;
dot3ahRxPkts = 0;
dot3ahRxSlowPkts = 0;
dot3ahRxInfoPkts = 0;
dot3ahRxSpecPkts = 0;
/*init flag field*/
localOAMFlagField.flagFieldVal = 0;
localOAMFlagField.Bits.criticEvent = 0;
localOAMFlagField.Bits.dyingGasp = 0;
localOAMFlagField.Bits.linkFault = 0;
/*init local information TLV*/
tLocalInfoTLV->infoType = TLV_INFO_TYPE_LOCAL;
tLocalInfoTLV->infoLen = TLV_INFO_LEN;
tLocalInfoTLV->oamVersion = OAM_VERSION;
tLocalInfoTLV->infoRevision = 0;
tLocalInfoTLV->infoState.infoTlvStateVal = 0;
tLocalInfoTLV->infoState.Bits.parAction = PAR_ACTION_FWD;
tLocalInfoTLV->infoState.Bits.muxAction = MUX_ACTION_FWD;
tLocalInfoTLV->oamConfig.infoTlvOamCfgVal = 0;
tLocalInfoTLV->oamConfig.Bits.oamMode = localOAMMode;
tLocalInfoTLV->oamConfig.Bits.unidirectSupport = 0;
tLocalInfoTLV->oamConfig.Bits.loopSupport = 0;
tLocalInfoTLV->oamConfig.Bits.linkEvents = 1;
tLocalInfoTLV->oamConfig.Bits.varRetrieval = 0;
tLocalInfoTLV->oampduConfig.infoTlvOamPduCfgVal = OAMPDU_MAX_SIZE;
tLocalInfoTLV->ouiHigh = OAMPDU_OUI_MSB;
tLocalInfoTLV->ouiLow = OAMPDU_OUI_LSB;
tLocalInfoTLV->vendorInfoCode = OAM_SPEC_CODE; /*fixed vendor info code*/
tLocalInfoTLV->vendorDTEType = localDTEType;
tLocalInfoTLV->hwVerTpLink.hwVerTpLinkVal= 0;
tLocalInfoTLV->hwVerTpLink.Bits.TpLinkStatus = localNoamPortLnkStat;
tLocalInfoTLV->hwVerTpLink.Bits.firstPwrUpFlg = locPwrUpFlag;
tLocalInfoTLV->hwVerTpLink.Bits.vendorHWVer = localHWVersion;
tLocalInfoTLV->vendorSWVer = localSWVersion;
tRemoteInfoTLV->infoType = TLV_INFO_TYPE_REMOTE;
/*Set slow protocol destination MAC, ports=10 and 8*/
dot3ahOAMMacAddrSet((0x1<<9)|(0x1<<localOAMPort));
/*init timer*/
pduTimer = get_timer();
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
locLstLnkTimer = get_timer();
init_timer(locLstLnkTimer, locLstLnkTmrPrd*TIMERTIC);
dot3ahOAMInited = 1;
}
/*
* Function:
* dot3ah_discovery()
* Purpose:
* Excute the dot3ah discovery state exchange.
* Parameters:
* None.
* Returns:
* None.
* Notes:
* This function shouled be call at the main loop.
*/
void dot3ah_discovery(void)
{
if(dot3ahOAMInited == 0)
return;
if(check_timer(locLstLnkTimer) == 0)
{
init_timer(locLstLnkTimer, locLstLnkTmrPrd*TIMERTIC);
localSatisfied = 0;
localStable = 0;
remoteStable = 0;
remoteStateValid = 0;
oamDiscoveryState = DISC_FAULT;
}
if(localOAMEnable == OAM_DISABLE)
{
oamPacketFirst = 1;
pduTmrPrd = PDU_TIME;
locLstLnkTmrPrd = LOCAL_LOST_LINK_TIME;
oamPduCntDefault = OAMPDU_COUNT_PER_SECOND;
localSatisfied = 0;
localStable = 0;
remoteStable = 0;
remoteStateValid = 0;
oamDiscoveryState = DISC_FAULT;
remoteDTEExist = 0;
return;
}
if(localOamPortLnkFault == 1)
{
localSatisfied = 0;
localStable = 0;
remoteStable = 0;
remoteStateValid = 0;
oamDiscoveryState = DISC_FAULT;
}
switch(oamDiscoveryState)
{
case DISC_FAULT:
if(localOamPortLnkFault == 1)
{
localPdu = LOCAL_PDU_LF_INFO;
}
else
{
if(localOAMMode == DTE_OAM_ACTIVE)
{
oamDiscoveryState = DISC_ACTIVE_SEND_LOCAL;
localPdu = LOCAL_PDU_INFO;
}
else
{
oamDiscoveryState = DISC_PASSIVE_WAIT;
localPdu = LOCAL_PDU_RX_INFO;
}
}
localStable = 0;
localOAMFlagField.Bits.localStableEval = DISCOVERY_NOT_COMPLETED;
break;
case DISC_PASSIVE_WAIT:
if(remoteStateValid == 1)
{
oamDiscoveryState = DISC_SEND_LOCAL_RMT;
localPdu = LOCAL_PDU_INFO;
localStable = 0;
localOAMFlagField.Bits.localStableEval = DISCOVERY_NOT_COMPLETED;
}
break;
case DISC_ACTIVE_SEND_LOCAL:
if(remoteStateValid == 1)
{
oamDiscoveryState = DISC_SEND_LOCAL_RMT;
localPdu = LOCAL_PDU_INFO;
localStable = 0;
localOAMFlagField.Bits.localStableEval = DISCOVERY_NOT_COMPLETED;
}
break;
case DISC_SEND_LOCAL_RMT:
if(localSatisfied == 1)
{
oamDiscoveryState = DISC_SEND_LOCAL_RMT_OK;
localPdu = LOCAL_PDU_INFO;
localStable = 1;
localOAMFlagField.Bits.localStableEval = DISCOVERY_COMPLETED;
}
break;
case DISC_SEND_LOCAL_RMT_OK:
if((localSatisfied==1) && (remoteStable==1))
{
oamDiscoveryState = DISC_SEND_ANY;
localPdu = LOCAL_PDU_ANY;
}
if(localSatisfied == 0)
{
oamDiscoveryState = DISC_SEND_LOCAL_RMT;
localPdu = LOCAL_PDU_INFO;
localStable = 0;
localOAMFlagField.Bits.localStableEval = DISCOVERY_NOT_COMPLETED;
}
break;
case DISC_SEND_ANY:
if((localSatisfied==1) && (remoteStable==0))
{
oamDiscoveryState = DISC_SEND_LOCAL_RMT_OK;
localPdu = LOCAL_PDU_INFO;
localStable = 1;
localOAMFlagField.Bits.localStableEval = DISCOVERY_COMPLETED;
}
if(localSatisfied == 0)
{
oamDiscoveryState = DISC_SEND_LOCAL_RMT;
localPdu = LOCAL_PDU_INFO;
localStable = 0;
localOAMFlagField.Bits.localStableEval = DISCOVERY_NOT_COMPLETED;
}
break;
default:
break;
}
if(oamDiscoveryState == DISC_SEND_ANY)
{
if(remoteDTEExist == 0)
{
if((tRemoteInfoTLV->ouiHigh==OAMPDU_OUI_MSB) && (tRemoteInfoTLV->ouiLow==OAMPDU_OUI_LSB))
{
#if 0
pduTmrPrd = MAX_PDU_TIME;
locLstLnkTmrPrd = MAX_LOCAL_LOST_LINK_TIME;
oamPduCntDefault = MAX_OAMPDU_COUNT_PER_SECOND;
#endif
}
DOT3AH_DEBUGOUT("Remote device discovered\n\r");
}
remoteDTEExist = 1;
}
else
{
if(remoteDTEExist == 1)
{
oamPacketFirst = 1;
pduTmrPrd = PDU_TIME;
locLstLnkTmrPrd = LOCAL_LOST_LINK_TIME;
oamPduCntDefault = OAMPDU_COUNT_PER_SECOND;
//DOT3AH_DEBUGOUT("Remote device lost\n\r");
}
remoteDTEExist = 0;
}
}
/*
* Function:
* dot3ah_send_info()
* Purpose:
* Excute the dot3ah discovery state exchange.
* Parameters:
* None.
* Returns:
* None.
* Notes:
* This function shouled be call at the main loop.
*/
void dot3ah_send_info(void)
{
UINT8 i;
if((dot3ahOAMInited==0) ||(localOAMEnable==OAM_DISABLE))
return;
if(check_timer(pduTimer) != 0)
return;
/*check if the OAM sublayer RX_INFO only*/
if(localPdu == LOCAL_PDU_RX_INFO)
{
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
oamPduCnt = oamPduCntDefault;
return;
}
/*check if the OAM sublayer is LF_INFO and don't support unidirection*/
if((localUnidirectional==0) && (localPdu==LOCAL_PDU_LF_INFO))
{
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
oamPduCnt = oamPduCntDefault;
return;
}
/*check if had sent an OAMPDU in one second,if true, return*/
if(oamPduCnt == 0)
{
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
oamPduCnt = oamPduCntDefault;
return;
}
oamPduCnt = oamPduCntDefault;
NETWORK_SEND_INITIALIZE(OAM_BUFFER);
/*Add Ethernet addresses information*/
for( i=0; i<6; i++)
{
send_frame.destination[i] = dot3ah_addr[i];
send_frame.source[i] = localmachine.localHW[i];
}
send_frame.protocol = PROTOCOL_SLOW;
/*Add egress port information*/
send_frame.sendFrameType = PORT_DIRECT_FRAME;
#if 0
if(localOAMMode == DTE_OAM_ACTIVE)
send_frame.port = localOAMPort; /*the port 8 is fixed fiber port*/
else
send_frame.port = received_frame.port; /*In passive mode*/
#else
send_frame.port = localOAMPort;
#endif
#pragma MESSAGE DISABLE C1825 /*Warning: indirection*/
NETWORK_ADD_DATALINK(&send_frame);
#pragma MESSAGE DEFAULT C1825 /*Warning: indirection*/
/*Put OAMPDU Data*/
SEND_NETWORK_B(SLOW_SUBTYPE_OAM); /*802.3ah OAM subType*/
localOAMFlagField.Bits.linkFault = localOamPortLnkFault;
SEND_NETWORK_W(localOAMFlagField.flagFieldVal); /*802.3ah OAM flag field*/
SEND_NETWORK_B(OAM_CODE_INFO); /*802.3ah OAM code field*/
/*If the OAM sublayer if at LF_INFO state, with on info TLVs*/
if(localPdu == LOCAL_PDU_LF_INFO)
{
SEND_NETWORK_B(TLV_INFO_TYPE_END);
NETWORK_COMPLETE_SEND(0x0040); /*Send the packet*/
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
dot3ahTxInfoPkts++;
return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?