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

📄 ethernet.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
字号:
#include <stdio.h>#include <ethernet.h>#define MAX_SIZE 2000#define TX_BD_NUM 1u8 *send_data = NULL;u8 send_data94[94] = {    0x00,0x04,0x61,0x93,0x63,0x38,0xaa,0x02,0x03,0x04,0x05,0x06,0x08,0x00,0x45,0x00,    0x00,0x50,0x19,0x26,0x40,0x00,0x34,0x06,0x6d,0x95,0xdc,0xb5,0x1f,0xb1,0xc0,0xa8,    0x02,0xde,0x00,0x6e,0x13,0x38,0xb2,0x87,0xac,0x6f,0x3b,0xa3,0x52,0x9e,0x50,0x18,    0x16,0xd0,0x86,0xae,0x00,0x00,0x2b,0x4f,0x4b,0x20,0x33,0x38,0x30,0x20,0x6d,0x65,    0x73,0x73,0x61,0x67,0x65,0x28,0x73,0x29,0x20,0x5b,0x31,0x32,0x38,0x30,0x34,0x38,    0x38,0x31,0x31,0x20,0x62,0x79,0x74,0x65,0x28,0x73,0x29,0x5d,0x0d,0x0a};u8 send_data73[73] = {    0x00,0x04,0x61,0x93,0x63,0x38,0xaa,0x02,0x03,0x04,0x05,0x06,0x08,0x00,0x45,0x00,     0x00,0x3b,0x19,0x27,0x40,0x00,0x34,0x06,0x6d,0xa9,0xdc,0xb5,0x1f,0xb1,0xc0,0xa8,     0x02,0xde,0x00,0x6e,0x13,0x38,0xb2,0x87,0xac,0x97,0x3b,0xa3,0x52,0xa4,0x50,0x18,     0x16,0xd0,0xed,0x4e,0x00,0x00,0x2b,0x4f,0x4b,0x20,0x33,0x38,0x30,0x20,0x31,0x32,     0x38,0x30,0x34,0x38,0x38,0x31,0x31,0x0d,0x0a};u8 send_data1514[1514] = {    0x00,0x04,0x61,0x93,0x63,0x38,0xaa,0x02,0x03,0x04,0x05,0x06,0x08,0x00,0x45,0x00,     0x05,0xdc,0x19,0x31,0x40,0x00,0x34,0x06,0x67,0xfe,0xdc,0xb5,0x1f,0xb1,0xc0,0xa8,     0x02,0xde, };u8 send_frame[MAX_SIZE];u8 rev_frame[MAX_SIZE];u32 len = 0;void eth_test(){	MAC_data_frame e_frame;	int i = 0;	eth_init();	while (1)	{	    /*		len = 94;	    	send_data = send_data94 + 14;		set_frame(&e_frame, 0x0008);		send_one_normal_frame(&e_frame);		wait_for_tx_init();		*/		/*		len = 73;	    	send_data = send_data73 + 14;		set_frame(&e_frame, 0x0008);		send_one_normal_frame(&e_frame);		wait_for_tx_init();		*/		len = 1514;	    	send_data = send_data1514 + 14;		for (i=0;i<1514-34;i++)		    send_data[i] = i;		set_frame(&e_frame, 0x0008);		send_one_normal_frame(&e_frame);		wait_for_tx_init();		wait_for_rx_init();		read_rx_normal_frame(&e_frame);	}}static void eth_init(){	u32 status = 0;	/* Double full duplex */	serial_put32(0x11110000);	ETH_SET32(REG_MAC_MODER, 0x0000A400);	/* Enable interrupt, unnessisary */	ETH_SET32(REG_MAC_INT_MASK, 0x0000007F);	/* For full duplex */	ETH_SET32(REG_MAC_IPGT, 0x00000015);	/* Allow to transfer control & receive frame and able to save to ram */	ETH_SET32(REG_MAC_CTRLMODER, 0x00000007);	/* setup MAC address */	ETH_SET32(REG_MAC_ADDR0, 0x03040506);	ETH_SET32(REG_MAC_ADDR1, 0x0000AA02);	ETH_SET32(REG_MAC_TX_BD_NUM, TX_BD_NUM);	/*	ETH_SET32(REG_MAC_MIIADDRESS , 0x01);	ETH_SET32(REG_MAC_MIICOMMAND , BIT_MAC_MIICMD_WCTRLDATA);	status = ETH_GET32(REG_MAC_MIIRX_DATA);	serial_puts("eth_int:REG_MAC_MIIRX_DATA:");	serial_put32(status);	*/	status = ETH_GET32(REG_MAC_MODER);	status |= 0x3;	ETH_SET32(REG_MAC_MODER, status);	status = ETH_GET32(REG_MAC_MODER);	serial_puts("\neth_int:REG_MAC_MODER:");	serial_put32(status);	/* Set TXBD frame buffer address */	ETH_SET32(DIS_TXBD_BUF + 4, PHY(send_frame));	/* Set RXBD frame buffer address */	ETH_SET32(DIS_TXBD_BUF + (TX_BD_NUM<<3) + 4, PHY(rev_frame));	/* Ready to receive datas */	status = (1518 << 16);	status |= BIT_MAC_RX_BD_EMPTY|BIT_MAC_RX_BD_IRQ|BIT_MAC_RX_BD_WRAP;	ETH_SET32(DIS_TXBD_BUF + (TX_BD_NUM<<3), status);	serial_puts("\nRX ready\n");}static void set_frame(MAC_data_frame *frame, u32 length){	DEST_ADDR(frame, 0x386393, 0x610400);	SRC_ADDR(frame, 0x060504, 0x0302AA);	LENGTH(frame, length);}static void loop_back_test(MAC_data_frame *frame){	MAC_data_frame rev_frame;	u32 i = 0;	u32 status = 0;	status = ETH_GET32(REG_MAC_MODER);	status |= BIT_MAC_MODER_LOOPBCK;	ETH_SET32(REG_MAC_MODER, status);	wait_for_rx_init();	send_one_normal_frame(frame);	wait_for_tx_init();	read_rx_normal_frame(&rev_frame);	i = compare_data(frame, &rev_frame);	if (i == -1)		serial_puts("Loop test error\n");	status &= ~BIT_MAC_MODER_LOOPBCK;	ETH_SET32(REG_MAC_MODER, status);}static void send_one_normal_frame(MAC_data_frame *frame){	send_one_frame(frame, send_frame);}static void send_one_frame(MAC_data_frame *frame, u8 *send_buf){	u8 *psend = NULL;	u32 status = 0;	u32 i = 0;	psend = send_buf;	for (i=0;i<6;i++)		psend[i] = frame->des_addr[i];	for (i=0;i<6;i++)		psend[6+i] = frame->src_addr[i];	*(u16 *)(psend + 12) = frame->length;	for (i=0;i<len-14;i++)		psend[14+i] = send_data[i];	/* Turn on transfer */	status &= ~BIT_MAC_TX_BD_READY;	status |= BIT_MAC_TX_BD_IRQ|BIT_MAC_TX_BD_WRAP|BIT_MAC_TX_BD_PAD|BIT_MAC_TX_BD_CRC;	status &= 0x0000ffff;	status |= (len) << 16;	ETH_SET32(DIS_TXBD_BUF, status);	ETH_SET32(DIS_TXBD_BUF, status|BIT_MAC_TX_BD_READY);		status = ETH_GET32(DIS_TXBD_BUF);	serial_puts("\nDIS_TXBD_BUF:");	serial_put32(status);}static void wait_for_tx_init(){	u32 status = 0;	u32 time_out = 0x10000;	/*	   do {	   status = ETH_GET32(DIS_TXBD_BUF);	   } while ((status & BIT_MAC_TX_BD_READY) && time_out--);	 */	serial_puts("\nWaiting for TXBD complete\n");	while(ETH_GET32(DIS_TXBD_BUF) & BIT_MAC_TX_BD_READY);	if (time_out)	{		serial_puts("Data has send out\n");		status = ETH_GET32(DIS_TXBD_BUF);		serial_puts("wait_for_tx_init:TXDB:");		serial_put32(status);		status = ETH_GET32(REG_MAC_INT_SOURCE);		serial_puts("\nwait_for_tx_init:INT Source:");		serial_put32(status);		ETH_SET32(REG_MAC_INT_SOURCE, status);		ETH_SET32(DIS_TXBD_BUF, 0);	}	else	{		serial_puts("Time Out\n");	}}static int compare_data(MAC_data_frame *s_frame, MAC_data_frame *r_frame){	int i = 0;	for (i=0;i<6;i++)	{		if (s_frame->des_addr[i] != r_frame->des_addr[i])			return -1;		if (s_frame->src_addr[i] != r_frame->src_addr[i])			return -1;	}	if (s_frame->length != r_frame->length)		return -1;	for (i=0;i<s_frame->length;i++)		if (send_frame[14+i] != rev_frame[14+i])			return -1;	return 0;}static void send_one_huge_frame(MAC_data_frame *frame){	send_one_frame(frame, send_frame);}static void send_one_small_frame(MAC_data_frame *frame){	send_one_frame(frame, send_frame);}static void wait_for_rx_init(){	while (ETH_GET32(DIS_TXBD_BUF + (TX_BD_NUM<<3)) & BIT_MAC_RX_BD_EMPTY);}static void read_rx_normal_frame(MAC_data_frame *frame){	u32 status = 0;	u32 irq_reg = 0;	u32 frame_len = 0;	/* Data arrived. Read out RXBD register and interrupt source register */	status = ETH_GET32(DIS_TXBD_BUF + (TX_BD_NUM<<3));	serial_puts("\nread_rx_normal_frame:RXDB:");	serial_put32(status);	irq_reg = ETH_GET32(REG_MAC_INT_SOURCE);	ETH_SET32(REG_MAC_INT_SOURCE, irq_reg);	serial_puts("\nread_rx_normal_frame:INT Source:");	serial_put32(irq_reg);	serial_putc('\n');	frame_len = (status >> 16) & 0xffff;	dump_data(rev_frame, frame_len);		/* Ready to receive datas */	status = (1518 << 16);	status |= BIT_MAC_RX_BD_EMPTY|BIT_MAC_RX_BD_IRQ|BIT_MAC_RX_BD_WRAP;	ETH_SET32(DIS_TXBD_BUF + (TX_BD_NUM<<3), status);	serial_puts("\nRX ready\n");}

⌨️ 快捷键说明

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