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

📄 rtl8019as.c

📁 RTL8019的驱动程序,平台是S3C44BOX,希望大家有用处
💻 C
字号:
/*------------------------------------------------------------------------ . RTL8019AS.c . This is a driver for RTL's 8019AS single-chip Ethernet device. . . (C) Copyright 2003
 . TCE Inc., Changzhou China
 . lu weixi <lu_weixi@163.com> ----------------------------------------------------------------------------*/#include "armboot.h"#include "command.h"#include "rtl8019.h"#include "net.h"#ifdef CONFIG_DRIVER_RTL8019

static const char version[] =	"RTL8019AS ethernet driver v1.0 2003/09/18\n";#define	RPSTART	0x4c
#define	RPSTOP	0x80
#define	SPSTART	0x40static unsigned int RBNRY;
#ifndef CONFIG_RTL8019_BASE#define CONFIG_RTL8019_BASE 0x6000000#endif#define RTL_BASE_ADDRESS CONFIG_RTL8019_BASE extern int eth_init(bd_t *bd);extern void eth_halt(void);extern int eth_rx(void);extern int eth_send(volatile void *packet, int length);//static int rtl_close(void);static int rtl_rcv(void);
static int rtl_open(void);static char rtl_mac_addr[] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8}; static unsigned char rtl_reset( void );static unsigned char rtl_reset( void ){	int i;
	
	RTL_outb(0x5a,RstAddr);
	i = 20000;		//old 20000
	while(i--);
	RTL_SELECT_BANK(0);
	return (RTL_inb(ISR)&0x80);
}
static int rtl_send_packet(volatile void *packet, int packet_length){	static int sFlag = 0;
	int i;
	unsigned char send_page;
	unsigned char *data;
	
	data = (unsigned char *)packet;
	
	send_page  = SPSTART;
	send_page += (sFlag&1)?6:0;
	sFlag++;			
		
	if(packet_length<60)	
		for(; packet_length<60; packet_length++)
			data[packet_length] = 0x20;		//just for pad, any data										
	
	RTL_SELECT_BANK(0);		
	RTL_outb(0x22,RCPORT);			
	RTL_outb(0,RSAR0);
	RTL_outb(send_page,RSAR1);
	RTL_outb(packet_length&0xff,RBCR0);	
	RTL_outb(((packet_length>>8)&0xff),RBCR1);			
	RTL_outb(0x12,RCPORT);							
	for(i=0; i<packet_length; i++)
	{					
		RTL_outb(data[i],RWPORT);		// tarns to ram
	}	
	while(RTL_inb(RCPORT)&4);
	RTL_outb(send_page,TPSR);
	RTL_outb(packet_length&0xff,TBCR0);	
	RTL_outb(((packet_length>>8)&0xff),TBCR1);				
	RTL_outb(0x1e,RCPORT);				// begin to send					

	return 0;
}static int rtl_open( void ){	int i;			RTL_SELECT_BANK(3);	
	RTL_outb(0xcf,CR9346);		//set eem1-0, 11 ,enable write config register
	RTL_outb(0x68,CONFIG3);		//clear pwrdn, sleep mode, set led0 as led_col, led1 as led_crs	old 0x68
	RTL_outb((RTL_inb(CONFIG1)|0x80),CONFIG1);
	RTL_outb(0x3f,CR9346); 		//disable write config register
	
	if(!rtl_reset())
	{
		printf("Rtl8019 Reset Failed!\n");
		printf("%x ", RTL_inb(ISR));
		return -1;
	}

	RTL_outb(0x21,RCPORT);		// set page 0 and stop 
	RTL_outb(RPSTART,Pstart);	// set Pstart 0x4c 
	RTL_outb(RPSTOP,Pstop);		// set Pstop 0x80 
	RTL_outb(RPSTART,BNRY);		// BNRY-> the last page has been read 	
	RTL_outb(SPSTART,TPSR);		// transmit page start register, 0x40 
	RTL_outb(0xcc,RCR);		// set RCR 0xcc 	
	RTL_outb(0xe0,TCR);		// set TCR 0xe0 	
	RTL_outb(0xc8,DCR);		// 8bit DMA 0xc8
	RTL_outb(0x03,IMR);		// set IMR 0x03
	RTL_outb(0xff,ISR);	
	
	RTL_SELECT_BANK(1);	
	RTL_outb(RPSTART+1,CURR);
	RTL_outb(0x00,MAR0);
	RTL_outb(0x41,MAR1);
	RTL_outb(0x00,MAR2);
	RTL_outb(0x80,MAR3);
	RTL_outb(0x00,MAR4);
	RTL_outb(0x00,MAR5);
	RTL_outb(0x00,MAR6);
	RTL_outb(0x00,MAR7);
	RTL_outb(0x22,RCPORT);		// set page 0 and start 
	
	RBNRY = RPSTART;
	
	i  = RTL_inb(ID8019L);		//READ RTL8019 ID
	i |= RTL_inb(ID8019H)<<8;
	RTL_SELECT_BANK(1);
	for(i=0; i<6; i++){
		RTL_outb(rtl_mac_addr[i],PAR0+i);	}
	
	return 0;}static int rtl_rcv( void ){	unsigned char RxPageBeg, RxPageEnd;
	unsigned char RxNextPage;
	unsigned char RxStatus;
	unsigned char *addr;
	int i, RxLength;
	int interrupts;	 
	
	RTL_SELECT_BANK(0);
	interrupts = RTL_inb(ISR);
	if(interrupts&1)
		RTL_outb(0x01,ISR);
	else	
		return 0;	
		
	RTL_SELECT_BANK(1);
	RxPageEnd = RTL_inb(CURR);

	RxPageBeg = RBNRY+1;
	if(RxPageBeg>=RPSTOP)
		RxPageBeg = RPSTART;		
		
	RTL_SELECT_BANK(0);
	RTL_outb(0x22,RCPORT);		
	RTL_outb(0,RSAR0);
	RTL_outb(RxPageBeg,RSAR1);
	RTL_outb(4,RBCR0);
	RTL_outb(0,RBCR1);
	RTL_outb(0x0a,RCPORT);
	RxStatus   = RTL_inb(RWPORT);
	RxNextPage = RTL_inb(RWPORT);	
	RxLength   = RTL_inb(RWPORT);
	RxLength  |= RTL_inb(RWPORT)<<8;
	
	if(RxLength>ETH_FRAME_LEN){
		if(RxPageEnd==RPSTART)
			RBNRY = RPSTOP-1;
		else
			RBNRY = RxPageEnd-1;						
		RTL_outb(RBNRY,BNRY);		 	
		return 0;		
	}
	
	if ( !(RxStatus & RS_ERRORS ) ){
		RTL_outb(4,RSAR0);
		RTL_outb(RxPageBeg,RSAR1);
		RTL_outb(RxLength,RBCR0);
		RTL_outb(RxLength>>8,RBCR1);	
		RTL_outb(0x0a,RCPORT);
		addr = (unsigned char *)NetRxPackets[0];
		for(i=0;i<=RxLength;i++){			
			if(i!=0){
				if(!(i&0xff)){
					RTL_outb(RxPageBeg,BNRY);				
					RxPageBeg++;
					if(RxPageBeg>=RPSTOP)
						RxPageBeg = RPSTART;					
				}	
			}		
			*(addr++) = RTL_inb(RWPORT);
		}
		NetReceive(NetRxPackets[0], RxLength);
		RBNRY = RxPageBeg;
		RTL_outb(RBNRY,BNRY);	
	} else {
		if(RxPageEnd==RPSTART)
			RBNRY = RPSTOP-1;
		else
			RBNRY = RxPageEnd-1;						
		RTL_outb(RBNRY,BNRY);		 	
		RxLength = 0;
	}
	
	return RxLength;
	
}/*static int rtl_close( void ){
	RTL_SELECT_BANK(0);	RTL_outb(0x21,RCPORT);	return 0;}*/int eth_init(bd_t *bd) 
{	printf("%s",version);	rtl_open();
		return 0;}void eth_halt()
{//	RTL_SELECT_BANK(0);//	RTL_outb(0x21,RCPORT);}int eth_rx()
{	return rtl_rcv();
}int eth_send(volatile void *packet, int length)
{	return rtl_send_packet(packet, length);
}

void rtl_set_mac_addr(const unsigned char *addr)
{	int i;	for (i=0; i < sizeof(rtl_mac_addr); i++){	    rtl_mac_addr[i] = addr[i];	}} #endif /* CONFIG_DRIVER_RTL8019 */

⌨️ 快捷键说明

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