📄 rtl8019as.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 + -