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

📄 mac.c

📁 bootloader
💻 C
字号:
#include "types.h"#include "bios.h"#include "bioscall.h"#include "eth.h"#include "board.h"#include "mac.h"#include "utils.h"static struct frame_desc_struct rx_fd[RX_FRAME_SIZE];static struct frame_desc_struct tx_fd[TX_FRAME_SIZE];static struct frame_buf_struct rx_buf[RX_FRAME_SIZE];static struct frame_buf_struct tx_buf[TX_FRAME_SIZE];static unsigned long gtx_ptr;static unsigned long grx_ptr;static void s3c4510_eth_fd_init(void){	struct frame_desc_struct *fd_ptr;	struct frame_desc_struct *fd_start_ptr;	struct frame_desc_struct *fd_last_ptr = NULL;	unsigned long fb_base;	unsigned long i;	// TxfdInitialize() in diag code	// Get Frame descriptor's base address	// +0x4000000 is for setting this area to non-cacheable area.	outl((unsigned long)tx_fd | NOCACHE_BIT, BDMATXPTR);	gtx_ptr =  inl(BDMATXPTR);	// Get Transmit buffer base address.	fb_base = (unsigned long)tx_buf | NOCACHE_BIT;	// Generate linked list.	fd_start_ptr = fd_ptr = (struct frame_desc_struct *)gtx_ptr;	fd_last_ptr = NULL;	for(i = 0; i < TX_FRAME_SIZE; i++) {		fd_ptr->frame_data_ptr = (unsigned long)(fb_base & CPU_owner);		fd_ptr->reserved = 0;		fd_ptr->status_and_frame_lenght = (unsigned long)0x0;		if(fd_last_ptr != NULL)			fd_last_ptr->next_frame_desc = (unsigned long)fd_ptr;		fd_last_ptr = fd_ptr;		fd_ptr++;		fb_base += sizeof(struct frame_buf_struct);	}	//Make Frame descriptor to ring buffer type.	fd_last_ptr->next_frame_desc = (unsigned long)fd_start_ptr;	// RxFDInitialize() in diag code	// Get Frame descriptor's base address	outl((unsigned long)rx_fd  | NOCACHE_BIT, BDMARXPTR);	grx_ptr = inl(BDMARXPTR);	// Get recieve buffer base address	fb_base = (unsigned long)rx_buf | NOCACHE_BIT;	// Generate linked list	fd_start_ptr = fd_ptr = (struct frame_desc_struct *)grx_ptr;	fd_last_ptr = NULL;	for(i = 0; i < RX_FRAME_SIZE; i++) {		fd_ptr->frame_data_ptr = (unsigned long)(fb_base | BDMA_owner);		fd_ptr->reserved = 0;		fd_ptr->status_and_frame_lenght = (unsigned long)0x0;		if(fd_last_ptr != NULL )			fd_last_ptr->next_frame_desc = (unsigned long)fd_ptr;		fd_last_ptr = fd_ptr;		fd_ptr++;		fb_base += sizeof(struct frame_buf_struct);	}   	// Make Frame descriptor to ring buffer type.	fd_last_ptr->next_frame_desc = (unsigned long)fd_start_ptr;}int s3c4510_eth_init(unsigned char *mac_addr){	int i;	// reset BDMA and MAC	outl(BRxRS, BDMARXCON);	outl(BTxRS, BDMATXCON);	outl(MaxRxFrameSize, BDMARXLSZ);	outl(Reset, MACON);	outl(gMACCON, MACON);	s3c4510_eth_fd_init();	for(i = 0; i < 4; i++)		CAM_Reg(0) = (CAM_Reg(0) << 8) | mac_addr[i];	for(i = 4; i < 6; i++)		CAM_Reg(1) = (CAM_Reg(1) << 8) | mac_addr[i];	CAM_Reg(1) = (CAM_Reg(1) << 16); 	outl(0x0001, CAMEN);	outl(gCAMCON, CAMCON);	outl(gBDMATXCON, BDMATXCON);	outl(gMACTXCON, MACTXCON);	outl(gBDMARXCON, BDMARXCON);	outl(gMACRXCON, MACRXCON);		return 0;}int s3c4510_eth_send(unsigned char *data, int len){	struct frame_desc_struct *fd_ptr;	volatile unsigned long *fb_ptr;	unsigned char *fb_data;	int i;	// 1. Get Tx frame descriptor & data pointer	fd_ptr = (struct frame_desc_struct *)gtx_ptr;	fb_ptr = (unsigned long *)&fd_ptr->frame_data_ptr;	fb_data = (unsigned char *)fd_ptr->frame_data_ptr;	// 2. Check BDMA ownership	if(*fb_ptr & BDMA_owner)		return -1;	// 3. Prepare Tx Frame data to Frame buffer	memcpy(fb_data, data, len);	if (len < 60) {		for (i = len; i < 60; i++)			fb_data[i] = 0x00;		len = 60;	}	// 4. Set Tx Frame flag & Length Field	fd_ptr->reserved = (Padding | CRCMode | FrameDataPtrInc | LittleEndian | WA00 | MACTxIntEn);	fd_ptr->status_and_frame_lenght = (len & 0xFFFF);	// 5. Change ownership to BDMA	fd_ptr->frame_data_ptr |= BDMA_owner;	// 6. Enable MAC and BDMA Tx control register	outl(gBDMATXCON, BDMATXCON);	outl(gMACTXCON, MACTXCON);	// 7. Change the Tx frame descriptor for next use	gtx_ptr = (unsigned long)(fd_ptr->next_frame_desc);	return 0;}int s3c4510_eth_rcv(unsigned char *data, int *len){	struct frame_desc_struct *fd_ptr;	unsigned long rx_status;	unsigned long bdma_status;	unsigned char *tmp;	// 1. Get Rx Frame Descriptor	fd_ptr = (struct frame_desc_struct *)grx_ptr;	if (fd_ptr->frame_data_ptr & BDMA_owner)		return -1;	rx_status = (fd_ptr->status_and_frame_lenght >> 16) & 0xffff;	// 2. Get current frame descriptor and status	bdma_status = inl(BDMASTAT);	// 3. Clear BDMA status register bit by write 1	outl(bdma_status | S_BRxRDF, BDMASTAT);	// 4. If Rx frame is good, then process received frame	*len = 0;	if (rx_status & Good) {		*len = (fd_ptr->status_and_frame_lenght & 0xffff) - 4;		tmp = (unsigned char *)fd_ptr->frame_data_ptr + 2;		// 6. Get received frame to memory buffer		memcpy(data, tmp, *len);	}	// 5. Change ownership to BDMA for next use	fd_ptr->frame_data_ptr |= BDMA_owner;	// Save Current Status and Frame Length field, and clear	fd_ptr->status_and_frame_lenght = 0x0;	// 6. Get Next Frame Descriptor pointer to process	grx_ptr = (unsigned long)(fd_ptr->next_frame_desc);	// 7. Check Notowner status	if (inl(BDMASTAT) & S_BRxNO) {		outl(S_BRxNO, BDMASTAT);	}	if ((inl(MACRXSTAT) & 0x400) == 0x400) {		outl(gBDMARXCON, BDMARXCON);		outl(gMACRXCON, MACRXCON);	}	return 0;}int s3c4510_eth_exit(void){	outl(0, BDMATXCON);	outl(0, BDMARXCON);	outl(0, BDMATXPTR);	outl(0, BDMARXPTR);	outl(0, BDMASTAT);	outl(0, MACON);	outl(0, CAMCON);	outl(0, MACTXCON);	outl(0, MACTXSTAT);	outl(0, MACRXCON);	outl(0, MACRXSTAT);	outl(0, STADATA);	outl(0x00006000, STACON);	outl(0, CAMEN);	outl(0, EMISSCNT);	outl(0, EPZCNT);	outl(0, ERMPZCNT);//	outl(0, ETXSTAT);	return 0;}

⌨️ 快捷键说明

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