dot3ah.c

来自「在freescale 的ne64上开发的源代码」· C语言 代码 · 共 1,260 行 · 第 1/3 页

C
1,260
字号
					dataEnd = 1;
					break;
				}
				if((dataLen+SPEC_STATISTIC_GET_REQ_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
				{
					dataEnd = 1;
					break;
				}
				dataLen += (SPEC_STATISTIC_GET_REQ_LEN + 2);
				break;
				
			case SPEC_TYPE_STATISTIC_GET_RES:
				/*check the statistics get response tlv length*/
				if(RECEIVE_NETWORK_B() != SPEC_STATISTIC_GET_RES_LEN)
				{
					dataEnd = 1;
					break;
				}
				if((dataLen+SPEC_STATISTIC_GET_RES_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
				{
					dataEnd = 1;
					break;
				}
				dataLen += (SPEC_STATISTIC_GET_RES_LEN + 2);
				break;
				
			case SPEC_TYPE_REG_RW_REQ:
				/*check the register read or write request tlv length*/
				if(RECEIVE_NETWORK_B() != SPEC_REG_RW_LEN)
				{
					dataEnd = 1;
					break;
				}
				if((dataLen+SPEC_REG_RW_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
				{
					dataEnd = 1;
					break;
				}
				dataLen += (SPEC_REG_RW_LEN + 2);
				break;
				
			case SPEC_TYPE_REG_RW_RES:
				/*check the register read or write response tlv length*/
				if(RECEIVE_NETWORK_B() != SPEC_REG_RW_LEN)
				{
					dataEnd = 1;
					break;
				}
				if((dataLen+SPEC_REG_RW_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
				{
					dataEnd = 1;
					break;
				}
				dataLen += (SPEC_REG_RW_LEN + 2);
				break;
			case SPEC_TYPE_FX_INFO_GET_REQ:
				/*check the register read or write response tlv length*/
				if(RECEIVE_NETWORK_B() != SPEC_FX_INFO_GET_REQ_LEN)
				{
					dataEnd = 1;
					break;
				}
				if((dataLen+SPEC_FX_INFO_GET_REQ_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
				{
					dataEnd = 1;
					break;
				}
				dataLen += (SPEC_FX_INFO_GET_REQ_LEN + 2);
				break;
			case SPEC_TYPE_FX_INFO_GET_RES:
				/*check the register read or write response tlv length*/
				if(RECEIVE_NETWORK_B() != SPEC_FX_INFO_GET_RES_LEN)
				{
					dataEnd = 1;
					break;
				}
				if((dataLen+SPEC_FX_INFO_GET_RES_LEN+2+SPEC_OAM_HEADER_FCS_LEN) > OAMPDU_MAX_SIZE)
				{
					dataEnd = 1;
					break;
				}
				dataLen += (SPEC_FX_INFO_GET_RES_LEN + 2);
				break;
			default:
				dataEnd = 1;
				break;
		}

		if(dataEnd == 1)
			break;
	}
	
	NETWORK_RECEIVE_INITIALIZE(bufIndex);

	process_oam_spec_tlv(pCurrentMBuf->working_ptr, dataLen);

	/*reset the lost link timer*/
	init_timer(locLstLnkTimer, locLstLnkTmrPrd*TIMERTIC);
}

/*
 * Function:
 *   process_dot3ah_oam()
 * Purpose:
 *   Process the dot3ah OAMPDU.
 * Parameters:
 *   frame -- the ethernet frame pointer.
 * Returns:
 *   None.
 * Notes:
 *   None.
 */
void process_dot3ah_oam(struct ethernet_frame* frame)
{
	UINT8  tempByte; 
	UINT16 bufIndex;

	if(dot3ahOAMInited==0)
		return;

	bufIndex = 0;
	dot3ahRxSlowPkts++;
	DOT3AH_DEBUGOUT("Begin process_dot3ah_oam\n\r");

	/*check the source address, be sure not equal to me*/
	if(memcmp(frame->source, localmachine.localHW, ETH_ADDRS_LEN) == 0)
		return;
	
	/*check if slow protocol packet*/
	if(frame->protocol != PROTOCOL_SLOW)
		return;
	
	NETWORK_RECEIVE_INITIALIZE(frame->buf_index);

	/*check the slow protocol subType*/
	tempByte = RECEIVE_NETWORK_B();
	bufIndex += 1;
	if(tempByte != SLOW_SUBTYPE_OAM)
	{
		otherSlowProtocolDetected = 1;
		/*If there is other slow protocol, the slow packets 
		is not only to cpu, it should forward to port 8 and port 10*/
		dot3ahOAMMacAddrSet((0x1<<9) | (0x1<<10) | (0x1<<8));
		return;
	}

	dot3ahRxPkts++;
	
	if((dot3ahOAMInited==0) || (localOAMEnable==OAM_DISABLE))
		return;
	
	/*check the receive port*/
	if(frame->port != localOAMPort)
		return;

	/*check the source address*/
	if(remoteDTEExist == 0)
	{
		if(oamPacketFirst == 1)
		{
			(void)memcpy(rmtDTEAddr, frame->source, ETH_ADDRS_LEN);
			oamPacketFirst = 0;						
		}
		else
		{
			if(memcmp(frame->source, rmtDTEAddr, ETH_ADDRS_LEN) != 0)
				return;
		}
	}
	else
	{
		if(memcmp(frame->source, rmtDTEAddr, ETH_ADDRS_LEN) != 0)
			return;
	}
	
	/*get the flag field*/
	rmtOAMFlagField.flagFieldVal= RECEIVE_NETWORK_W();
	bufIndex += 2;
	if(rmtOAMFlagField.Bits.localStableEval == 0x3)
		return;
	localOAMFlagField.Bits.rmtStableEval = rmtOAMFlagField.Bits.localStableEval;
	
	/*get the code field*/
	tempByte = RECEIVE_NETWORK_B();
	bufIndex += 1;
	
	switch(tempByte)
	{
		case OAM_CODE_INFO:
			process_info_oampdu();
			break;
		case OAM_CODE_ORG_SPEC:
			process_spec_oampdu(frame->buf_index + bufIndex);
			break;			
		case OAM_CODE_EVENT_NOTIFY:
		case OAM_CODE_VARIABLE_REQ:
		case OAM_CODE_VARIABLE_RES:
		case OAM_CODE_LOOP_CTRL:
		default:
			return;
	}
}

/*
 * Function:
 *   dot3ah_port_set()
 * Purpose:
 *   Set whitch port to support dot3ah OAM.
 * Parameters:
 *   port -- 1:FX1 port,2:FX or FX2 port.
 * Returns:
 *   OK or ERROR.
 * Notes:
 *   If TP-FX converter,port 1 is invalid.
 */
UINT8 dot3ah_port_set(UINT8 port)
{
	UINT8 portTmp;

	portTmp = localOAMPort;
	if(port == 1)
	{
		if(localDTEType == OL100CR_X4X_V5)
			return ERROR;
		localOAMPort = 10;
	}
	else if(port == 2)
	{
		localOAMPort = 8;
	}
	else
		return ERROR;

	if(portTmp != localOAMPort)
	{
		/*Set slow protocol destination MAC, ports=10 and 8*/
		dot3ahOAMMacAddrSet((0x1<<9)|(0x1<<localOAMPort));
		localSatisfied = 0;
		localStable = 0;	
		remoteStable = 0;
		remoteStateValid = 0;
		oamDiscoveryState = DISC_FAULT;
		hwLfpRecover();
	}
	return OK;
}

/*
 * Function:
 *   dot3ah_port_get()
 * Purpose:
 *   Get whitch port to support dot3ah OAM.
 * Parameters:
 *   port -- 1:FX1 port,2:FX or FX2 port.
 * Returns:
 *   OK or ERROR.
 * Notes:
 *   If TP-FX converter,port 1 is invalid.
 */
UINT8 dot3ah_port_get(UINT8 *port)
{
	*port = 0;
	if(localOAMPort == 10)
		*port = 1;
	else if(localOAMPort == 8)
		*port = 2;

	return OK;	
}

/*
 * Function:
 *   dot3ah_enable_set()
 * Purpose:
 *   Set dot3ah status.
 * Parameters:
 *   enable -- 1:enable,0:disalbe.
 * Returns:
 *   OK or ERROR.
 * Notes:
 *   None.
 */
UINT8 dot3ah_enable_set(UINT8 enable)
{
	if(enable)
	{
		localOAMEnable = OAM_ENABLE;
		dot3ahOAMMacAddrSet((0x1<<9)|(0x1<<localOAMPort));
	}
	else
	{
		localOAMEnable = OAM_DISABLE;
		dot3ahOAMMacAddrSet((0x1<<8)|(0x1<<10));
	}

	return OK;
}

/*
 * Function:
 *   dot3ah_enable_get()
 * Purpose:
 *   Get dot3ah status.
 * Parameters:
 *   enable -- 1:enable,0:disalbe.
 * Returns:
 *   OK or ERROR.
 * Notes:
 *   None.
 */
UINT8 dot3ah_enable_get(UINT8 *enable)
{
	*enable = localOAMEnable;
	return OK;
}

/*
 * Function:
 *   dot3ah_mode_set()
 * Purpose:
 *   Set dot3ah mode.
 * Parameters:
 *   mode -- 1:active,0:passive.
 * Returns:
 *   OK or ERROR.
 * Notes:
 *   None.
 */
UINT8 dot3ah_mode_set(UINT8 mode)
{
	localOAMMode = mode;
	return OK;
}

/*
 * Function:
 *   dot3ah_mode_get()
 * Purpose:
 *   Get dot3ah mode.
 * Parameters:
 *   mode -- 1:active,0:passive.
 * Returns:
 *   OK or ERROR.
 * Notes:
 *   None.
 */
UINT8 dot3ah_mode_get(UINT8 *mode)
{
	*mode = localOAMMode;
	return OK;
}

/*
 * Function:
 *   dot3ah_info_show()
 * Purpose:
 *   show dot3ah information.
 * Parameters:
 *   None.
 * Returns:
 *   None.
 * Notes:
 *   None.
 */
void dot3ah_info_show(void)
{
	printf("   information:\n\r");

	if(localOAMEnable)
		printf("   enable\n\r");
	else
		printf("   disable\n\r");
	if(localOAMMode)
		printf("   active\n\r");
	else
		printf("   passive\n\r");

	switch(oamDiscoveryState)
	{
		case DISC_FAULT:
			printf("    DISC_FAULT\n\r");
			break;
		case DISC_ACTIVE_SEND_LOCAL:
			printf("    DISC_ACTIVE_SEND_LOCAL\n\r");
			break;
		case DISC_PASSIVE_WAIT:
			printf("    DISC_PASSIVE_WAIT\n\r");
			break;
		case DISC_SEND_LOCAL_RMT:
			printf("    DISC_SEND_LOCAL_RMT\n\r");
			break;
		case DISC_SEND_LOCAL_RMT_OK:
			printf("    DISC_SEND_LOCAL_RMT_OK\n\r");
			break;
		case DISC_SEND_ANY:
			printf("    DISC_SEND_ANY\n\r");
			break;
		default:
			printf("    unknown\n\r");
			break;
	}
	if(remoteDTEExist)
		printf("   remote exist\n\r");
	else
		printf("   remote not exist\n\r");

	printf("   TX %u info packets\n\r",dot3ahTxInfoPkts);
	printf("   TX %u spec packets\n\r",dot3ahTxSpecPkts);
	printf("   RX %u slow packets\n\r",dot3ahRxSlowPkts);
	printf("   RX %u packets\n\r",dot3ahRxPkts);
	printf("   RX %u info packets\n\r",dot3ahRxInfoPkts);
	printf("   RX %u spec packets\n\r",dot3ahRxSpecPkts);
	printf("   locLstLnkTimer %lu\n\r",check_timer(locLstLnkTimer));		
	if(otherSlowProtocolDetected)
		printf("   other slow protocol detected\n\r");
	else
		printf("   no other slow protocol detected\n\r");	
}

⌨️ 快捷键说明

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