在好例子网,分享、交流、成长!
您当前所在位置:首页Others 开发实例一般编程问题 → 8306e网络编程(可用于网络交换设备)

8306e网络编程(可用于网络交换设备)

一般编程问题

下载此实例
  • 开发语言:Others
  • 实例大小:1.31M
  • 下载次数:4
  • 浏览次数:351
  • 发布时间:2020-01-13
  • 实例类别:一般编程问题
  • 发 布 人:海天冰雪
  • 文件格式:.rar
  • 所需积分:5
 相关标签: 网络编程 编程 网络

实例介绍

【实例简介】RTL8306e是一款网络交换机芯片,可进行10M/100M网口、光口通信,驱动简单,可用作网络交换设备。该程序可进行网口、光口数据传送,实现10M/100M网功能,并附有全部代码

【实例截图】

from clipboard

【核心代码】


/****************************************Copyright (c)****************************************************
**                            Guangzhou ZHIYUAN electronics Co.,LTD.
**
**                                 http://www.embedtools.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name:           main.c
** Last modified Date:  2010-02-04
** Last Version:        V1.0
** Descriptions:        The main() function example template
**
**--------------------------------------------------------------------------------------------------------
** Created by:          Lanwuqiang
** Created date:        2010-02-05
** Version:             V1.0
** Descriptions:        添加用户应用程序
**
**--------------------------------------------------------------------------------------------------------
** Modified by:         ZhangNingbo
** Modified date:       2010-02-25
** Version:             V1.0
** Descriptions:        串口查询方式示例程序
**
**--------------------------------------------------------------------------------------------------------
** Modified by:        
** Modified date:      
** Version:            
** Descriptions:       
**
** Rechecked by:
*********************************************************************************************************/
#include <string.h>
#include "..\config.h"
#include "x_ClnkDefs.h"
#include "main.h"
#include ".\RTL8306E_API\mdcmdio.h"  
#include ".\RTL8306E_API\rtk_api_ext.h"  



#define SwitchType  3
/*********************************************************************************************************
  宏定义
*********************************************************************************************************/
#define Eeprom_LoAdd  0x3f000
#define Eeprom_HiAdd  0x7f000
unsigned char Eeprom_buf[256];

#define frist_block_start   0x00000
#define host_begin  0x7000
//*********************************************************************************************************/
#define Version "    YT_CPE  2013-09-18 Clink 1.66.3  Ver 3.1.4    \r\n\r\n"


#define UART_BPS    9600                                              /*  串口通信波特率              */
//*********************************************************************************************************/
#define TP_PAUSE 'p'
#define TP_HANDSHAKE 'h'
#define TP_CONFIGURE 'c'
#define TP_UPDATE 'u'
#define TP_INDIRECT 'i'
#define TP_FILE 'f'
#define TP_COMPRESSED 'z'
#define TP_END 'e'

/*************************************************************************************/

#define READ 0x03
#define READ_STATUS_REGISTER 0x05
#define WREN 0x06
#define PROGRAM 0x02
#define SECTOR_ERASE 0x20 
#define BLOCK_ERASE 0xd8
/*************************************************************************************/

unsigned long mdio[4];
#define MDIO1_PORT 	GPIO0DATA
#define MDIO1_DIR 		GPIO0DIR
#define MDC1       		(1ul << 2)		//p0.2
#define MDIO1        		(1ul << 3)		//p0.3
#define MDC1_OUT_E()  	MDIO1_DIR  |=  MDC1                	//设置为输出                 
#define MDIO1_OUT_E()  	MDIO1_DIR  |=  MDIO1        
#define MDIO1_IN_E()  	MDIO1_DIR  &= ~MDIO1    		 //设置为输入  

#define MDIO2_PORT 	GPIO1DATA
#define MDIO2_DIR 		GPIO1DIR
#define MDC2       		(1ul << 1)		//p1.1
#define MDIO2        		(1ul << 0)		//p1.0
#define MDC2_OUT_E()  	MDIO2_DIR  |=  MDC2                	//设置为输出                 
#define MDIO2_OUT_E()  	MDIO2_DIR  |=  MDIO2        
#define MDIO2_IN_E()  	MDIO2_DIR  &= ~MDIO2    		 //设置为输入  

     
#define ZIP_Reset       	(1ul << 4)		//p3.4
#define PLL_Reset        	(1ul << 5)		//p3.5
#define ZIP_OUT_E()  		GPIO3DIR  |=  ZIP_Reset                	//设置为输出                 
#define PLL_OUT_E()  		GPIO3DIR  |=  PLL_Reset 
#define ZIP_Reset_1()    	GPIO3DATA |=  ZIP_Reset                                                
#define ZIP_Reset_0()     	GPIO3DATA &= ~ZIP_Reset 
#define PLL_Reset_1()    	GPIO3DATA |=  PLL_Reset                                                
#define PLL_Reset_0()     	GPIO3DATA &= ~PLL_Reset 


#define 	  SPI_CS        	(1ul << 7)            //p0.7
#define     CE_Low()    		GPIO0DATA &= ~SPI_CS;   
#define     CE_High()   		GPIO0DATA |=  SPI_CS;

#define 	  LED_OUT        	(1ul << 0)            //p2.0
#define 	  LED_OUT_E()  	GPIO2DIR  |=  LED_OUT                	//设置为输出 
#define     LED_ON()    	GPIO2DATA &= ~LED_OUT;   
#define     LED_OFF()   	GPIO2DATA |=  LED_OUT;

#define 	  RESET_IN        	(1ul << 2)            //p3.2
#define 	  RESET_IN_E()  	GPIO3DIR  &= ~RESET_IN    		 //设置为输入

#define 	  SW_R_IN        	(1ul << 4)            //p0.4
#define 	  SW_OUT_E() 	GPIO0DIR  |=  SW_R_IN                	//设置为输出 
#define 	  SW_OUT_1() 	GPIO0DATA |=  SW_R_IN                                                
#define 	  SW_OUT_0() 		GPIO0DATA &= ~SW_R_IN 

/*************************************************************************************/
unsigned char UartReceiveBuf[30];
unsigned char UartReceiveLen;

/*************************************************************************************/
unsigned char link_stat;
unsigned char update_flash_flag=0;		//正在升级标记

unsigned long lst_update_sig;		//Last update signature - or address in the fhash where to write
unsigned char lof_read_req;		//Set when we should read LOF
unsigned char last_link_status;		//What the link status was last time we checked
unsigned int SoC_watchdog;		//Count down timer to determine if SoC is hung or not

unsigned long update_ln_buf;
unsigned long update_ln_end;
unsigned long Currently_LOF=0;

#define SOC_BOOT_TIMEOUT	60000		// 35s
/*************************************************************************************/

#define CRC32_POLY 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
unsigned long int crc_mini_tab[2] = { 0, CRC32_POLY};

/*************************************************************************************/
// update
#define 	NumOfMapTx			0x0c007ae4
#define  	NumOfMapTxErr			0x0c007afc
#define  	NumOfRsrvRx			0x0c007b18
#define  	NumOfRsrvRxErr			0x0c007b30
#define  	NumOfRsrvRxDropped	0x0c007b48

SwitchGetStruct SwitchGetData[5];

unsigned long systemtime=0;
/*************************************************************************************/
void console(void);
void bootup(void);
void eeprom_write(void);
void eeprom_read(void);
void uart_hex32(long int val);
void uart_puts(char *s);
void uart_puts_hex32(char *s,unsigned long val);
int32 function(uint32 enabled);
void Switch_Data_Init(void);
void Switch_Init(void);
void Switch_Set(INT8U PortIndex);
void get_switch_info(void);
void set_LOF(void);
void vlan_entry_clean(void);
/*********************************************************************************************************
** Function name:       myDelay
** Descriptions:        软件延时
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/

void myDelay (INT32U ulTime)
{
    INT32U i;

    i = 0;
    while (ulTime--) {
        for (i = 0; i < 5000; i  );
    }
}
void my_Delay (INT32U ulTime)
{
    INT32U i;
    for (i = 0; i < ulTime; i  );

}

void IO_Init(void)
{
    	SYSAHBCLKCTRL |= (1ul << 16);                                       /*  使能GPIO模块时钟             */
//	IOCON_PIO0_2 &= ~0x07; 
//	IOCON_PIO0_3 &= ~0x07; 
//	IOCON_PIO1_0 = ~0x07; 
//	IOCON_PIO1_1 = ~0x07; 	
	MDC1_OUT_E();                 
	MDIO1_OUT_E(); 
	MDC2_OUT_E();                 
	MDIO2_OUT_E(); 
	ZIP_OUT_E() ;                 
	PLL_OUT_E();
	ZIP_Reset_1();
	PLL_Reset_1();

	LED_OUT_E();
	RESET_IN_E();
	SW_OUT_E();

}





/*********************************************************************************************************
** Function name:       uartInit
** Descriptions:        串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为9600
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
__asm void UART_IRQHandler(void)
{
	/* Re-direct interrupt, get handler address from application vector table */
	ldr r0, =0x1094
	ldr r0, [r0]
	BX  r0
    	NOP
}
/*********************************************************************************************************
** Function name:        uartInit
** Descriptions:        串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为115200
** input parameters:    无
** output parameters:   无
** Returned value:      无
*********************************************************************************************************/
void uartInit (void)
{
    INT16U usFdiv;
    SYSAHBCLKCTRL |= (1 << 16);                                        /* 使能IOCON时钟               */
    IOCON_PIO1_6 |= 0x01;                                              /* 将P1.6 1.7配置为RXD和TXD    */
    IOCON_PIO1_7 |= 0x01;

    SYSAHBCLKCTRL |= (1<<12);                                          /* 打开UART功能部件时钟         */
    UARTCLKDIV     = 0x01;                                             /* UART时钟分频                 */

    U0LCR  = 0x83;                                                     /* 允许设置波特率               */
    usFdiv = (FAHBCLK / UARTCLKDIV /16)/UART_BPS;                        /* 设置波特率                   */
    U0DLM  = usFdiv / 256;
    U0DLL  = usFdiv % 256;
    U0LCR  = 0x03;                                                     /* 锁定波特率                   */
    U0FCR  = 0x87;                                                     /* 使能FIFO,设置8个字节触发点  */
}


//part 1 -------------uart read/write
// ########################################################################
// ##      初始化
// ########################################################################

 void uart_send(const char c)
{
    U0THR = c;                                                      /*  写入数据                    */
    while ((U0LSR & 0x40) == 0) {                                       /*  等待数据发送完毕            */
    }
}

void uart_puts(char *s)
{
	while (*s)
	{
		uart_send(*s  );
	}
}

void uart_puts_hex32_no_nl(char *s, unsigned long val)
{
	uart_puts(s);
	uart_hex32(val);
}

void uart_puts_hex32(char *s,unsigned long val)
{
	uart_puts_hex32_no_nl(s,val);
	uart_puts("\r\n");
}

void uart_nibble(int val)
{
	val &= 0xf;
	if (val > 9)
		uart_send('A'   val-10);
	else
		uart_send(val   '0');
}

void uart_hex(int val)
{
	uart_nibble(val >> 4);
	uart_nibble(val);
}

void uart_hex32(long val)
{
	int i;
	for (i=24;i>=0;i-=8)
	{
		uart_hex(val >> i);
	}
}

void TIMER16_0_IRQHandler (void)
{
    TMR16B0IR = 0x01;                                                   /* 清除中断标志                 */
    systemtime  ;
}
void Timer16B0Init (void)
{
    SYSAHBCLKCTRL |= (1 << 7);                                          /* 打开定时器模块               */

    TMR16B0IR      = 1;
    TMR16B0PR      = 1000;                                              /* 设置分频系数                 */
    TMR16B0MCR     = 3;                                                 /* 设置MR0匹配后复位TC并产生中断*/
    TMR16B0MR0     = FAHBCLK/1000;                                      /* 设置中断时间0.1S               */
                                                                        /* 16位定时器计数最大值65535    */
    TMR16B0TCR     = 0x01;                                              /* 启动定时器                   */
    zyIsrSet(NVIC_TIMER16B0, (unsigned long)TIMER16_0_IRQHandler, 3);   /* 设置中断并使能               */

}

//part 2 -------------serial flash read/write
// ########################################################################
// ##      初始化
// ########################################################################
void SF_Init(void)
{  
    SYSAHBCLKCTRL |= (1 << 16);                                          /* 配置IOCON模块时钟            */
    IOCON_PIO0_7 &= ~0x07;                                               /* 初始化SPI0引脚               */
    GPIO0DIR    |= SPI_CS;

    IOCON_PIO0_6 |= 0x02;
    IOCON_PIO0_8 |= 0x01;
    IOCON_PIO0_9 |= 0x01;

    PRESETCTRL    |= 0x01;                                              /* 禁止SPI0复位                 */

    IOCON_SCKLOC  = 0x02;                                               /* P0.6配置为SCK                */
    SYSAHBCLKCTRL |= (1 << 11);                                         /* 打开SPI0外设                 */
    SSP0CLKDIV     = 0x01;                                              /* SSP时钟分频                  */
   
    SSP0CR0 =       (0x01 << 8) |                                       /* SCR  设置SPI时钟分频         */
                    (0x00 << 7) |                                       /* CPHA 时钟输出相位,           */
                                                                        /* 仅SPI模式有效                */
                    (0x00 << 6) |                                       /* CPOL 时钟输出极性,           */
                                                                        /* 仅SPI模式有效                */
                    (0x00 << 4) |                                       /* FRF  帧格式 00=SPI,01=SSI,   */
                                                                        /* 10=Microwire,11=保留         */
                    (0x07 << 0);                                        /* DSS  数据长度,0000-0010=保留,*/
                                                                        /* 0011=4位,0111=8位,1111=16位  */

    SSP0CR1 =       (0x00 << 3) |                                       /* SOD  从机输出禁能,1=禁止     */
                    (0x00 << 2) |                                       /* MS   主从选择,0=主机,1=从机  */
                    (0x01 << 1) |                                       /* SSE  SSP使能                 */
                    (0x00 << 0);                                        /* LBM  回写模式                */
             
    SSP0CPSR = 2;                                                       /* PCLK分频值                   */
    SSP0ICR  = 0x03;                                                    /* 中断清除寄存器               */
}

// ########################################################################
// ##      允许芯片读写串行flash
// ########################################################################
void SF_CS_ENABLE(void)
{
	CE_Low();
}

// ########################################################################
// ##    禁止芯片读写flash
// ########################################################################
void SF_CS_DISABLE(void)
{
	CE_High();
}

/*********************************************************************************************************
** 函数名称: Send_Byte
** 函数功能:通过硬件SPI发送一个字节到MX25L1602
** 输入参数: data
** 输出参数: 无
** 返 回 值:无
*********************************************************************************************************/
void Send_Byte (INT8U data)
{
    SSP0DR = data;
    while( (SSP0SR & 0x10) == 0x10);                                    /* 等待TFE置位,即发送FIFO空    */
    data = SSP0DR;   
}

/*********************************************************************************************************
** 函数名称:Get_Byte
** 函数功能:通过硬件SPI接口接收一个字节到处理器
** 输入参数:无
** 输出参数:无
*********************************************************************************************************/
INT8U Get_Byte (void)
{
    SSP0DR = 0xFF;                                                      /* 发送该数据用以产生时钟       */
    while ( 0 == (SSP0SR & 0x01));                                      /* 等待数据发送完毕             */
   /*
    * 判断当前是否空闲(是否处于TX Or RX)
    */
    while( SSP0SR & (1 << 4));
   /*
    * 判断是否已接收到数据,必须判断是否接收完成,否则
    * 新的TX发送再次写入LPC_SSP0->DR寄存器
    */
   while( SSP0SR & (1 << 2) == 0x00); 
   return (INT8U)(SSP0DR);                                              /* 返回接收到的数据             */
}
 
// ########################################################################
// ##      从串行flash 中发送或接收一个字符
// ########################################################################
unsigned char SF_SpiTransfer(unsigned char data,unsigned char flag)
{
	if(flag==1)		//读
	{
    		SSP0DR = 0xFF;                                                      /* 发送该数据用以产生时钟       */
    		while ( 0 == (SSP0SR & 0x01));                                      /* 等待数据发送完毕             */
   /*
    * 判断当前是否空闲(是否处于TX Or RX)
    */
    		while( SSP0SR & (1 << 4));
   /*
    * 判断是否已接收到数据,必须判断是否接收完成,否则
    * 新的TX发送再次写入LPC_SSP0->DR寄存器
    */
   		while( SSP0SR & (1 << 2) == 0x00); 
   		return (INT8U)(SSP0DR);                                              /* 返回接收到的数据             */
	}
	else			//写
	{
    		SSP0DR = data;
    		while( (SSP0SR & 0x10) == 0x10);                                    /* 等待TFE置位,即发送FIFO空    */
    		return (INT8U)(SSP0DR); 
	}
}
// ########################################################################
// ##       等待串行flash 可读
// ########################################################################
void SF_WaitSpiReady(void)
{
	char sr;            		// SPI memory status register 
	for (;;) 
	{	
		SF_CS_ENABLE();  	// Pull down the chip select line of the SPI serial memory
		SF_SpiTransfer(READ_STATUS_REGISTER,0);
                //--------------------------------------------------------------
                // get the status register value, send the value 0xFF to avoid
                // toggle on the MOSI line
                //--------------------------------------------------------------
		sr = SF_SpiTransfer(0xFF,1);
		SF_CS_DISABLE();        // Pull high the chip select line of the SPI serial memory
		if (!(sr & 1))
			return;
	}
}

// ########################################################################
// ##      发送一个32位地址到串行flash (有效19位 寻址512K)
// ########################################################################
void SF_SendAddr(unsigned long addr)
{
	SF_SpiTransfer((char)(addr>>16),0); // transmit the most significant address byte
	SF_SpiTransfer((char)(addr>>8),0);  // transmit the middle address byte
	SF_SpiTransfer((char)(addr),0);     // transmit the less significant address byte
}


// ########################################################################
// ##    从flash中读取一个块指令(读开始)
// ########################################################################
void SF_ReadFlashBegin(unsigned long addr)
{
	SF_WaitSpiReady();
	SF_CS_ENABLE();                      // Pull down the chip select line of the SPI serial memory
	SF_SpiTransfer(READ,0);          //transmitt the op_code READ
	SF_SendAddr(addr);
}

// ########################################################################
// ##       写数据命令
// ########################################################################
void SF_WriteCommand(void)
{
        SF_WaitSpiReady();
        SF_CS_ENABLE();                 	// Pull down the chip select line of the SPI serial memory
        SF_SpiTransfer(WREN,0);           	// transmitt the op_code
        SF_CS_DISABLE();                	// Pull high the chip select line of the SPI serial memory
}


// ########################################################################
// ##    擦除flash的64K字节
// ########################################################################
void SF_EraseSector(unsigned long addr)
{
        SF_WriteCommand();            		// always perform a WREN command before any write operation
        SF_WaitSpiReady();
        SF_CS_ENABLE();                 	// Pull down the chip select line of the SPI serial memory
        SF_SpiTransfer(SECTOR_ERASE,0);         	// transmit the SECTOR_ERASE op_code
        SF_SendAddr(addr);
        SF_CS_DISABLE();                	// Pull high the chip select line of the SPI serial memory
}

// ########################################################################
// ##    写flash
// ##    入口:
// ##   addr = 要写入的flash起始地址                   ##
// ##   count = 写入的字节数                ##
// ##   ptr = 写入的数据(指针)     ##
// ##   dir = 指针的操作方向, -1 或 1                             ##  
// ########################################################################
void SF_PutChars(unsigned long  addr, unsigned int count, unsigned char *ptr, char dir, char auto_erase)
{
	int pg;
	pg=256;

	while (count--)
	{
		if (  pg >= 256)
       	{
          		SF_CS_DISABLE();
          		
			if (auto_erase && ((addr & 0xfff)==0))
			{	SF_EraseSector(addr);
			//	uart_puts_hex32("  addr1=",addr);
			}
          		SF_WriteCommand();      // always perform a WREN command before any write operation
                 	SF_WaitSpiReady();
                  	SF_CS_ENABLE();         // Pull down the chip select line of the SPI serial memory
                 	SF_SpiTransfer(PROGRAM,0);// transmitt the op_code WRITE
                   	SF_SendAddr(addr);
                  	pg=addr & 0xff;         // Compute the number of bytes left in this page.
            	}
            	SF_SpiTransfer(*ptr,0);
           	ptr =dir;
           	addr  ;
  	}
	SF_CS_DISABLE();                        // Pull high the chip select line of the SPI serial memory
}


 // ########################################################################
// ##      从flash 中读取32位数据
// ########################################################################
unsigned long  flash_long(void)
{
	signed char j;
	unsigned long data;

	data=0;
	for (j=24;j>=0;j-=8)
	{
		data |= (unsigned long) SF_SpiTransfer(0xff,1) << j;
	}
	
	return(data);
}


//part 3 ------------ MII 
// ########################################################################
// ##         初始化
// ########################################################################

void setup_MDIO1ClockOut16Bit(void)
{
	mdio[0]=MDIO1_PORT & ~(MDIO1|MDC1);
	mdio[1]=mdio[0] | MDC1;
	mdio[2]=mdio[0] | MDIO1;
	mdio[3]=mdio[1] | mdio[2];
}


void setup_MDIO2ClockOut16Bit(void)
{
	mdio[0]=MDIO2_PORT & ~(MDIO2|MDC2);
	mdio[1]=mdio[0] | MDC2;
	mdio[2]=mdio[0] | MDIO2;
	mdio[3]=mdio[1] | mdio[2];
}
// ########################################################################
// ##             MDIO1ClockOut8Bit - send 8 bits to MDIO bus             ##
// ##            发送一个8位的数据到MDIO总线上
// ########################################################################
void MDIO1ClockOut8Bit(unsigned char val)
{
	unsigned char i;

	for(i=0;i<8;i  )
	{
		if(val&0x80)
		{
			MDIO1_PORT=mdio[2];
			MDIO1_PORT=mdio[3];
		}
		else
		{
			MDIO1_PORT=mdio[0];
			MDIO1_PORT=mdio[1];
		
		}
		val<<=1;
	}
}

void MDIO2ClockOut8Bit(unsigned char val)
{
	unsigned char i;

	for(i=0;i<8;i  )
	{
		if(val&0x80)
		{
			MDIO2_PORT=mdio[2];
			MDIO2_PORT=mdio[3];
		}
		else
		{
			MDIO2_PORT=mdio[0];
			MDIO2_PORT=mdio[1];
		
		}
		val<<=1;
	}
}


// ########################################################################
// ##          MDIOClockOut16Bit - Write 16 bits to the MDIO bus         ##
// ##         发送16位数据到MDIO总线上
// ########################################################################
void MDIO1ClockOut16Bit(unsigned int info)
{
	MDIO1ClockOut8Bit(info >> 8);
	MDIO1ClockOut8Bit(info);
}

void MDIO2ClockOut16Bit(unsigned int info)
{
	MDIO2ClockOut8Bit(info >> 8);
	MDIO2ClockOut8Bit(info);
}

// ########################################################################
// ##   MDIOClockOutPreamble - send the 32 bit preamble to the MDIO bus  ##
// ##  发送32位前导码到MDIO总线上
// ########################################################################
void MDIO1ClockOutPreamble(void)
{
	unsigned long m2, m3;
	unsigned char ct;
	m2 = mdio[2];
	m3 = mdio[3];
	
	for (ct=0;ct<8/*32/4*/;ct  )
	{
		MDIO1_PORT=m2;
		MDIO1_PORT=m3;
		MDIO1_PORT=m2;
		MDIO1_PORT=m3;
		MDIO1_PORT=m2;
		MDIO1_PORT=m3;
		MDIO1_PORT=m2;
		MDIO1_PORT=m3;
	}
}

void MDIO2ClockOutPreamble(void)
{
	unsigned long m2, m3;
	unsigned char ct;
	m2 = mdio[2];
	m3 = mdio[3];
	
	for (ct=0;ct<8/*32/4*/;ct  )
	{
		MDIO2_PORT=m2;
		MDIO2_PORT=m3;
		MDIO2_PORT=m2;
		MDIO2_PORT=m3;
		MDIO2_PORT=m2;
		MDIO2_PORT=m3;
		MDIO2_PORT=m2;
		MDIO2_PORT=m3;
	}
}

// ########################################################################
// ##          MDIO1ClockIn16Bit - read 16 bits from the mdio bus         ##
// ##          从MDIO总线上读取16位字节
// ########################################################################
unsigned int MDIO1ClockIn16Bit(void)
{
	int mdio_val;
	int bit;
	int rc;
	mdio_val=MDIO1_PORT & ~(MDIO1|  MDC1);
	rc=0;
	MDIO1_IN_E();
	for (bit=15;bit>=0;--bit)
	{
		MDIO1_PORT=mdio_val | MDIO1;
		if (MDIO1_PORT & MDIO1)
			rc=(rc << 1) | 1;
		else
			rc=(rc << 1) | 0;
		MDIO1_PORT=mdio_val | MDIO1|  MDC1;
	}
	MDIO1_OUT_E();
	MDIO1_PORT=mdio_val | MDIO1 |  MDC1;
	MDIO1_PORT=mdio_val | MDIO1 |  MDC1;
	MDIO1_PORT=mdio_val | MDIO1 |  MDC1;
	MDIO1_PORT=mdio_val | MDIO1 |  MDC1;
	return(rc);
}

unsigned int MDIO2ClockIn16Bit(void)
{
	int mdio_val;
	int bit;
	int rc;
	mdio_val=MDIO2_PORT & ~(MDIO2|  MDC2);
	rc=0;
	MDIO2_IN_E();
	for (bit=15;bit>=0;--bit)
	{
		MDIO2_PORT=mdio_val | MDIO2;
		if (MDIO2_PORT & MDIO2)
			rc=(rc << 1) | 1;
		else
			rc=(rc << 1) | 0;
		MDIO2_PORT=mdio_val | MDIO2|  MDC2;
	}
	MDIO2_OUT_E();
	MDIO2_PORT=mdio_val | MDIO2 |  MDC2;
	MDIO2_PORT=mdio_val | MDIO2 |  MDC2;
	MDIO2_PORT=mdio_val | MDIO2 |  MDC2;
	MDIO2_PORT=mdio_val | MDIO2 |  MDC2;
	return(rc);
}
		
// ########################################################################
// ##     ClinkReadMDIOData - read one of the PHY registers on EN2210    ##
// ##     读取EN2210的一个寄存器数据
// ##     EN2210所有的信息全部是通过MDIO 总线访问最后的5个PHY寄存器。
// ##     为了访问这5个寄存器,这个程序按照常规发送"read"请求,
// ##     并发送访问的寄存器地址,然后从EN2210中读取16位数据。
// ##     这样允许访问EN2210中的任何寄存器。
// ##     入口:reg_addr  。这个重要的寄存器地址是 : 0x1b ~0x1f
// ########################################################################
unsigned int ClinkReadMDIOData(int reg_addr)
{
	setup_MDIO1ClockOut16Bit();
	MDIO1ClockOutPreamble();
	MDIO1ClockOut16Bit((MDIO_READ_MASK_HI << 8) | MDIO_READ_MASK_LO(reg_addr));
	return(MDIO1ClockIn16Bit());
}

// ########################################################################
// ##    ClinkWriteMDIOData - write value to the EN2210 MDIO interface   ##
// ##   把16位数据写入EN2210的MDIO接口,下面是5个寄存器的映射
// ##   Register                Meaning                                
// ##   ----------      ---------------------------------------------    ##
// ##     0x1b          Write control / status register                  ##
// ##     0x1c          1/2 of 32 bit address latch (high)               ##
// ##     0x1d          1/2 of 32 bit address latch (low)                ##
// ##     0x1e          1/2 of 32 bit data latch (high)                  ##
// ##     0x1f          1/2 of 32 bit data latch (low)                   ##
// ########################################################################
void ClinkWriteMDIOData(int reg_addr,unsigned val)
{
	setup_MDIO1ClockOut16Bit();
	MDIO1ClockOutPreamble();
	MDIO1ClockOut16Bit((MDIO_WRITE_MASK_HI << 8) | MDIO_WRITE_MASK_LO(reg_addr));
	MDIO1ClockOut16Bit(val);
}

// ########################################################################
// ##             PHY_operation - Raw MDIO bus read or write             ##
// ##       这是一个通用的MDIO总线读写程序,
// ##       允许我们读写任何器件的任何寄存器。
// ##       入口:
// ##       	operation:    	PHY_READ | PHY_WRITE
// ##            phy:		     	EN2210设置为1,其他为2
// ##            addr:		寄存器地址
// ## 		val:			数值
// ########################################################################
unsigned int PHY_operation(int operation,int phy, int addr,unsigned int val)
{
	setup_MDIO2ClockOut16Bit();
	MDIO2ClockOutPreamble();
	MDIO2ClockOut16Bit(operation | (MDIO_START_BITS << 8) | (phy << 7) | (addr << 2));
	if (operation == PHY_READ)
		return(MDIO2ClockIn16Bit());
	else
		MDIO2ClockOut16Bit(val);
	return(val);
}

// ########################################################################
// ##          ClinkWaitMDIOReady - wait for SoC bus to say idle         ##
// ##     检测EN2210是否空闲,
// ########################################################################
void ClinkWaitMDIOReady(void)
{
	unsigned int rc;
	for (;;) 
	{			// If there is problem in SoC, Watchdog interrupt will reset me !!!
		rc=ClinkReadMDIOData(ADDRESS_MODE);
		if ((rc & 0xff) == 0)
			return;
		if (rc & CLINK_BUSY)
		{
			uart_puts("CLINK_BUSY\r\n");
			bootup();
		}
		if (rc & CLINK_ERROR)
		{
			uart_puts("CLINK_ERROR\r\n");
			bootup();
		}
		return;
	}
}

unsigned long ClinkReadFrom(unsigned long addr)
{
	unsigned long data;
	ClinkWaitMDIOReady();
	ClinkWriteMDIOData(ADDRESS_HIGH, addr >> 16);
	ClinkWriteMDIOData(ADDRESS_LOW, addr);
	ClinkWriteMDIOData(ADDRESS_MODE, CLINK_START_READ);
	ClinkWaitMDIOReady();
	data=ClinkReadMDIOData(DATA_HIGH);
	data = data << 16;
	data |= ClinkReadMDIOData(DATA_LOW);
	return data;
}

void ClinkWriteTo(unsigned long addr, unsigned long data)
{
	ClinkWaitMDIOReady();
	ClinkWriteMDIOData(ADDRESS_HIGH, addr >> 16);
	ClinkWriteMDIOData(ADDRESS_LOW, addr);
	
	ClinkWriteMDIOData(DATA_HIGH, data >> 16);
	ClinkWriteMDIOData(DATA_LOW, data);
	ClinkWriteMDIOData(ADDRESS_MODE, CLINK_START_WRITE);
}

// ########################################################################
// ##          Turbo_open - Setup the system for turbo download          ##
// ##         这个函数用于Turbo模式的开始,用于下载image,那时地址自动增加。
// ##         低地址发送两次是为了兼容之前的版本中出现的bug
// ########################################################################
void Turbo_open(unsigned long addr)
{
	ClinkWaitMDIOReady();
	ClinkWriteMDIOData(ADDRESS_HIGH, addr >> 16);
	ClinkWriteMDIOData(ADDRESS_LOW, addr);
	ClinkWriteMDIOData(ADDRESS_LOW, addr);
}

void Turbo_write(unsigned long data)
{
	ClinkWriteMDIOData(DATA_HIGH, data >> 16);
	ClinkWriteMDIOData(DATA_LOW, data);
	ClinkWriteMDIOData(ADDRESS_MODE, CLINK_START_WRITE | CLINK_AUTO_INC);
}


void Turbo_close(void)
{
	ClinkWriteMDIOData(ADDRESS_MODE, 0);
}  

// ########################################################################
//zxf

 unsigned long  crctab32[128] =
{
  	0x0,
  	0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
  	0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
  	0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
  	0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
  	0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
  	0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
  	0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
  	0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
  	0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
  	0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
  	0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
  	0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
  	0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
  	0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
  	0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
  	0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
  	0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
  	0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
  	0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
  	0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
  	0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
  	0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
  	0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
  	0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
  	0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
  	0xDC3ABDED, 0xD8FBA05A
};

unsigned long compute_crc(unsigned char *databuf,unsigned long len,unsigned char flag)
{
	unsigned char val;
	unsigned long i;
	unsigned long crc=0;
	unsigned char ix;
	
	for (i=0;i<len;i  )
	{
		if(flag==0)
			val=databuf[i];
		else
			val=SF_SpiTransfer(0xFF,1); 
			
     		ix=(unsigned int) (crc >> 24) ^ val;
        	if ((ix & 0xc0) == 0x80)
     		{
           		crc = (crc << 8) ^ ((crctab32[ix>>1]) << 1) ^ (crctab32[ix & 1]);
       	}
		else if ((ix & 0xc0) == 0xc0)
		{
           		crc = (crc << 8) ^ ((crctab32[ix>>1]) << 1) ^ (crctab32[~ix & 1]);
		}
         	else
         		crc = (crc << 8) ^ (crctab32[ix]);
	}
	return(crc);
}

unsigned char crc_check (unsigned char *databuf,unsigned long len,unsigned long *crc,unsigned char flag)
{

	unsigned long crc1;
	*crc=compute_crc(databuf,len-4,flag);

	if(flag==0)
	{
		crc1=databuf[len-4];crc1<<=8;
		crc1 =databuf[len-3];crc1<<=8;
		crc1 =databuf[len-2];crc1<<=8;
		crc1 =databuf[len-1];
	}
	else
	{
		crc1=SF_SpiTransfer(0xFF,1);crc1<<=8;
		crc1 =SF_SpiTransfer(0xFF,1);crc1<<=8;
		crc1 =SF_SpiTransfer(0xFF,1);crc1<<=8;
		crc1 =SF_SpiTransfer(0xFF,1);
	}	
//	uart_puts_hex32("crc_c=",*crc);
//	uart_puts_hex32("crc_r=",crc1);

	if(crc1==0)
		return 0;
	if(crc1==*crc)
		return 1;
	else
		return 0;

}
// ########################################################################

void fetch_data_and_override(unsigned long info[])
{
	char i;
	char *info_fill;
	
	info_fill=(char *)(&info[3]);
	for(i=0;i<4;i  ,info_fill  )
	*info_fill=SF_SpiTransfer(0xff,1);
}

void locate(char *name,unsigned  long *info,unsigned char LocateFile_flag)
{
	unsigned char temp,i;
	unsigned char *info_fill;
	
	info[2]=SF_SpiTransfer(0xff,1);	//读取类型
	temp=SF_SpiTransfer(0xff,1);	
	i=0;
	if(LocateFile_flag==1)
		info[2]=1;				//
	while((temp!=0x00)&&(i<50))			//判断是否为0,如果为0,取文件名
	{
		if(LocateFile_flag==1)
		{
			if(name[i]!=temp)info[2]=0;
		}
		else
		{	
			name[i]=temp;
			name[i 1]='\0';
		}
		i  ;
		temp=SF_SpiTransfer(0xff,1);	
		
	}
	//取数据,地址低字节
	info_fill=(unsigned char *)(&info[1]);
	for(i=0;i<4;i  ,info_fill  )
		*info_fill=SF_SpiTransfer(0xff,1);
	//取长度,地址低字节
	info_fill=(unsigned char *)(&info[0]);
	for(i=0;i<4;i  ,info_fill  )
		*info_fill=SF_SpiTransfer(0xff,1);

}

void ClinkDownloadFirmware(unsigned long clinkAddr, unsigned long len)
{
	unsigned long data;
	Turbo_open(clinkAddr);

	while (len)
	{	
		data=flash_long();

		Turbo_write(data);
		len-=4;
	}

	Turbo_close();
}

//下载配置文件和image
unsigned char ClinkProcessRecord(void)
{
	char name[30];
	unsigned long i;
	unsigned long info[4];
	locate(name,info,0);
	info[3]=0;
	switch (info[2])
	{
		case TP_FILE:
			if (info[1])
				ClinkDownloadFirmware(info[1],info[0]);
			else
			{
				for (i=0;i<info[0];i  )
					SF_SpiTransfer(0xff,1);
			}
			break;
			
		case TP_CONFIGURE:
			fetch_data_and_override(info);
			
		if(strcmp(name,"CSC_CLK_CTL0")==0)
//			uart_puts_hex32_no_nl(" CSC_CLK_CTL0= ",info[3]);
				info[3]=0x0B000000;
		if(strcmp(name,"GPHY_ENH_CTRL")==0)
//		uart_puts_hex32_no_nl(" GPHY_ENH_CTRL= ",info[3]);
				info[3]=0x0201;

			ClinkWriteTo(info[1],info[3]);
			break;
			
		case TP_UPDATE:
			fetch_data_and_override(info);
			ClinkWriteTo(info[1],info[3]=ClinkReadFrom(info[1]) |info[3]);
			break;		
			
		case TP_INDIRECT:
			fetch_data_and_override(info);
			info[3]=ClinkReadFrom( info[3]);
			ClinkWriteTo(info[1], info[3]);
			break;

		case TP_END:
		case TP_PAUSE:
		
			break;
			
		default:
			uart_puts("ERROR\r\n");
			return('e');
	}
/*
	uart_puts(name);
	uart_puts_hex32_no_nl(" = ",info[3]);
	uart_puts("\r\n");
*/
	return((unsigned char)info[2]);
}

#define ANY_NODE_ID 0x99
void retrieve_reply(void)
{
	unsigned long  data;
	SoC_watchdog=0x4242;
	
	data=ClinkReadFrom(HOST_MAILBOX_INCOMMING);	
	if((data&0xff)==0x85)
	{
		if((data&0xff00)!=0)
			bootup();
	}
	else if((data&0xff)==ANY_NODE_ID)
	{
		data=ClinkReadFrom(0x0c00b8dc);
		if((Currently_LOF!=data)&&(data!=0))
		{	
			uart_puts_hex32("Lof = ",data);
			Currently_LOF=data;
			Eeprom_buf[7]=((data>>24)&0xff);
			Eeprom_buf[8]=((data>>16)&0xff);
			Eeprom_buf[9]=((data>>8)&0xff);
			Eeprom_buf[10]=((data)&0xff);
			eeprom_write();
		}
		
	}

	ClinkWriteTo(READ_CSR_REG,ClinkReadFrom(READ_CSR_REG) & 0x7fffffff);
	return;
}


void send_request(void)
{
	ClinkReadFrom(WRITE_CSR_REG);	
	if((ClinkReadFrom(WRITE_CSR_REG) & 0x80000000)==0)
	{
		if(lof_read_req!=0)
		{
			lof_read_req=0;
			ClinkWriteTo(HOST_MAILBOX_OUTGOING,((unsigned long ) ANY_NODE_ID << 8) | CLNK_MBX_ETH_DATA_BUF_CMD);
			ClinkWriteTo(HOST_MAILBOX_OUTGOING 4,DATA_BUF_MY_NODE_INFO_CMD_TYPE);
		}
		else
		{
			ClinkWriteTo(HOST_MAILBOX_OUTGOING,((unsigned long ) ANY_NODE_ID << 8) | CLNK_MBX_ETH_GET_STATUS_CMD);
		}
	}
	ClinkWriteTo(WRITE_CSR_REG,ClinkReadFrom(WRITE_CSR_REG) | 0x80000000);

}


void update_scan(void)
{
	unsigned long  data,i;
	unsigned long  clinkadd;
	
	unsigned long position;
	unsigned char update_info[272];
	SwitchSetStruct *SwitchSetbuf;		
	SwitchGetStruct *SwitchGetbuf;
	
	clinkadd=update_ln_buf;
	
	while(clinkadd<update_ln_end)
	{
		data=ClinkReadFrom(clinkadd);

		if((data&0xffffff00)==0x476f6f00)				//=Goo
		{
			clinkadd =(data&0xff)*4;
			position=ClinkReadFrom(clinkadd);				//position
			update_info[0]=(unsigned char)((position>>24)&0xff);
			update_info[1]=(unsigned char)((position>>16)&0xff);
			update_info[2]=(unsigned char)((position>>8)&0xff);
			update_info[3]=(unsigned char)((position)&0xff);
			
			if(position!=lst_update_sig)
			{
				lst_update_sig=position;
				for(i=0;i<67;i  )	
				{
					clinkadd =4;
					data=ClinkReadFrom(clinkadd);		//info
					update_info[i*4 4]=(unsigned char)((data>>24)&0xff);
					update_info[i*4 5]=(unsigned char)((data>>16)&0xff);
					update_info[i*4 6]=(unsigned char)((data>>8)&0xff);
					update_info[i*4 7]=(unsigned char)((data)&0xff);
				}
				clinkadd =4;
				i=ClinkReadFrom(clinkadd);			//block_checksum
				if((position&0xff)>0)
					data=compute_crc(update_info,272,0);
				else
					data=i;
				if(i==data)
				{	
					if(((update_info[264]==Eeprom_buf[1])&&(update_info[265]==Eeprom_buf[2])&&(update_info[266]==Eeprom_buf[3])
					&&(update_info[267]==Eeprom_buf[4])&&(update_info[268]==Eeprom_buf[5])&&(update_info[269]==Eeprom_buf[6]))||
					((update_info[264]==0xff)&&(update_info[265]==0xff)&&(update_info[266]==0xff)
					&&(update_info[267]==0xff)&&(update_info[268]==0xff)&&(update_info[269]==0xff)))
					{
						switch(position&0xff)
						{
							case 0:		//update
								clinkadd=(position&0x0000ff00) (unsigned char)(position>>16)-0x0400;
								if(clinkadd==0)
									update_flash_flag=1;
								if(update_flash_flag==1)
								{
									SF_PutChars(clinkadd*256,256,update_info 8,1,1);
									uart_puts_hex32("add=",clinkadd);
									if(clinkadd==0x3ef)
									{							
										SF_ReadFlashBegin(0x0);
										if(crc_check(update_info,0x3f000,&data,1)==1)
										{
											SF_ReadFlashBegin(0x40000 0x3effc);
											clinkadd=SF_SpiTransfer(0xFF,1);clinkadd<<=8;
											clinkadd =SF_SpiTransfer(0xFF,1);clinkadd<<=8;
											clinkadd =SF_SpiTransfer(0xFF,1);clinkadd<<=8;
											clinkadd =SF_SpiTransfer(0xFF,1);
											if(data==clinkadd)
												uart_puts("update seccess,same!\r\n");
											else
											{
												uart_puts("update seccess,reboot!\r\n");
												bootup();
											}
										}
										else
											update_flash_flag=0;

									}
								}
								break;
							case 1:		//EEPROM
							//	uart_puts_hex32("  EEPROM=",position);
								
								break;
							case 2:		//reset
								bootup();
								break;
							case 3:		//交换机控制
							
								switch(update_info[8])
								{
									// set
									case 0xf1:									
									case 0xf2:									
									case 0xf3:																	
									case 0xf4:
										i=update_info[8]-0xf1;
										if(Eeprom_buf[12]==2)i =2;
										memcpy(Eeprom_buf 32 i*32,update_info 10,32);
										vlan_entry_clean();
										Switch_Set(0);		
										Switch_Set(1);
										Switch_Set(2);
										Switch_Set(3);
										eeprom_write();
										
										break;

									// get
									case 0x01:	
									
										SwitchGetbuf=&SwitchGetData[0];
										data=update_info[8];data<<=8;
										data =Eeprom_buf[12];data<<=8;
										data =SwitchType;data<<=8;
										ClinkWriteTo(NumOfRsrvRx,data);
										ClinkWriteTo(NumOfMapTx,SwitchGetbuf->rxTraffic);		// 下行流量
										ClinkWriteTo(NumOfRsrvRxErr,SwitchGetbuf->txTraffic);		// 上行流量			
										ClinkWriteTo(NumOfMapTxErr,SwitchGetbuf->rxDropPacketCount);		//下行丢包
										ClinkWriteTo(NumOfRsrvRxDropped,SwitchGetbuf->rxErrorPacketCount);	//下行错包
										break;

									case 0x02:
									case 0x04:
									case 0x06:
									case 0x08:
										i=(update_info[8]-0x02)/2;
										if(Eeprom_buf[12]==2)i =2;
										SwitchSetbuf=(SwitchSetStruct*)(&Eeprom_buf[32 i*32]);
										
										data=update_info[8];data<<=8;
										data =SwitchSetbuf->portModelControl;data<<=8;
										data =SwitchSetbuf->broadcastProtectionEnable;data<<=8;
										data =SwitchSetbuf->flowControlEnable;
										ClinkWriteTo(NumOfRsrvRx,data);
										
										data=SwitchSetbuf->vlanID[0];data<<=8;
										data =SwitchSetbuf->vlanID[1];
										data<<=8;
										data =SwitchSetbuf->priorityGrade;data<<=8;
										data =SwitchSetbuf->portEnable;
										ClinkWriteTo(NumOfMapTx,data);

										data=SwitchSetbuf->downstreamRateControl[0];data<<=8;
										data =SwitchSetbuf->downstreamRateControl[1];data<<=8;
										data =SwitchSetbuf->downstreamRateControl[2];data<<=8;
										data =SwitchSetbuf->downstreamRateControl[3];
										ClinkWriteTo(NumOfRsrvRxErr,data);
										
										data=SwitchSetbuf->upstreamRateControl[0];data<<=8;
										data =SwitchSetbuf->upstreamRateControl[1];data<<=8;
										data =SwitchSetbuf->upstreamRateControl[2];data<<=8;
										data =SwitchSetbuf->upstreamRateControl[3];
										ClinkWriteTo(NumOfMapTxErr,data);
																				
										data=SwitchSetbuf->autoConfigStatus;data<<=8;
										data =SwitchSetbuf->portMACLimit;data<<=8;
										data<<=8;
										ClinkWriteTo(NumOfRsrvRxDropped,data);									
										
										break;
										
									case 0x03:									
									case 0x05:									
									case 0x07:
									case 0x09:
										i=(update_info[8]-0x03)/2;
										if(Eeprom_buf[12]==2)i =2;
										SwitchGetbuf=&SwitchGetData[i];
										
										data=update_info[8];data<<=8;									
										data =(SwitchGetbuf->portLinkStatus)&0xff;data<<=8;
										data =(SwitchGetbuf->portModelStatus)&0xff;data<<=8;										
										ClinkWriteTo(NumOfRsrvRx,data);
										
										ClinkWriteTo(NumOfMapTx,SwitchGetbuf->txTraffic);		// 下行流量
										ClinkWriteTo(NumOfRsrvRxErr,SwitchGetbuf->rxTraffic);		// 上行流量			
										ClinkWriteTo(NumOfMapTxErr,SwitchGetbuf->rxDropPacketCount);		//上行丢包
										ClinkWriteTo(NumOfRsrvRxDropped,SwitchGetbuf->rxErrorPacketCount);	//上行错包
										break;

									default:
										break;

								}
							
								break;
							default:
								break;
						}
					}
				}
				return;
			}
		}
		else
			clinkadd =1016;
	}
}


INT8U hex_nibble(INT8U val)
{
        if ('A' <= val && val <='F')
                return(val - 'A'   10);
        if ('a' <= val && val <='f')
                return(val - 'a'   10);
        if ('0' <= val && val <='9')
                return(val - '0');
        return 0;
}
//00 12 d6 22 02 29
//30 30 31 32 44 36 32 32 30 32 32 39 0D
INT8U resetflag=0;
INT32U resettime=0;
void console(void)
{
 	INT8U ch,i;
 	INT32U maxresettime;
	 if (GPIO3DATA & RESET_IN)
	 {		 	
	 	if((resettime>40)&&(resettime<=400))		//10s
		{	
		 	ClinkWriteTo(CLNK_REG_CPU_RESET,1);
		 	bootup();
	 	}
	 	else
			resettime=0;
	 }	
 	else
 	{
 		resettime  ;		
 		if(link_stat==0)
 			maxresettime=2000;
 		else
 			maxresettime=15000;
		if(resettime>maxresettime)
		{	
			uart_puts("Reset sw\r\n");
			Switch_Data_Init();		
			Eeprom_buf[7]=0x3b;Eeprom_buf[8]=0x9a;
			Eeprom_buf[9]=0xca;Eeprom_buf[10]=0x00;
			eeprom_write();
			
			SW_OUT_0();		//复位交换机和clink
			myDelay(50);
			SW_OUT_1();
			ClinkWriteTo(CLNK_REG_CPU_RESET,1);
			bootup();
		}
 	}
    	if((U0LSR & 0x01)==0)                                       /*  等待接收标志置位            */
		return;
	else
	{	
		ch=U0RBR;

		UartReceiveBuf[UartReceiveLen]=ch;
		if((UartReceiveLen==0)||(UartReceiveLen==1))
		{	
			if(ch==0x30)
				UartReceiveLen  ;
			else
				UartReceiveLen=0;
		}
		else if(UartReceiveLen==2)
		{
			if(ch==0x31)
				UartReceiveLen  ;
			else
				UartReceiveLen=0;
		}
		else if(UartReceiveLen==3)
		{
			if(ch==0x32)
				UartReceiveLen  ;
			else
				UartReceiveLen=0;
		}
		else
			UartReceiveLen  ;
		if(UartReceiveLen==13)
		{
			UartReceiveLen=0;
			if(((UartReceiveBuf[4]==0x44)||(UartReceiveBuf[4]==0x64))&&(UartReceiveBuf[5]==0x36))
			{
				Eeprom_buf[4]=(hex_nibble(UartReceiveBuf[6])<<4) hex_nibble(UartReceiveBuf[7]);
				Eeprom_buf[5]=(hex_nibble(UartReceiveBuf[8])<<4) hex_nibble(UartReceiveBuf[9]);
				Eeprom_buf[6]=(hex_nibble(UartReceiveBuf[10])<<4) hex_nibble(UartReceiveBuf[11]);
				if((Eeprom_buf[4]>0x20)&&((Eeprom_buf[4]-0x20)%2==0))
					Eeprom_buf[12]=4;
				else
					Eeprom_buf[12]=2;
				uart_puts(" -------MAC------- P\r\n");
				for (i=1;i<7;i  )
				{	
					uart_hex(Eeprom_buf[i]);
					uart_puts(" ");
				}
				uart_hex(Eeprom_buf[12]);
				uart_puts("\r\n");	
				eeprom_write();
				bootup();
			}
			
		}	
		//00 00 12 D6 21 11 22 3B 9A CA 00 00 02 
	}
}

int main(void )
{
	INT8S i;
	INT32U  j;
	INT32U data,oldsystemtime=0;
	
	INT8U last_record_type;


 	targetInit();                                                       /*  初始化目标板,切勿删除      */
    	pinInit();                                                          /*  引脚初始化                  */
       SYSAHBCLKCTRL |= (1 << 6);
       
   	uartInit ();  
	IO_Init();
	SF_Init();
	Timer16B0Init();
	
	eeprom_read();

				
	Switch_Init();	
	
	PLL_Reset_0();
	ZIP_Reset_0();
	
	uart_puts(Version);

	PLL_Reset_1();
	myDelay(1);
	ZIP_Reset_1();

	
//	uart_puts_hex32("0x0014 = ",SwRegisterRead(0x0014));
	uart_puts("I  -----MAC--------- ----LOF----    N\r\n");
	for (i=0;i<13;i  )
	{	
		uart_hex(Eeprom_buf[i]);
		uart_puts(" ");
	}
	uart_puts("\r\n");	

	if((Eeprom_buf[4]==0x22)&&(Eeprom_buf[5]==0x00)&&(Eeprom_buf[6]==0x01))		//MAC地址还未烧写
	{
		uart_puts("Input Address:\r\n");	
		LED_ON();
		oldsystemtime=0;
		while(oldsystemtime<2500000)
		{
			oldsystemtime  ;
			console();
		}
	}
	else
	{
		LED_OFF();
	}
	
	UartReceiveLen=0;	

	if (ClinkReadMDIOData(0) == 0xffff)
	{
		uart_puts("PHY\r\n");
	}

	lst_update_sig=0xffffffff;
	lof_read_req=0;
	last_link_status=0;
	
	SoC_watchdog=0x2a2a;	//	RESET_SOC_WATCHDOG();

	//复位3230
	ClinkWriteTo(EHI_SYS_RESET_SET,0xffffffff);
	myDelay(50);
	ClinkWriteTo(EHI_SYS_RESET_SET,0);

//######################################################################
// ## Hold and release the DIC so it can startup 
//######################################################################
	ClinkWriteTo(DIC_MISC_CTL_0,0);
	ClinkReadFrom(DIC_MISC_CTL_0);
	ClinkWriteTo(DIC_TC_CTL_0,0);
	ClinkWriteTo(DIC_MISC_CTL_0,0x1f);

        //----------------------------------------------------------------------
        // Put the CPU into a hold state - hold reset
        //----------------------------------------------------------------------
	ClinkWriteTo(CLNK_REG_CPU_RESET,1);

	
//######################################################################
//## Download a the firmware code into the EN3230 now
//######################################################################

	ClinkWaitMDIOReady();			// Is this really necessary? - should it be done earlier?

	SF_ReadFlashBegin(frist_block_start host_begin);
	uart_puts("Loading image...\r\n");
	last_record_type=0;
	while (last_record_type != TP_PAUSE && last_record_type != TP_END)
	{	
		console();
		last_record_type=ClinkProcessRecord();
	}

	data=0L;
	for (i=1;i<5;i  )
		data=(data << 8) | Eeprom_buf[i];
	ClinkWriteTo(MAC_ADDR_HI,data);

	data=0L;
	for (i=5;i<7;i  )
		data=(data << 8) | ((unsigned long ) Eeprom_buf[i] << 16);
	ClinkWriteTo(MAC_ADDR_LO,data);

	Currently_LOF=0L;
	for (i=7;i<11;i  )
		Currently_LOF=(Currently_LOF << 8) |Eeprom_buf[i];
	ClinkWriteTo(FS_CFG_LOF,Currently_LOF);
 // ################################################################
 //##Setup the FLOW control MAC address in the GPHY
 //################################################################
	data=0L;
	for (i=1;i<5;i  )
		data=(data >>8) | ((unsigned long )Eeprom_buf[i]<<24);
	ClinkWriteTo(GPHY_FLOW_MAC_HI,data);

	data=0L;
	for (i=5;i<7;i  )
		data=(data >>8) | ((unsigned long ) Eeprom_buf[i]<< 24);
	ClinkWriteTo(GPHY_FLOW_MAC_LO,data);

	last_record_type=0;
	while (last_record_type != TP_PAUSE && last_record_type != TP_END)
	{
		console();
		last_record_type=ClinkProcessRecord();
	}


//######################################################################
//## Wait for CPU to come alive and respond to the "startup" request
//######################################################################
	uart_puts("Waiting for link...\r\n");

	j=0;
	while (1)
	{
		console();
		data=ClinkReadFrom(DEBUG_REG_0);
		if(((data!=0x00)&&(data!=0x12))||(j  > SOC_BOOT_TIMEOUT))
		{	
			bootup();
		}
		if(ClinkReadFrom(MAILBOX_RET_UNSOL_MSGBUF)!=0)
			break;
	}
	data=ClinkReadFrom(MAILBOX_RET_PD_ENTRIES) * 8;
	ClinkWriteTo(DIC_D_PD_SIZE_0,data);
	ClinkWriteTo(DIC_D_PD_SIZE_1,data);
	ClinkWriteTo(DIC_D_PD_SIZE_2,data);

	update_ln_buf=ClinkReadFrom(MAILBOX_RET_RX_DID);
	update_ln_end=update_ln_buf 0x700;
	for(j=0;j<256;j  )
		ClinkWriteTo(update_ln_end-(1 j)*4,0);
	last_record_type=0;

	while (last_record_type != TP_PAUSE && last_record_type != TP_END)
	{
		console();
		last_record_type=ClinkProcessRecord();
	}
	SF_CS_DISABLE();
	while(1)
	{
		console();
		data=ClinkReadFrom(DIC_D_STATUS);
		if((data&0xff)!=0)
		{
			ClinkWriteTo(DIC_D_STATUS,3);
			break;
		}
	}
	ClinkWriteTo(MAILBOX_RET_UNSOL_MSGBUF,0);


	link_stat=1;
	while (1)
	{
		if((oldsystemtime!=systemtime)&&((systemtime%5)==0))
		{			
			get_switch_info();
			
			oldsystemtime=systemtime;
		}

		data=ClinkReadFrom(READ_CSR_REG);

		if(last_link_status!=(data & 0xff))
		{
			last_link_status=data & 0xff;
			lof_read_req=last_link_status;
		}
			
		if (data & 0xff)
		{
			if (link_stat)
			{
				uart_puts("Link is up!\r\n");

				set_LOF();
				link_stat=0;
			}
		}
		else
		{
			if(link_stat==0)
			{	
				bootup();
			}
		}
		if(SoC_watchdog==1)
			bootup();
		else
			SoC_watchdog--;

		if(data&0x80000000)
			retrieve_reply();
		send_request();
		update_scan();
		data=ClinkReadFrom(DEBUG_REG_0);
		if(data!=0x12)
		{	
			if(data==0x21)
				uart_puts("Check bond opt!\r\n\r\n");
			bootup();
		}	
		console();
	}
}

void set_LOF(void)
{
	unsigned long lof;

	lof=ClinkReadFrom(0x0c00ad9c);
	if(lof!=Currently_LOF)
	{
		Eeprom_buf[7]=(lof>>24)&0xff;Eeprom_buf[8]=(lof>>16)&0xff;
		Eeprom_buf[9]=(lof>>8)&0xff;Eeprom_buf[10]=lof&0xff;
		eeprom_write();
	}		
}


void bootup(void)
{
	 AITCR = (0x05fa << 16)   4;
}

void eeprom_write(void)
{
	unsigned long crc;
	
	crc=compute_crc(Eeprom_buf,252,0);
	Eeprom_buf[252]=((crc>>24)&0xff);
	Eeprom_buf[253]=((crc>>16)&0xff);
	Eeprom_buf[254]=((crc>>8)&0xff);
	Eeprom_buf[255]=((crc)&0xff);
	SF_PutChars(Eeprom_LoAdd,256,Eeprom_buf,1,1);
	SF_PutChars(Eeprom_HiAdd,256,Eeprom_buf,1,1);		
}


void eeprom_read(void)
{
	unsigned char flag=0;
	unsigned int  i;
	unsigned long crc1,crc2;

	// 判断第二块flash是否有问题
	SF_ReadFlashBegin(Eeprom_HiAdd);
	for (i=0;i<256;i  )
		Eeprom_buf[i]=SF_SpiTransfer(0xff,1);

	if(crc_check(Eeprom_buf,256,&crc2,0)==0)		
		flag=1;

	// 判断第一块flash是否有问题
	SF_ReadFlashBegin(Eeprom_LoAdd);
	for (i=0;i<256;i  )	
		Eeprom_buf[i]=SF_SpiTransfer(0xff,1);

	if(crc_check(Eeprom_buf,256,&crc1,0)==1)		//没有问题
	{
		if(flag==1)
			SF_PutChars(Eeprom_HiAdd,256,Eeprom_buf,1,1);		
		return;
	}
	else											// 有问题
	{
		if(flag==0)
		{
			SF_ReadFlashBegin(Eeprom_HiAdd);
			for (i=0;i<256;i  )
				Eeprom_buf[i]=SF_SpiTransfer(0xff,1);
			SF_PutChars(Eeprom_LoAdd,256,Eeprom_buf,1,1);
			return;
		}
	}
	

	uart_puts("Initializtion!\r\n");		
	// 初始化数据
	Eeprom_buf[0]=0x00;
	Eeprom_buf[1]=0x00;Eeprom_buf[2]=0x12;
	Eeprom_buf[3]=0xd6;Eeprom_buf[4]=0x22;
	Eeprom_buf[5]=0x00;Eeprom_buf[6]=0x01;
	
	Eeprom_buf[7]=0x3b;Eeprom_buf[8]=0x9a;
	Eeprom_buf[9]=0xca;Eeprom_buf[10]=0x00;

	Eeprom_buf[11]=0;
	Eeprom_buf[12]=4;

	Switch_Data_Init();     
	
	crc1=compute_crc(Eeprom_buf,252,0);
	Eeprom_buf[252]=((crc1>>24)&0xff);
	Eeprom_buf[253]=((crc1>>16)&0xff);
	Eeprom_buf[254]=((crc1>>8)&0xff);
	Eeprom_buf[255]=((crc1)&0xff);
	SF_PutChars(Eeprom_LoAdd,256,Eeprom_buf,1,1);
	SF_PutChars(Eeprom_HiAdd,256,Eeprom_buf,1,1);		
}


void Switch_Data_Init(void)
{
	unsigned char  i;
	SwitchSetStruct *SwitchSetbuf;
	// 交换机初始化
	for(i=0;i<4;i  )
	{
		SwitchSetbuf=(SwitchSetStruct*)(&Eeprom_buf[32 i*32]);
		SwitchSetbuf->autoConfigStatus=1;
		SwitchSetbuf->portModelControl=0;
		SwitchSetbuf->vlanID[0]=0;
		SwitchSetbuf->vlanID[1]=1;
		SwitchSetbuf->priorityGrade=0;
		SwitchSetbuf->portEnable=1;
		SwitchSetbuf->broadcastProtectionEnable=1;
		SwitchSetbuf->flowControlEnable=1;
		SwitchSetbuf->downstreamRateControl[0]=0x00;
		SwitchSetbuf->downstreamRateControl[1]=0x01;
		SwitchSetbuf->downstreamRateControl[2]=0x86;
		SwitchSetbuf->downstreamRateControl[3]=0xa0;
		SwitchSetbuf->upstreamRateControl[0]=0x00;
		SwitchSetbuf->upstreamRateControl[1]=0x01;
		SwitchSetbuf->upstreamRateControl[2]=0x86;
		SwitchSetbuf->upstreamRateControl[3]=0xa0;
		SwitchSetbuf->portMACLimit=0;
		SwitchSetbuf->resetMib=0;
	}
}



void Switch_Init(void)
{
	INT8U port;
	uint32 regval;
	rtk_priority_select_t priDec;
  	rtl8306e_qosSchPara_t sch_para;

	SW_OUT_0();
	myDelay(50);
	SW_OUT_1();
	myDelay(100);
	
	rtk_switch_init();

	
	/*****************************************************/
	//VLAN
	rtk_vlan_init();

	/*set tag insert for port 4*/
	rtl8306e_regbit_set(0, 29, 12, 0, 1);
	rtl8306e_regbit_get(0, 16, 10, 0, &regval);
	rtl8306e_regbit_set(0, 16, 10, 0, 0);

	for(port=0;port<4;port  )
	{
		rtl8306e_regbit_set (port, 22, 1, 0, 0);
		rtl8306e_regbit_set (port, 22, 1, 1, 0);
		rtl8306e_regbit_set (port, 22, 0, 0, 1);
		rtl8306e_regbit_set (port, 22, 0, 1, 1);

	}

	/*****************************************************/
	//QOS
	// Init qos and set two queue
	/*
	rtk_qos_init(4);

	// Set priority weight
	priDec.dot1q_pri=5;
	priDec.port_pri=4;
	priDec.dscp_pri=3;
	priDec.acl_pri=2;
	priDec.vid_pri=1;
	rtk_qos_priSel_set(&priDec);

	rtl8306e_qos_1pPriRemap_set(0,0);
	rtl8306e_qos_1pPriRemap_set(1,0);
	rtl8306e_qos_1pPriRemap_set(2,1);
	rtl8306e_qos_1pPriRemap_set(3,1);
	rtl8306e_qos_1pPriRemap_set(4,2);
	rtl8306e_qos_1pPriRemap_set(5,2);
	rtl8306e_qos_1pPriRemap_set(6,3);
	rtl8306e_qos_1pPriRemap_set(7,3);
	*/
        rtl8306e_qos_queueNum_set(4) ;

	// Set priority weight
      	priDec.dot1q_pri=5;
	priDec.port_pri=4;
 	priDec.dscp_pri=3;
 	priDec.acl_pri=2;
   	priDec.vid_pri=1;
	rtk_qos_priSel_set(&priDec);

       // 做好队列映射
        for(port = 0 ; port< 4; port  )
        {
            rtl8306e_qos_priToQueMap_set(port,port);
        }

     // 1Qmapping:

        rtl8306e_qos_1pPriRemap_set(0,0);
        rtl8306e_qos_1pPriRemap_set(1,0);
        rtl8306e_qos_1pPriRemap_set(2,1);
        rtl8306e_qos_1pPriRemap_set(3,1);
        rtl8306e_qos_1pPriRemap_set(4,2);
        rtl8306e_qos_1pPriRemap_set(5,2);
        rtl8306e_qos_1pPriRemap_set(6,3);
        rtl8306e_qos_1pPriRemap_set(7,3);

        // 设置好set0
        sch_para.q0_wt = 0x01;
        sch_para.q1_wt = 0x01;
        sch_para.q2_wt = 0x7F ;
        //或者设定 sch_para.q2_wt = 0x00;
        sch_para.q3_wt = 0x7F;
        //或者设定 sch_para.q3_wt = 0x00;                       
        sch_para.q2_n64Kbps = 0x00;
        sch_para.q3_n64Kbps = 0x00 ;

        rtl8306e_qos_schedulingPara_set(RTL8306_QOS_SET0, sch_para);

        for(port = 0 ; port < 5; port  )
        {
           //基于802.1q的优先级
            rtl8306e_qos_priSrcEnable_set (port, RTL8306_1QBP_PRIO, 1) ;
           //所有端口启用set0,Q2和Q3开启strict priority(q2.wt=q3.wt=0x00)或者127wight, 且不开启q2、q3的出限速控制, lbmask = 0;         
            rtl8306e_qos_portSchedulingMode_set (port, RTL8306_QOS_SET0, 0) ;
        }


	/*****************************************************/
	// 端口隔离
	rtl8306e_port_isolation_set(0x0267);

	

	/*****************************************************/
	//端口控制
	for(port=0;port<4;port  )
		Switch_Set(port);

	/*****************************************************/
	for(port=0;port<5;port  )
	{
		// 设置字节统计
		rtl8306e_mibUnit_set(port,RTL8306_MIB_CNT1,RTL8306_MIB_BYTE);
		rtl8306e_mibUnit_set(port,RTL8306_MIB_CNT2,RTL8306_MIB_BYTE);
		// 统计清除
		rtl8306e_mib_reset(port);
	}

}

void vlan_entry_clean(void)
{
	INT8U i;
	for(i=1;i<5;i  )		//判断设置的VLAN已经存在,
	{
		rtl8306e_vlan_entry_set(i,0 , 0, 0);
	}
}


void Switch_Set(INT8U PortIndex)
{
	INT8U i,trigNum,filTime;
	INT32U VLANID,pIgPortMsk,val;
	uint32 pVid, pMbrmsk, pUntagmsk;
	rtk_port_phy_ability_t pAbility;
	SwitchSetStruct *SwitchSetbuf;

	SwitchSetbuf=(SwitchSetStruct*)(&Eeprom_buf[32 PortIndex*32]);
	
	/*****************************************************/
	VLANID=SwitchSetbuf->vlanID[0];VLANID<<=8;VLANID =SwitchSetbuf->vlanID[1];
	//VLAN
	rtl8306e_vlan_tagInsert_get(4,&pIgPortMsk);
	if(VLANID>1)
	{
		rtl8306e_vlan_tagInsert_set(4, pIgPortMsk|(0x01<<PortIndex));		

		val=0;
		for(i=1;i<5;i  )		//判断设置的VLAN已经存在,
		{
			rtl8306e_vlan_entry_get(i,&pVid,&pMbrmsk,&pUntagmsk);
			if((pVid&0xffff)==VLANID)					
			{
				rtl8306e_vlan_entry_set(i,pVid , pMbrmsk|(0x01<<PortIndex), pUntagmsk|(0x01<<PortIndex));	
				val=1;
				break;
			}
		}

		if(val==0)	//不存在,则直接设置
			rtl8306e_vlan_entry_set(PortIndex 1,VLANID , 0x10 (0x01<<PortIndex), 0x01<<PortIndex);	
		
		/*set PVid for every port*/
		rtk_vlan_portPvid_set(PortIndex, VLANID, 0);

		/*****************************************************/
		//QOS
		rtk_qos_1pRemark_set(SwitchSetbuf->priorityGrade/2,SwitchSetbuf->priorityGrade);		
		        
		rtk_vlan_vlanBasedPriority_set(VLANID,SwitchSetbuf->priorityGrade/2);
	}
	else
	{
		rtl8306e_vlan_tagInsert_set(4, (pIgPortMsk&(~(0x01<<PortIndex)))&0x0f);

	}
	/*****************************************************/
	// 端口MAC地址数量限制
	if(SwitchSetbuf->portMACLimit==0)
		rtk_l2_limitLearningCnt_set(PortIndex, 0xff);   
	else
		rtk_l2_limitLearningCnt_set(PortIndex, SwitchSetbuf->portMACLimit);   

	/*****************************************************/
	// 端口限速
	val=SwitchSetbuf->downstreamRateControl[0];val<<=8;
	val =SwitchSetbuf->downstreamRateControl[1];val<<=8;
	val =SwitchSetbuf->downstreamRateControl[2];val<<=8;
	val =SwitchSetbuf->downstreamRateControl[3];
	/*
	if((SwitchSetbuf->flowControlEnable==0)&&(val<0x1996))
		val*=2;
	if((SwitchSetbuf->flowControlEnable==0)&&(PortIndex!=1))	
		rtk_rate_igrBandwidthCtrlRate_set(PortIndex,val/8,DISABLED);			//下行
	*/
	rtk_rate_egrBandwidthCtrlRate_set(PortIndex,val/64,DISABLED);			// x
	
	val=SwitchSetbuf->upstreamRateControl[0];val<<=8;
	val =SwitchSetbuf->upstreamRateControl[1];val<<=8;
	val =SwitchSetbuf->upstreamRateControl[2];val<<=8;
	val =SwitchSetbuf->upstreamRateControl[3];

	rtk_rate_igrBandwidthCtrlRate_set(PortIndex,val/64,DISABLED);			// s

	/*****************************************************/
	// 端口使能
	rtl8306e_reg_get(PortIndex, 0, 0, &val);
	if(SwitchSetbuf->portEnable==0)
	{	
		val=val|(0x01<<11);
		rtl8306e_reg_set(PortIndex, 0, 0, val);
	}
	else
	{	
		val=val&(~(0x01<<11));
		rtl8306e_reg_set(PortIndex, 0, 0, val);
	}

	/*****************************************************/
	// 端口环路检测使能
	rtl8306e_reg_get(0, 16, 0, &val);
	val=val|(0x01<<2);
	rtl8306e_reg_set(0, 16, 0, val);
	/*****************************************************/
	// 端口状态控制
	pAbility.AutoNegotiation=0;
	pAbility.Half_10=0;
	pAbility.Full_10=0;
	pAbility.Half_100=0;
	pAbility.Full_100=0;
	pAbility.FC=0;
	pAbility.AsyFC=0;
	switch(SwitchSetbuf->portModelControl)
	{
		case 0:pAbility.AutoNegotiation=1;break;
		case 1:pAbility.Full_100=1;break;
		case 2:pAbility.Half_100=1;break;
		case 3:pAbility.Full_10=1;break;
		case 4:pAbility.Half_10=1;break;					
		default:pAbility.AutoNegotiation=1;break;
	}
	// 流控
	if(SwitchSetbuf->flowControlEnable)
		pAbility.FC=1;
	rtk_port_phyForceModeAbility_set(PortIndex,&pAbility);	

	/*****************************************************/
	
	/*****************************************************/
	if(PortIndex==0)
	{
		// 广播风暴抑制
		if(SwitchSetbuf->broadcastProtectionEnable==0)
		{
			rtl8306e_storm_filterEnable_set(RTL8306_BROADCASTPKT,DISABLE);
			rtl8306e_storm_filterEnable_set(RTL8306_MULTICASTPKT,DISABLE);
			rtl8306e_storm_filterEnable_set(RTL8306_UDAPKT,DISABLE);
		}
		else
		{
			rtl8306e_storm_filterEnable_set(RTL8306_BROADCASTPKT,ENABLE);
			rtl8306e_storm_filterEnable_set(RTL8306_MULTICASTPKT,ENABLE);
			rtl8306e_storm_filterEnable_set(RTL8306_UDAPKT,ENABLE);
			switch(SwitchSetbuf->broadcastProtectionEnable)
			{
				case 1:trigNum=RTL8306_STM_FILNUM8;filTime=RTL8306_STM_FIL800MS;break;
				case 2:trigNum=RTL8306_STM_FILNUM16;filTime=RTL8306_STM_FIL800MS;break;
				case 3:trigNum=RTL8306_STM_FILNUM32;filTime=RTL8306_STM_FIL800MS;break;
				case 4:trigNum=RTL8306_STM_FILNUM64;filTime=RTL8306_STM_FIL800MS;break;
				case 5:trigNum=RTL8306_STM_FILNUM128;filTime=RTL8306_STM_FIL800MS;break;
				case 6:trigNum=RTL8306_STM_FILNUM256;filTime=RTL8306_STM_FIL800MS;break;
				case 7:trigNum=RTL8306_STM_FILNUM64;filTime=RTL8306_STM_FIL100MS;break;
				case 8:trigNum=RTL8306_STM_FILNUM128;filTime=RTL8306_STM_FIL100MS;break;
				case 9:trigNum=RTL8306_STM_FILNUM256;filTime=RTL8306_STM_FIL100MS;break;
				default:	trigNum=RTL8306_STM_FILNUM8;filTime=RTL8306_STM_FIL100MS;break;			
			}
				rtl8306e_storm_filter_set(trigNum,filTime,DISABLE);
		}

		// 统计信息清除
		if(SwitchSetbuf->resetMib)
		{
			SwitchSetbuf->resetMib=0;
			for(i=0;i<5;i  )
				rtl8306e_mib_reset(i);

		}
	}
}

void get_switch_info(void)
{
	INT8U i;
	INT32U mibinfo;
	rtk_port_linkStatus_t pLinkStatus;
	rtk_port_speed_t pSpeed;
	rtk_port_duplex_t pDuplex;
	SwitchGetStruct *SwitchGetbuf;



	for(i=0;i<5;i  )
	{
		SwitchGetbuf=&SwitchGetData[i];

		// 端口状态
		rtk_port_phyStatus_get(i,&pLinkStatus,&pSpeed,&pDuplex);
		SwitchGetbuf->portLinkStatus=pLinkStatus;
		if((pSpeed==PORT_SPEED_100M)&&(pDuplex==PORT_FULL_DUPLEX))
			SwitchGetbuf->portModelStatus=1;
		else if((pSpeed==PORT_SPEED_100M)&&(pDuplex==PORT_HALF_DUPLEX))
			SwitchGetbuf->portModelStatus=2;
		else if((pSpeed==PORT_SPEED_10M)&&(pDuplex==PORT_FULL_DUPLEX))
			SwitchGetbuf->portModelStatus=3;
		else
			SwitchGetbuf->portModelStatus=4;

		//环路检测
		rtl8306e_reg_get(i, 24, 0, &mibinfo);
		SwitchGetbuf->portLoopStatus=(mibinfo>>8)&0x01;
//		uart_puts("port:");uart_hex(i);uart_puts_hex32_no_nl(" loop status",SwitchGetbuf->portLoopStatus);uart_puts("\r\n");
		
		//统计信息
		rtl8306e_mib_get(i,RTL8306_MIB_CNT1,&mibinfo);		//TX byte count
		if(mibinfo>=SwitchGetbuf->txByteCount)
		{
			SwitchGetbuf->txTraffic=(mibinfo-SwitchGetbuf->txByteCount)/5;
		}
		SwitchGetbuf->txByteCount=mibinfo;		

		rtl8306e_mib_get(i,RTL8306_MIB_CNT2,&mibinfo);		//RX byte count
		if(mibinfo>=SwitchGetbuf->rxByteCount)
		{
			SwitchGetbuf->rxTraffic=(mibinfo-SwitchGetbuf->rxByteCount)/5;
		}
		SwitchGetbuf->rxByteCount=mibinfo;	

		rtl8306e_mib_get(i,RTL8306_MIB_CNT3,&mibinfo);		//RX drop packet count
		SwitchGetbuf->rxDropPacketCount=mibinfo;

		rtl8306e_mib_get(i,RTL8306_MIB_CNT4,&mibinfo);		//RX CRC error packet count
		SwitchGetbuf->rxErrorPacketCount=mibinfo;

		rtl8306e_mib_get(i,RTL8306_MIB_CNT5,&mibinfo);		//RX fragment packet  count
		SwitchGetbuf->rxFragmentPacketCount=mibinfo;

	}
//	uart_puts("\r\n");
}
				

/*
PHY REG: 00000500
PHY REG: 00007940
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00003000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000081
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000

0x0100:0000007D


MAC模式:
GPHY_ENH_CTRL = 0xc081
CSC_CLK_CTL0 = 0

PHY模式:
GPHY_ENH_CTRL = 00000201
CSC_CLK_CTL0 = 0B000000

arp -s 192.168.100.162 00-1d-7d-7d-6e-75
*/
// pc3 reset  pd6  pll reset
/*********************************************************************************************************
  End Of File
*********************************************************************************************************/


实例下载地址

8306e网络编程(可用于网络交换设备)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警