📄 etherne.c
字号:
/* NE2000-compatible net card drivers
noice: this file only can work for "Byte-mode".*/
#include <stdio.h>
//#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include "..\Target\44blib.h"
#include "ether.h" /* Typedefs and function prototypes */
#include "netutil.h"
#include "net.h"
#define WORDMODE 0 /* Set to zero if using 8-bit XT-bus cards */
//---------8019 register define (ethernet.sch)------------------------------//
#define RTL8019_Base 0x08000000//Bank4 0x08000000~0x0c000000
#define RTL_Offset_00 0x0000 //Register (3 pages)
#define RTL_Offset_01 0x0100
#define RTL_Offset_02 0x0200
#define RTL_Offset_03 0x0300
#define RTL_Offset_04 0x0400
#define RTL_Offset_05 0x0500
#define RTL_Offset_06 0x0600
#define RTL_Offset_07 0x0700
#define RTL_Offset_08 0x0800
#define RTL_Offset_09 0x0900
#define RTL_Offset_0a 0x0a00
#define RTL_Offset_0b 0x0b00
#define RTL_Offset_0c 0x0c00
#define RTL_Offset_0d 0x0d00
#define RTL_Offset_0e 0x0e00
#define RTL_Offset_0f 0x0f00
#define RTL_Offset_10 0x1000 //DMA address
#define RTL_Offset_18 0x1800 //Reset address
#define RTL8019_REG_0 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_00))
#define RTL8019_REG_1 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_01))
#define RTL8019_REG_2 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_02))
#define RTL8019_REG_3 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_03))
#define RTL8019_REG_4 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_04))
#define RTL8019_REG_5 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_05))
#define RTL8019_REG_6 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_06))
#define RTL8019_REG_7 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_07))
#define RTL8019_REG_8 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_08))
#define RTL8019_REG_9 (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_09))
#define RTL8019_REG_A (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_0a))
#define RTL8019_REG_B (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_0b))
#define RTL8019_REG_C (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_0c))
#define RTL8019_REG_D (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_0d))
#define RTL8019_REG_E (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_0e))
#define RTL8019_REG_F (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_0f))
#define RTL8019_REG_DMA (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_10)) //1 byte
#define RTL8019_REG_DMA_HW (*(volatile unsigned short*)(RTL8019_Base+RTL_Offset_10))//2 byte
#define RTL8019_REG_RST (*(volatile unsigned char*)(RTL8019_Base+RTL_Offset_18))
/* NE2000 definitions */
#define DATAPORT RTL8019_REG_DMA//0x10
#define NE_RESET RTL8019_REG_RST//0x18
/* 8390 Network Interface Controller (NIC) page0 register offsets */
#define CMDR RTL8019_REG_0//0x00 /* command register for read & write */
#define PSTART RTL8019_REG_1//0x01 /* page start register for write */
#define PSTOP RTL8019_REG_2//0x02 /* page stop register for write */
#define BNRY RTL8019_REG_3//0x03 /* boundary reg for rd and wr */
#define TPSR RTL8019_REG_4//0x04 /* tx start page start reg for wr */
#define TBCR0 RTL8019_REG_5//0x05 /* tx byte count 0 reg for wr */
#define TBCR1 RTL8019_REG_6//0x06 /* tx byte count 1 reg for wr */
#define ISR RTL8019_REG_7//0x07 /* interrupt status reg for rd and wr */
#define RSAR0 RTL8019_REG_8//0x08 /* low byte of remote start addr */
#define RSAR1 RTL8019_REG_9//0x09 /* hi byte of remote start addr */
#define RBCR0 RTL8019_REG_A//0x0A /* remote byte count reg 0 for wr */
#define RBCR1 RTL8019_REG_B//0x0B /* remote byte count reg 1 for wr */
#define RCR RTL8019_REG_C//0x0C /* rx configuration reg for wr */
#define TCR RTL8019_REG_D//0x0D /* tx configuration reg for wr */
#define DCR RTL8019_REG_E//0x0E /* data configuration reg for wr */
#define IMR RTL8019_REG_F//0x0F /* interrupt mask reg for wr */
/* NIC page 1 register offsets */
#define PAR0 RTL8019_REG_1//0x01 /* physical addr reg 0 for rd and wr */
#define PAR1 RTL8019_REG_2//0x02
#define PAR2 RTL8019_REG_3//0x03
#define PAR3 RTL8019_REG_4//0x04
#define PAR4 RTL8019_REG_5//0x05
#define PAR5 RTL8019_REG_6//0x06
#define CURR RTL8019_REG_7//0x07 /* current page reg for rd and wr */
#define MAR0 RTL8019_REG_8//0x08 /* multicast addr reg 0 for rd and WR */
#define MAR1 RTL8019_REG_9//0x08
#define MAR2 RTL8019_REG_A//0x08
#define MAR3 RTL8019_REG_B//0x08
#define MAR4 RTL8019_REG_C//0x08
#define MAR5 RTL8019_REG_D//0x08
#define MAR6 RTL8019_REG_E//0x08
#define MAR7 RTL8019_REG_F//0x08
/* Buffer Length and Field Definition Info */
#define TXSTART 0x40 /* Tx buffer start page */
#define TXPAGES 6 /* Pages for Tx buffer */
#define RXSTART (TXSTART+TXPAGES) /* Rx buffer start page */
#if WORDMODE
#define RXSTOP 0x7e /* Rx buffer end page for word mode */
#define DCRVAL 0x49 /* DCR values for word mode */
#else
#define RXSTOP 0x5f /* Ditto for byte mode */
#define DCRVAL 0x48
#endif
#define STARHACK 0 /* Set non-zero to enable Starlan length hack */
typedef struct /* Net driver configuration data */
{
WORD dtype; /* Driver type */
BYTE myeth[MACLEN]; /* MAC (Ethernet) addr */
LWORD ebase; /* Card I/O base addr */
WORD next_pkt; /* Next (current) Rx page */
} CONFIGNE;
static CONFIGNE configs[MAXNETS]; /* Driver configurations */
static LWORD ebase; /* Temp I/O base addr; usually 280h for PC */
int promisc=0; /* Flag to enable promiscuous mode */
typedef struct { /* NIC hardware packet header */
BYTE stat; /* Error status */
BYTE next; /* Pointer to next block */
WORD len; /* Length of this frame incl. CRC */
} NICHDR;
NICHDR nichdr;
BYTE MYMAC[MACLEN]={0x01,0x12,0x34,0x56,0x67,0x89};
/* Private prototypes */
void resetnic(CONFIGNE *cp, char cold);
void getnic(WORD addr, BYTE data[], WORD len);
void putnic(WORD addr, BYTE data[], WORD len);
BYTE nicwrap(int page);
//BYTE innic(int reg);
//void outnic(int reg, int b);
extern void Delay(int time);
extern void Uart_Printf(char *fmt,...);
/* Initialise card given driver type and base addr.
** Return driver type, 0 if error */
int init_etherne(WORD dtype, LWORD baseaddr)
{
int ok=0;
CONFIGNE *cp;
cp = &configs[dtype & NETNUM_MASK]; /* Get pointer into driver data */
cp->dtype = dtype; /* Set driver type */
cp->ebase = ebase = baseaddr; /* Set card I/O base address */
//outnic(NE_RESET, innic(NE_RESET));
NE_RESET=0x03; /* Write a random number, then do reset */
Delay(100);
//if ((innic(ISR) & 0x80) == 0) /* Report if failed */
if((ISR & 0x80)==0)
{
Uart_Printf(" Ethernet card failed to reset!\n");
}
else
{
Uart_Printf("\nEthernet card success to reset!\n");
resetnic(cp, 1); /* Reset Ethernet card, get my addr */
ok = 1;
}
return(ok);
}
/* Close down ethernet controller */
void close_etherne(WORD dtype)
{
ebase = configs[dtype & NETNUM_MASK].ebase;
if (ebase)
{
//outnic(CMDR, 0x21);
CMDR=0x21; /* Stop, DMA abort, page 0 */
configs[dtype & NETNUM_MASK].ebase = 0;
}
}
/* Return pointer to my Ethernet addr, given driver type */
BYTE *etherne_addr(WORD dtype)
{
return(configs[dtype & NETNUM_MASK].myeth);
}
/* Poll network interface to keep it alive; send & receive frames */
void poll_etherne(WORD dtype)
{
WORD len;
static BYTE ebuff[MAXFRAMEC];
CONFIGNE *cp;
cp = &configs[dtype & NETNUM_MASK];
if (cp->ebase) /* If Ether card in use.. */
{
ebase = cp->ebase; /* Set card I/O address */
//outnic(ISR, 0x01);
ISR=0x01; /* Clear interrupt flag */
/* Transmit */
//while (!(innic(CMDR)&0x04) && /* While NIC ready & frame avail */
while(!(CMDR&0x04)&&(len=transmit_upcall(cp->dtype, ebuff, MAXFRAME))>0)
{ /* ..transmit frame */
put_etherne(cp->dtype, ebuff, len);
}
Delay(200);
/* Receive */
while ((len=get_etherne(cp->dtype, ebuff))>0)
{ /* Store frames in buff */
receive_upcall(cp->dtype, ebuff, len);
}
}
}
/* Get packet into buffer, return length (excl CRC), or 0 if none available */
WORD get_etherne(WORD dtype, void *pkt)
{
WORD len=0, curr;
BYTE bnry;
CONFIGNE *cp;
#if STARHACK
int hilen, lolen;
#endif
//Uart_Printf("\n Come to get_etherne");
cp = &configs[dtype & NETNUM_MASK];
ebase = cp->ebase;
//if (innic(ISR) & 0x10) /* If Rx overrun.. */
if(ISR & 0x10)
{
Uart_Printf(" NIC Rx overrun\n");
resetnic(cp, 0); /* ..reset controller (drastic!) */
}
//outnic(CMDR, 0x60);
CMDR=0x60; /* DMA abort, page 1 */
curr = CURR;//innic(CURR); /* Get current page */
//outnic(CMDR, 0x20);
CMDR=0x20; /* DMA abort, page 0 */
if (curr != cp->next_pkt) /* If Rx packet.. */
{
//Uart_Printf("\n Rx packet");
memset(&nichdr, 0xee, sizeof(nichdr)); /* ..get NIC header */
getnic((WORD)(cp->next_pkt<<8), (BYTE *)&nichdr, sizeof(nichdr));
#if STARHACK
hilen = nichdr.next - cp->next_pkt - 1;
lolen = nichdr.len & 0xff;
if (hilen < 0) /* Do len calc from NIC datasheet */
hilen = RXSTOP - cp->next_pkt + nichdr.next - RXSTART - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -