📄 ne2kif.c.svn-base
字号:
/*
* 04/27/2003: delete code: set mac addr manually,
* add code: get mac addr from skyeye ne2k nic, which get from skyeye.conf
* chenyu <chenyu@hpclab.cs.tsinghua.edu.cn>
* 01/21/2003: ne2k driver for lwip(OS independent) initial version
* yangye <yangye@163.net>
*/
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "arch/cc.h"
#include "netif/arp.h" //nothingbn 05_12_10
#include "netif/ne2kif.h"
#include "globe.h"
#include "includes.h"
#include "delay.h"
#define IP4_ADDRH(a,b,c,d) ((unsigned int)(a & 0xff) << 24) | ((unsigned int)(b & 0xff) << 16) | \
((unsigned int)(c & 0xff) << 8) | (unsigned int)(d & 0xff)
NODE locnode = {{0x12,0x34,0x56,0x78,0x90,0xab}, //MAC address
IP4_ADDRH(192,168,14,138), //local IP not used!!
IP4_ADDRH(255,255,255,0), //subnet mask not used!!
IP4_ADDRH(192,168,14,33), //net gate IP not used!!
8080}; // not used!!
struct RTL8019if {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
const struct eth_addr ethbroadcast = {0xff,0xff,0xff,0xff,0xff,0xff};
struct netif *rtl8019if_netif; //points to the real netif ,used by ne2k_isr
static void ne2k_copyin(u16_t count, u8_t *buf);
static void ne2k_copyout(u16_t count, u8_t *buf);
static void ne2k_discard(u16_t count);
void ne2k_isr(void);
void enbale_net_irq(void); //nothingbn 06_01_03
static void low_level_init(struct netif * netif);
static struct pbuf * low_level_receive(struct RTL8019if *rtl8019if);
static err_t low_level_send(struct RTL8019if *rtl8019if,struct pbuf *p);
/*
* Read the specified number of bytes from the device DMA port into
* the supplied buffer.
*/
static void ne2k_copyin(u16_t count, u8_t *buf)
{
while(count--) {
*buf++ = inb(NE_DMA);
}
}
//sdy060616 //add DMA function
/*static void ne2k_copyin(u16_t count, u8_t *buf)
{
//unsigned int t_count;
unsigned int temp;
INT8U err;
if(count <= 18)
{
while(count--)
{
*(buf++) = inb(NE_DMA);
}
return;
}
temp = rZDISRC0;
//t_count = count;
//IDADDR = buf//DAS = 01(increment)//OPT = 10(normal)
temp = rZDIDES0;
temp = temp & 0xf0000000;
temp = ((unsigned int)buf & 0x0fffffff) | temp ;
rZDIDES0 = temp ;
//ICNT = count//EN = 0(disable)//AR = 0(disable)//INTS = 11(whenever terminal count)
//OTF = 00(N/A)//TMD = 00(not used)//QTY = 10(Whole Service)//QSC = 10(N/A)
temp = rZDICNT0;
temp = temp & 0xfff00000;
temp = count | temp;
rZDICNT0 = temp;
temp = rZDICNT0;
temp = temp | (0x1<<20);
rZDICNT0 = temp;
temp = rZDCSRC0;
temp = rZDCDES0;
temp =rZDCCNT0;
temp = rZDCON0;
temp = temp | (0x1);
//start ZDNA0
rZDCON0 = temp;
temp = rZDCSRC0;
temp = rZDCDES0;
temp =rZDCCNT0;
OSSemPend(g_sem_ZDMA0IRQ, (INT16U)0, &err);
}*/
/*
* Write the specified number of bytes from the device DMA port into
* the supplied buffer.
*/
static void ne2k_copyout(u16_t count, u8_t *buf)
{
while(count--) {
outb(*buf++,NE_DMA);
}
}
/*
* Pull the specified number of bytes from the device DMA port,
* and throw them away.
*/
static void ne2k_discard(u16_t count)
{
u8_t tmp;
while(count--) {
tmp = inb(NE_DMA);
}
}
//change to DMA model. sdy060612
/*// void NICISR(void) interrupt
void ne2k_isr(void)
{
u8_t isr,curr,bnry;
struct netif *netif;
//close nic
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
//in PAGE0
isr = inb(NE_ISR);
// ram overflow interrupt
if (isr & ISR_OVW) {
outb(ISR_OVW,NE_ISR); // clear interrupt
// ne2k_overflowProcess(); //yangye :no overflow now
}
// error transfer interrupt ,NIC abort tx due to excessive collisions
if (isr & ISR_TXE) {
outb(ISR_TXE,NE_ISR); // clear interrupt
//temporarily do nothing
}
// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
if (isr & ISR_RXE) {
outb(ISR_RXE,NE_ISR); // clear interrupt
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP,NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
outb(curr, NE_BNRY);
}
//got packet with no errors
if (isr & ISR_PRX) {
outb(ISR_PRX, NE_ISR); // clear interrupt
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
bnry = inb(NE_BNRY);
//yangye 2003-1-21
//get more than one packet until receive buffer is empty
while(curr != bnry){
ne2k_recv_packet(rtl8019if_netif);
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
bnry = inb(NE_BNRY);
}
}
//Transfer complelte, do nothing here
if( isr & ISR_PTX){
PRINT("ne2k_isr: is ISR_PTX\n");
outb(ISR_PTX, NE_ISR); // clear interrupt
}
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
outb(0xff, NE_ISR); // clear ISR
//nothingbn 06_01_09
//clear ISR on 44b0
rI_ISPC=BIT_EINT1;
//open nic for next packet
outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
}*/
void ne2k_isr(void)
{
u8_t isr,curr,bnry;
struct netif *netif;
//close nic
//outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);//sdy060613
//in PAGE0
isr = inb(NE_ISR);
// ram overflow interrupt
if (isr & ISR_OVW) {
outb(ISR_OVW, NE_ISR); // clear interrupt
// ne2k_overflowProcess(); //yangye :no overflow now
}
// error transfer interrupt ,NIC abort tx due to excessive collisions
if (isr & ISR_TXE) {
outb(ISR_TXE, NE_ISR); // clear interrupt
//temporarily do nothing
}
// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
if (isr & ISR_RXE) {
outb(ISR_RXE, NE_ISR); // clear interrupt
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP,NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
outb(curr, NE_BNRY);
}
//got packet with no errors
if (isr & ISR_PRX) {
outb(ISR_PRX, NE_ISR); // clear interrupt
//sdy060612
OSSemPost(g_sem_NetIRQ);
/*outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
bnry = inb(NE_BNRY);
//yangye 2003-1-21
//get more than one packet until receive buffer is empty
while(curr != bnry){
ne2k_recv_packet(rtl8019if_netif);
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
bnry = inb(NE_BNRY);
}*/
}
//Transfer complelte, do nothing here
if( isr & ISR_PTX){
PRINT("ne2k_isr: is ISR_PTX\n");
outb(ISR_PTX, NE_ISR); // clear interrupt
}
//outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);//sdy060613
outb(0xff, NE_ISR); // clear ISR
//clear ISR on 44b0
rI_ISPC=BIT_EINT1;
//open nic for next packet
outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
}
//nothingbn 06_01_03
/**
* Enable the EINT on 44b for ne2kif
*
*/
void enable_net_irq(void)
{
/* #if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
*/
//OS_ENTER_CRITICAL();
/*rINTMSK &= ~(BIT_EINT1);
rI_ISPC = BIT_EINT1;
pISR_EINT1 = (U32)ne2k_isr;*/
pISR_EINT1 = (U32)ne2k_isr; //sdy060612
rI_ISPC = BIT_EINT1;
rINTMSK &= ~(BIT_EINT1);
//OS_EXIT_CRITICAL();
}
/**
* Initialize the rtk8019as, resetting the interface and getting the ethernet
* address.
*/
static void
low_level_init(struct netif * netif)
{
u8_t i;
struct RTL8019if *rtl8019if;
u8_t mac_addr[6];
outb(0x22, NE_CR);
rtl8019if = netif->state;
//yangye 2003-1-21
//get mac addr from ne2k PROM
//ft! sim_ne2k not support dma read now!
//hack : manual write mac addr
//chy 2003-04-27: delete below code
/*
{
mac_addr[0] = 0;
mac_addr[1] = 1;
mac_addr[2] = 2;
mac_addr[3] = 3;
mac_addr[4] = 4;
mac_addr[5] = 5;
}
*/
//to do: add dam read for sim_ne2k
/*
* Initialize physical device
*/
//write and read 0x1f to reset the nic
outb(0, NE_RESET);
i=inb(NE_RESET); //nothingbn 05_12_30
//delay at least 10ms
//Delay(0);
//Delay(800);
OSTimeDly(5); //sdy060612
//in PAGE0
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
//Delay(40);
//OSTimeDly(10); //sdy060612
/* FIFO threshold = 8 bytes, normal operation, 8-bit byte write DMA, BOS=0 */
outb(DCR_LS | DCR_FIFO8, NE_DCR);
outb(0, NE_RBCR0);
outb(0, NE_RBCR1);
#if 0 //yangye: don't use in skyeye , maybe later
/*
* Promicuous receive(receive all the packets), including bad packets.
*/
outb(RCR_AB | RCR_AM | RCR_SEP | RCR_PRO, NE_RCR);
#else
/*
* Allow broadcast packets, in addition to packets unicast to us.
* Multicast packets that match MAR filter bits will also be
* allowed in.
*/
outb(RCR_AB, NE_RCR);
#endif
//Place the SNIC in LOOPBACK mode 1 or 2 (Transmit Configuration Register e 02H or 04H)
outb(TCR_LOOP_INT, NE_TCR);
outb(XMIT_START >> 8, NE_TPSR);
outb(RECV_START >> 8, NE_PSTART);
outb(RECV_START >> 8, NE_BNRY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -