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

📄 ne2kif.c.svn-base

📁 lwip协议在arm7+uCos系统上的移植
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -