📄 netdrv.c
字号:
/*******************************************************************
*******************************************************************/
#include "..\system.h"
#ifdef INTEL_X86_CPU
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#endif
#include "..\utility.h"
#include "..\hardware.h"
#include "ne2000.h"
#include "NetDrv.h"
/************************** 8019 port operation ****************************/
/* Wrap 8019 write port operation */
#define rtl8019Write(RTL_ADDRESS, RTL_DATA) (outp((io_address) \
+ ((unsigned char)(RTL_ADDRESS)) , (unsigned short)(RTL_DATA)))
/* Wrap 8019 read port operation */
#define rtl8019Read(RTL_ADDRESS) (inp((io_address) \
+ ((unsigned char)(RTL_ADDRESS)) ))
/*************************** 调试变量和函数 ********************************/
#if defined(INTEL_X86_CPU) && defined(DEBUG)
INT16U sndok = 0; /* 发送成功次数 */
#endif
INT16U usrdatalen = 0; /* user data length */
INT16U rcvErrStatus = 0; /* receiving error status */
#ifdef ARM_XSCALE_CPU
unsigned char nextPage = 0;
unsigned short curAddress = 0;
#endif
/***************************** 局部变量定义 ********************************/
NET_CONFIG_STRUCT NetConfig[MAX_CARD_NUMBER]; /* 网络配置数组 */
/**************************** 函数声明 *************************************/
static void rtl8019Init(INT16U CardID); /* 8019as芯片初始化 */
static void rtl8019ReadMAC(INT16U CardID); /* 读芯片MAC地址 */
static void rtl8019Overrun(INT16U CardID); /* 芯片溢出处理 */
/**************************** 全局函数定义 *********************************/
/* 初始化网络配置数组 */
void NetCfgInit(void) {
NetConfig[0].CardID = 0;
NetConfig[0].IOAddr = NET0_IOBADDR;
NetConfig[1].CardID = 1;
NetConfig[1].IOAddr = NET1_IOBADDR;
NetConfig[2].CardID = 2;
NetConfig[2].IOAddr = NET2_IOBADDR;
NetConfig[3].CardID = 3;
NetConfig[3].IOAddr = NET3_IOBADDR;
}
/*
函数名 : netOpen
功能 : 网卡芯片检测,初始化
参数 : CardID 网卡逻辑编号
返回值 : 初始化是否正确
0x00 正确
0xFF 网卡不存在
*/
INT8U netOpen(INT16U CardID) {
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
if (0xFF == ReadPort(io_address)) {
return(0xFF);
}
rtl8019ReadMAC(CardID); /* Read the Physical Address */
rtl8019Init(CardID); /* Initialize */
return(0x00);
}
void netClose(INT16U CardID) {
CardID = CardID;
}
/*
函数名 : rtl8019Receive
功能 : 8019As接收以太网帧
参数 : CardID 网卡逻辑编号
buffer 接收缓冲区指针
返回值 : 接收是否成功 TRUE 成功 FALSE 失败
*/
BOOL rtl8019Receive(INT16U CardID, INT8U *buffer)
{
unsigned short in = 0, out = 0;
unsigned short i = 0;
unsigned short rxlen = 0;
unsigned char header[4] = {0, 0, 0, 0};
#ifdef INTEL_X86_CPU
static unsigned char nextPage = 0;
static unsigned short curAddress = 0;
#endif
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
/* read CURR from page 1 */
rtl8019Write(CR, 0x62);
in = rtl8019Read(CURR);
rtl8019Write(CR, 0x22); /* return to page 0 */
out = rtl8019Read(BNDRY); /* Get the boundary register */
/* return if there is no packet in the buffer */
if (in == out) {
rcvErrStatus = (NET_ERROR|0x03);
usrdatalen = 0;
return(FALSE);
}
/* Clear the packet received interrupt flag */
rtl8019Write(ISR, (1 << ISR_PRX) );
/* If the boundary pointer is invalid,reset the buffer then exit */
if ( (out >= RXSTOP_INIT) || (out < RXSTART_INIT) )
{
rtl8019Write(BNDRY, RXSTART_INIT);
rtl8019Write(CR, 0x62);
rtl8019Write(CURR, RXSTART_INIT);
rtl8019Write(CR, 0x22);
rcvErrStatus = (NET_ERROR|0x04);
usrdatalen = 0;
return(FALSE);
}
/* Initiate DMA to transfer the packet header: */
/* statrs(1), nextptr(1), bytecount(2) */
rtl8019Write(RBCR0, 4);
rtl8019Write(RBCR1, 0);
rtl8019Write(RSAR0, 0);
rtl8019Write(RSAR1, out);
rtl8019Write(CR, 0x0A);
for (i = 0; i < 4; i++ ) {
header[i] = (unsigned char)rtl8019Read(NIC_DATA);
}
/* End the DMA operation */
rtl8019Write(CR, 0x22);
for (i = 0; i < 50; i++ ) {
if ( rtl8019Read(ISR) & (1 << 6) ) {
break;
}
}
rtl8019Write(ISR, 1 << 6 );
rxlen = (header[PACKET_LENHIGH] << 8) + header[PACKET_LENLOW];
nextPage = header[PACKET_NEXTBLK];
curAddress = (out << 8) + 4;
/* If the nextPage pointer is invalid,the packet is not ready yet,exit */
if ( (nextPage >= RXSTOP_INIT) || (nextPage < RXSTART_INIT) ) {
rcvErrStatus = (NET_ERROR|0x05);
usrdatalen = 0;
return(FALSE);
}
rxlen -= 4;
/* Initial DMA to transfer data */
rtl8019Write(RBCR0, rxlen);
rtl8019Write(RBCR1, (rxlen >> 8));
rtl8019Write(RSAR0, curAddress);
rtl8019Write(RSAR1, (curAddress >> 8));
rtl8019Write(CR, 0x0A);
/* Ignore Dest. MAC(6), Src MAC(6), type/len(2) */
for (i = 0; i < 14; i++ ) {
rtl8019Read(NIC_DATA);
}
usrdatalen = rxlen - 14;
for (i = 0; i < rxlen - 14; i++ ) {
buffer[i] = (unsigned char)rtl8019Read(NIC_DATA);
}
/* End the DMA operation */
rtl8019Write(CR, 0x22);
for (i = 0; i < 50; i++ ) {
if ( rtl8019Read(ISR) & (1 << ISR_RDC) ) {
break;
}
}
rtl8019Write(ISR, 1 << ISR_RDC );
curAddress += rxlen;
if ( curAddress >= RXSTOP_ADDRESS ) {
curAddress = curAddress - (RXSTOP_ADDRESS - RXSTART_ADDRESS);
}
/* End the DMA operation */
rtl8019Write(CR, 0x22);
for (i = 0; i <= 50; i++) {
if (rtl8019Read(ISR) & (1 << ISR_RDC) ) {
break;
}
}
rtl8019Write(ISR, 1 << ISR_RDC);
/* Set the boundary register to point to the start of the next packet */
rtl8019Write(BNDRY, nextPage);
rcvErrStatus = 0;
return(TRUE);
}
/*
函数名 : rtl8019Send
功能 : 8019As发送以太网帧
参数 : CardID 网卡逻辑编号
destMAC 目标MAC数组指针
buffer 发送缓冲区指针
len 数据长度
返回值 : void
*/
void rtl8019Send(INT16U CardID, INT8U * destMAC, INT8U * buffer, long int len)
{
long int i = 0;
long int length = 0;
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
length = len;
#ifdef INTEL_X86_CPU
_disable();
#endif
rtl8019Write(CR, 0x22); /* Abort Remote DMA,start command */
/* Still transmitting a packet - wait for it to finish */
while ( rtl8019Read(CR) & 0x04 ) ;
length += 14; /* include the length of DA,SA,Type */
/* Load data byte count for remote DMA */
rtl8019Write(RBCR0, length);
rtl8019Write(RBCR1, (length >> 8));
/* Set start address for remote DMA operation */
rtl8019Write(RSAR0, 0x00);
rtl8019Write(RSAR1, 0x40);
rtl8019Write(CR, 0x12); /* Remote write operation */
/* write frame */
for (i = 0 ; i < MACLEN ; i++) { /* destination mac address */
rtl8019Write(NIC_DATA, (destMAC[i]));
}
for ( i = 0 ; i < MACLEN ; i++) { /* source mac address */
rtl8019Write(NIC_DATA, (NetConfig[CardID].LocalMAC[i]));
}
rtl8019Write(NIC_DATA, len >> 8);
rtl8019Write(NIC_DATA, len&0xff);
for (i = 0 ; i < len ; i++) {
rtl8019Write(NIC_DATA, (*(buffer+i)));
}
/* End the DMA operation */
for (i = 0; i < 400; i++) {
if (rtl8019Read(ISR) & (1 << ISR_RDC)) {
break;
}
}
rtl8019Write(ISR, (1 << ISR_RDC));
/* Load beginning page for transmit buffer */
rtl8019Write(TPSR, TXSTART_INIT);
rtl8019Write(TBCR0, length );
rtl8019Write(TBCR1, length >> 8);
/* Send the contents of the transmit buffer onto the network */
rtl8019Write(CR, 0x26);
#ifdef INTEL_X86_CPU
_enable();
#endif
}
/* Process Receive Overflow */
void rtl8019ProcessInterrupt(INT16U CardID) {
#if defined(INTEL_X86_CPU) && defined(DEBUG)
static INT16U noverflow = 0;
#endif
INT16U io_address = 0;
INT8U byte = 0;
io_address = NetConfig[CardID].IOAddr;
byte = (unsigned char)rtl8019Read(ISR);
if ( byte & (1 << ISR_OVW) ) {
rcvErrStatus = (NET_ERROR|0x06);
usrdatalen = 0;
rtl8019Overrun(CardID);
#if defined(INTEL_X86_CPU) && defined(DEBUG)
wprintf(12, 40, "Net%d overflow %u", CardID, noverflow++);
#endif
}
}
/* whether the receive buffer is empty? */
BOOL IsEmpty(INT16U CardID) {
unsigned short in = 0, out = 0;
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
rtl8019Write(CR, 0x62);
in = rtl8019Read(CURR);
rtl8019Write(CR, 0x22);
out = rtl8019Read(BNDRY);
if (in == out) {
return(TRUE);
} else {
return(FALSE);
}
}
/* whether the transmition is completed */
BOOL IsTransEnd(INT16U CardID) {
INT16U io_address = 0;
INT8U byte = 0;
io_address = NetConfig[CardID].IOAddr;
byte = (unsigned char)rtl8019Read(ISR);
if (byte & (1 << ISR_TXE)) {
rtl8019Write(ISR, (1 << ISR_TXE) );
#if defined(INTEL_X86_CPU) && defined(DEBUG)
wprintf(13, 50, "Net%d TXE error", CardID);
#endif
return(TRUE);
}
if (byte & (1 << ISR_PTX)) {
rtl8019Write(ISR, (1 << ISR_PTX) );
#if defined(INTEL_X86_CPU) && defined(DEBUG)
sndok++;
#endif
return(TRUE);
} else {
return(FALSE);
}
}
/**************************** 局部函数定义 *********************************/
static void rtl8019Init(INT16U CardID) {
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
#ifdef ARM_XSCALE_CPU
nextPage = 0;
curAddress = 0;
#endif
rtl8019Write(CR, 0x21);
rtl8019Write(NIC_RESET, 0xFF);
#ifdef INTEL_X86_CPU
Delay(100);
#endif
rtl8019Write(CR, 0x21); /* Page 0,Abort DMA,Stop Command */
rtl8019Write(DCR, DCR_INIT);
rtl8019Write(RBCR0, 0x00); /* Clear remote byte count registers */
rtl8019Write(RBCR1, 0x00);
rtl8019Write(RCR, 0x14);
rtl8019Write(TPSR, TXSTART_INIT);
rtl8019Write(TCR, 0x02); /* Internal Loop Back */
rtl8019Write(BNDRY, RXSTART_INIT); /* Start of Buffer RAM */
rtl8019Write(PSTART, RXSTART_INIT); /* Start of Buffer RAM */
rtl8019Write(PSTOP, RXSTOP_INIT); /* 8-bit mode */
rtl8019Write(CR, 0x61);
rtl8019Write(CURR, RXSTART_INIT);
/*
Physical_Address is not initialized on the first pass. We need to
read it from the 93C46 and set it during initialization
*/
rtl8019Write(PAR0, NetConfig[CardID].LocalMAC[0]);
rtl8019Write(PAR1, NetConfig[CardID].LocalMAC[1]);
rtl8019Write(PAR2, NetConfig[CardID].LocalMAC[2]);
rtl8019Write(PAR3, NetConfig[CardID].LocalMAC[3]);
rtl8019Write(PAR4, NetConfig[CardID].LocalMAC[4]);
rtl8019Write(PAR5, NetConfig[CardID].LocalMAC[5]);
rtl8019Write(CR, 0x22);
rtl8019Write(ISR, 0xFF); /* Clear Interrupt Status Register */
rtl8019Write(IMR, IMR_INIT); /* Setup Interrupt Mask Register */
rtl8019Write(TCR, TCR_INIT); /* Take the NIC out of Loop Back. */
}
/* Read 8019AS MAC address from Remote DMA Port */
static void rtl8019ReadMAC(INT16U CardID)
{
int ignore = 0;
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
rtl8019Write(CR, 0x22); /* Page0,Abort Remote DMA,Start Command */
rtl8019Write(RBCR0, 0xFF); /* Set maximum number of bytes to read/write */
rtl8019Write(RBCR1, 0xFF);
rtl8019Write(RSAR0, 0);
rtl8019Write(RSAR1, 0);
rtl8019Write(CR, 0x0A); /* Page0,Remote Read,Start Command */
NetConfig[CardID].LocalMAC[0] = (INT8U)rtl8019Read(NIC_DATA);
ignore = rtl8019Read(NIC_DATA);
NetConfig[CardID].LocalMAC[1] = (INT8U)rtl8019Read(NIC_DATA);
ignore = rtl8019Read(NIC_DATA);
NetConfig[CardID].LocalMAC[2] = (INT8U)rtl8019Read(NIC_DATA);
ignore = rtl8019Read(NIC_DATA);
NetConfig[CardID].LocalMAC[3] = (INT8U)rtl8019Read(NIC_DATA);
ignore = rtl8019Read(NIC_DATA);
NetConfig[CardID].LocalMAC[4] = (INT8U)rtl8019Read(NIC_DATA);
ignore = rtl8019Read(NIC_DATA);
NetConfig[CardID].LocalMAC[5] = (INT8U)rtl8019Read(NIC_DATA);
ignore = rtl8019Read(NIC_DATA);
}
static void rtl8019Overrun(INT16U CardID) /* 芯片溢出处理 */
{
unsigned char data_L = 0, resend = 0;
INT16U io_address = 0;
io_address = NetConfig[CardID].IOAddr;
data_L = (unsigned char)rtl8019Read(CR);
rtl8019Write(CR, 0x21);
#ifdef INTEL_X86_CPU
Delay(10);
#endif
rtl8019Write(RBCR0, 0x00);
rtl8019Write(RBCR1, 0x00);
if (!(data_L & 0x04)) {
resend = 0;
} else if (data_L & 0x04) {
data_L = (unsigned char)rtl8019Read(ISR);
if ((data_L & 0x02) || (data_L & 0x08)) {
resend = 0;
} else {
resend = 1;
}
}
rtl8019Write(TCR, 0x02);
rtl8019Write(CR, 0x22);
rtl8019Write(BNDRY, RXSTART_INIT);
rtl8019Write(CR, 0x62);
rtl8019Write(CURR, RXSTART_INIT);
rtl8019Write(CR, 0x22);
rtl8019Write(ISR, 0x10);
rtl8019Write(TCR, TCR_INIT);
if (resend) {
rtl8019Write(CR, 0x26);
}
rtl8019Write(ISR, 0xFF);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -