dot3ah.c
来自「在freescale 的ne64上开发的源代码」· C语言 代码 · 共 1,260 行 · 第 1/3 页
C
1,260 行
}
/*put the local info TLV data*/
tLocalInfoTLV->hwVerTpLink.Bits.TpLinkStatus = localNoamPortLnkStat;
tLocalInfoTLV->hwVerTpLink.Bits.firstPwrUpFlg = locPwrUpFlag;
SEND_NETWORK_BUF(localInfoTLV,TLV_INFO_LEN);
tLocalInfoTLV->infoRevision++;
/*if discovery state is ACTIVE_SEND_LOCAL, send local info TLV only*/
if(oamDiscoveryState == DISC_ACTIVE_SEND_LOCAL)
{
SEND_NETWORK_B(TLV_INFO_TYPE_END);
NETWORK_COMPLETE_SEND(0x0040); /*Send the packet*/
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
DOT3AH_DEBUGOUT("Send DISC_ACTIVE_SEND_LOCAL\n\r");
dot3ahTxInfoPkts++;
return;
}
/*put the remote info TLV data*/
SEND_NETWORK_BUF(remoteInfoTLV,TLV_INFO_LEN);
/*put the specific info TLV data or end info*/
SEND_NETWORK_B(TLV_INFO_TYPE_END);
/*Send the packet*/
NETWORK_COMPLETE_SEND(46);
//DOT3AH_DEBUGOUT("Send DISC_ACTIVE_SEND_RMT\n\r");
dot3ahTxInfoPkts++;
init_timer(pduTimer, pduTmrPrd*TIMERTIC);
}
/*
* Function:
* dot3ah_send_spec()
* Purpose:
* Send organization specific OAM.
* Parameters:
* buf -- organization specific TLVs data pointer
* len -- the data length
* Returns:
* OK or ERROR.
* Notes:
* None.
*/
STATUS dot3ah_send_spec(void *buf, UINT16 len)
{
UINT8 i;
if((oamDiscoveryState!=DISC_SEND_ANY)&&(oamDiscoveryState!=DISC_SEND_LOCAL_RMT_OK))
return ERROR;
if(remoteDTEType == DTE_TYPE_UNKNOWN)
return ERROR;
if(oamPduCnt == 0) /*had sent 10 OAMPDUs in a second*/
return ERROR;
oamPduCnt -= 1;
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;
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*/
SEND_NETWORK_W(rmtOAMFlagField.flagFieldVal); /*802.3ah OAM flag field*/
SEND_NETWORK_B(OAM_CODE_ORG_SPEC); /*802.3ah OAM code field*/
/*put the OUI*/
SEND_NETWORK_B(OAMPDU_OUI_MSB);
SEND_NETWORK_W(OAMPDU_OUI_LSB);
/*put the OAM specific code*/
SEND_NETWORK_B(OAM_SPEC_CODE);
/*put the specific info TLV data*/
SEND_NETWORK_BUF((UINT8 *)buf, len);
/*put the specific end info*/
SEND_NETWORK_B(SPEC_TYPE_END);
/*Send the packet*/
NETWORK_COMPLETE_SEND(len+9); /*9 bytes=subType+flag+code+OUI+specCode+specEnd*/
DOT3AH_DEBUGOUT("Send spec: ");
for(i=0;i<len;i++)
{
DOT3AH_DEBUGOUT("%02x ",*((UINT8 *)buf+i));
}
DOT3AH_DEBUGOUT("\n\r");
dot3ahTxSpecPkts++;
return OK;
}
/*
* Function:
* process_info_oampdu()
* Purpose:
* Process the information OAMPDU.
* Parameters:
* None.
* Returns:
* None.
* Notes:
* None.
*/
void process_info_oampdu(void)
{
UINT8 tempByte;
dot3ahRxInfoPkts++;
/*get the local info type*/
tempByte = RECEIVE_NETWORK_B();
if(tempByte == TLV_INFO_TYPE_END)
{
return;
}
/*get int remote DTE local info TLV*/
if(tempByte != TLV_INFO_TYPE_LOCAL)
{
return; /*it's an invalid info OAMPDU*/
}
else
{
/*check the info OAMPDU length field*/
tempByte = RECEIVE_NETWORK_B();
if(tempByte != TLV_INFO_LEN)
{
return; /*length is inlvalid*/
}
tRemoteInfoTLV->infoLen = tempByte;
/*get the OAM Version field*/
tRemoteInfoTLV->oamVersion = RECEIVE_NETWORK_B();
/*get the info OAMPDU Revision field*/
tRemoteInfoTLV->infoRevision = RECEIVE_NETWORK_W();
/*get the info OAMPDU state field*/
tRemoteInfoTLV->infoState.infoTlvStateVal = RECEIVE_NETWORK_B();
/*get the info OAM configration field*/
tRemoteInfoTLV->oamConfig.infoTlvOamCfgVal = RECEIVE_NETWORK_B();
/*get the info OAMPDU configration field*/
tRemoteInfoTLV->oampduConfig.infoTlvOamPduCfgVal = RECEIVE_NETWORK_W();
/*get the info OAMPDU OUI field*/
tRemoteInfoTLV->ouiHigh = RECEIVE_NETWORK_B();
tRemoteInfoTLV->ouiLow = RECEIVE_NETWORK_W();
/*get the info OAMPDU vendor specific field*/
tRemoteInfoTLV->vendorInfoCode = RECEIVE_NETWORK_B();
tRemoteInfoTLV->vendorDTEType = RECEIVE_NETWORK_B();
tRemoteInfoTLV->hwVerTpLink.hwVerTpLinkVal = RECEIVE_NETWORK_B();
tRemoteInfoTLV->vendorSWVer = RECEIVE_NETWORK_B();
/*analyze the remote DTE state and config, set corresponding variable*/
remoteStateValid = 1;
if((tLocalInfoTLV->oamConfig.infoTlvOamCfgVal & tRemoteInfoTLV->oamConfig.infoTlvOamCfgVal)&0x1E)
{
localSatisfied = 1;
}
else
{
localSatisfied = 0;
}
if(rmtOAMFlagField.Bits.localStableEval == DISCOVERY_COMPLETED)
{
remoteStable = 1;
}
else if(rmtOAMFlagField.Bits.localStableEval != 0x3)
{
remoteStable = 0;
}
/*get remote DTE information*/
if(rmtOAMFlagField.Bits.linkFault == 1)
remoteFXLink = 0;
else
remoteFXLink = 1;
if((tRemoteInfoTLV->ouiHigh==OAMPDU_OUI_MSB) && (tRemoteInfoTLV->ouiLow==OAMPDU_OUI_LSB))
{
if(tRemoteInfoTLV->vendorInfoCode == OAM_SPEC_CODE)
{
remoteDTEType = tRemoteInfoTLV->vendorDTEType;
remoteTPLink = tRemoteInfoTLV->hwVerTpLink.Bits.TpLinkStatus;
remotePwrUpFlg = tLocalInfoTLV->hwVerTpLink.Bits.firstPwrUpFlg;
remoteHWVer = tRemoteInfoTLV->hwVerTpLink.Bits.vendorHWVer;
remoteSWVer = tRemoteInfoTLV->vendorSWVer;
}
}
}
/*get the remote info type*/
tempByte = RECEIVE_NETWORK_B();
if(tempByte == TLV_INFO_TYPE_END)
{
return;
}
if(tempByte != TLV_INFO_TYPE_REMOTE)
{
return; /*it's an invalid info OAMPDU*/
}
else
{
/*check the info OAMPDU length field*/
if(RECEIVE_NETWORK_B() != TLV_INFO_LEN)
return; /*length is inlvalid*/
/*get the OAM Version field*/
RECEIVE_NETWORK_B();
/*get the info OAMPDU Revision field*/
RECEIVE_NETWORK_W();
/*get the info OAMPDU state field*/
RECEIVE_NETWORK_B();
/*get the info OAM configration field*/
RECEIVE_NETWORK_B();
/*get the info OAMPDU configration field*/
RECEIVE_NETWORK_W();
/*get the info OAMPDU OUI field*/
RECEIVE_NETWORK_B();
RECEIVE_NETWORK_W();
/*get the info OAMPDU vendor specific field*/
RECEIVE_NETWORK_W();
RECEIVE_NETWORK_W();
}
/*reset the lost link timer*/
init_timer(locLstLnkTimer, locLstLnkTmrPrd*TIMERTIC);
/*get the specific info type*/
tempByte = RECEIVE_NETWORK_B();
if(tempByte == TLV_INFO_TYPE_END)
{
return;
}
else
{
/*process the specific info here, no definition now*/
}
}
/*
* Function:
* process_spec_oampdu()
* Purpose:
* Process the organization specific OAMPDU.
* Parameters:
* bufIndex -- the data start pointer in MBUF.
* Returns:
* None.
* Notes:
* None.
*/
void process_spec_oampdu(UINT16 bufIndex)
{
UINT8 tempByte;
UINT16 tempWord;
UINT16 dataLen;
UINT8 dataEnd;
dot3ahRxSpecPkts++;
/*get the OUI*/
tempByte = RECEIVE_NETWORK_B();
bufIndex += 1;
tempWord = RECEIVE_NETWORK_W();
bufIndex += 2;
/*check the OUI, if not wri OUI, return*/
if((tempByte!=OAMPDU_OUI_MSB) || (tempWord!=OAMPDU_OUI_LSB))
return;
/*check the specific code, if not 0xB3, return*/
if(RECEIVE_NETWORK_B() != OAM_SPEC_CODE)
return;
bufIndex += 1;
dataEnd = 0;
dataLen = 0;
for(;;)
{
/*get the specific TLV type*/
tempByte = RECEIVE_NETWORK_B();
switch(tempByte)
{
case SPEC_TYPE_END:
dataEnd = 1;
break;
case SPEC_TYPE_CFG_SET_REQ:
/*check the config tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_CFG_SET_REQ_LEN)
{
dataEnd = 1;
break;
}
if((dataLen+SPEC_CFG_SET_REQ_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
{
dataEnd = 1;
break;
}
dataLen += (SPEC_CFG_SET_REQ_LEN + 2);
break;
case SPEC_TYPE_STAT_GET_REQ:
/*check the status get request tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_STAT_GET_REQ_LEN)
{
dataEnd = 1;
break;
}
if((dataLen+SPEC_STAT_GET_REQ_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
{
dataEnd = 1;
break;
}
dataLen += (SPEC_STAT_GET_REQ_LEN + 2);
break;
case SPEC_TYPE_STAT_GET_RES:
/*check the status get response tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_STAT_GET_RES_LEN)
{
dataEnd = 1;
break;
}
if((dataLen+SPEC_STAT_GET_RES_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
{
dataEnd = 1;
break;
}
dataLen += (SPEC_STAT_GET_RES_LEN + 2);
break;
case SPEC_TYPE_RATELMT_SET_REQ:
/*check the rate limit set request tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_RATELMT_SET_REQ_LEN)
{
dataEnd = 1;
break;
}
if((dataLen+SPEC_RATELMT_SET_REQ_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
{
dataEnd = 1;
break;
}
dataLen += (SPEC_RATELMT_SET_REQ_LEN + 2);
break;
case SPEC_TYPE_RATELMT_GET_REQ:
/*check the rate limit get request tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_RATELMT_GET_REQ_LEN)
{
dataEnd = 1;
break;
}
if((dataLen+SPEC_RATELMT_GET_REQ_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
{
dataEnd = 1;
break;
}
dataLen += (SPEC_RATELMT_GET_REQ_LEN + 2);
break;
case SPEC_TYPE_RATELMT_GET_RES:
/*check the rate limit get response tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_RATELMT_GET_RES_LEN)
{
dataEnd = 1;
break;
}
if((dataLen+SPEC_RATELMT_GET_RES_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
{
dataEnd = 1;
break;
}
dataLen += (SPEC_RATELMT_GET_RES_LEN + 2);
break;
case SPEC_TYPE_STATISTIC_GET_REQ:
/*check the statistics get request tlv length*/
if(RECEIVE_NETWORK_B() != SPEC_STATISTIC_GET_REQ_LEN)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?