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

📄 ethernet.c

📁 开发工具用EMBEST IDE进行开发,该程序是一个S3C44B0直接驱动网卡的程序,包括8019初始化,物理层收包发包,UDP的接收和发送,IP的发送和接收.已及ARM的地址解板,整个程序是自顶而下
💻 C
📖 第 1 页 / 共 2 页
字号:
	unsigned char bnry,curr;
	char j;
	page(0);
	
   	//bnry=reg03;		//bnry page have read 读页指针
   	bnry=nic_read(NIC_PG0_BNRY);
//Uart_Printf("\n in query_8019() fuction bnry== %x\n",bnry);
   	
   	
   	
	page(1);
	curr=nic_read(NIC_PG0_ISR);		//curr writepoint 8019写页指针
//Uart_Printf("\n in query_8019() fuction curr== %x\n",curr);

	page(0);
	if (curr==0)return;
	
	bnry++;
	
//	Uart_Printf("\n in query_8019() fuction bnry+1== %x\n",bnry);
	if (bnry>0x7f)	bnry=0x4c;
	if (bnry != curr)	
	{
	    event_word |= EVENT_ETH_ARRIVED;
	 //  event_word=0x1ff;
	//    Uart_Printf("\n in query_8019() in event_word== %x\n",event_word);
	}
//	   Uart_Printf("\n in query_8019() out event_word== %x\n",event_word);
	   
	nic_write(NIC_PG0_RBCR1, 0x00);
	nic_write(NIC_PG0_RBCR0, 0x00);
	nic_write(NIC_CR,NIC_CR_STA | NIC_CR_RD2);
	//reg0b=0x00; reg0a=0x00;  reg00=0x22;//complete dma page 0
}
//------------------------------------------------------------------------
// This functions checks 8019 status then sends an ethernet
// frame to it by calling an assembler function. 
//------------------------------------------------------------------------

void send_frame(unsigned char * outbuf, unsigned short len)/*发送一个数据包的命令,长度最小为60字节,最大1514字节*/
{
unsigned char i;
unsigned short ii;
	page(0);
	if(len<60)len=60;
	
	nic_write(0x00,0x22);
	txd_buffer_select=!txd_buffer_select;
//	Uart_Printf("\n txd_buffer_select== %x\n",txd_buffer_select);
  	if	(txd_buffer_select)
  	 nic_write(NIC_PG0_RSAR1, 0x40);
//		reg09=0x40 ;	//txdwrite highaddress
	else
		 nic_write(NIC_PG0_RSAR1, 0x46);
     //   reg09=0x46 ;	//txdwrite highaddress
      	 nic_write(NIC_PG0_RSAR0, 0x00);
	//reg08=0x00; 		//read page address low

 
    	nic_write(NIC_PG0_RBCR1, ((len >> 8) & 0xff));
//	reg0b=len>>8;		//read count high
		nic_write(NIC_PG0_RBCR0, ((len) & 0xff));
//	reg0a=len&0xff;		//read count low;
		nic_write(NIC_CR, 0x12);
//	reg00=0x12;			//write dma, page0
	for	(ii=0;ii<len;ii++)	
	{
		nic_write(NIC_IOPORT, *(outbuf+ii));
//	Uart_Printf("\n in ii= outuf== %d %x\n",ii,*(outbuf+ii));
	//   reg10=*(outbuf+ii);  
	}

	/* 以下3句为中止dma的操作,可以不要            */
	
	//reg0b=0x00;		//read count high   中止DMA操作
	nic_write(NIC_PG0_TBCR1, 0x00);
	nic_write(NIC_PG0_TBCR0, 0x00);
//	reg0a=0x00;		//read count low;
	nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
//	reg00=0x22;		//complete dma page 0

	for(i=0;i<16;i++)	//最多重发16次
	{
		for(ii=0;ii<1000;ii++)	//检查txp为是否为低
		{
			 if((nic_read(NIC_CR) & 0x04)==0)break;
			//if ((reg00&0x04)==0) break;
		}
		if ((nic_read(NIC_PG0_TSR)&0x01)!=0)break;
		//if ((reg04&0x01)!=0) break;	//表示发送成功
		nic_write(NIC_CR, 0x3e);
	//	reg00=0x3e;
	}
	nic_write(NIC_PG0_ISR,0xff);
	//reg07=0xff;
	if(txd_buffer_select)
		nic_write(NIC_PG0_TPSR,0x40);
		//reg04=0x40;	//txd packet start; 
	else
			nic_write(NIC_PG0_TPSR,0x46);
		//reg04=0x46;	//txd packet start; 
		nic_write(NIC_PG0_TBCR1,((len >> 8) & 0xff));
//	reg06=len>>8;	//high byte counter
		nic_write(NIC_PG0_TBCR0, ((len) & 0xff));
	//reg05=len&0xff;	//low byte counter
		nic_write(NIC_PG0_ISR,0xff);
	//reg07=0xff;
	nic_write(NIC_CR, 0x3e);
//	reg00=0x3e;		//to sendpacket;  
	free(outbuf);
	//printf("ETH:send  frame.\n");
}


//------------------------------------------------------------------------
// This function gets an incoming Ethernet frame from the 8019.
// There may be more than 1 waiting but just allocate memory for
// one and read one in.  Use the 8019 to queue incoming packets.
//------------------------------------------------------------------------
unsigned char * rcve_frame(void)
{
unsigned char bnry,curr,next_page;
unsigned short len, ii;
unsigned char temp;
unsigned char  * buf;

	page(0);
   	bnry=nic_read(NIC_PG0_BNRY);
//Uart_Printf("\n in rcve_frame fuction NIC_NIC_PG0_BNRY== %x\n",bnry);
   //	bnry=reg03;		//bnry page have read 
	page(1);
	curr=nic_read(NIC_PG1_CURR);
//Uart_Printf("\n in rcve_frame fuction NIC_GPO_CURR== %x\n",curr);
	//curr=reg07;		//curr writepoint 8019
	page(0);
	if ((curr==0))	return NULL;	
	next_page=bnry;
//Uart_Printf("\n in rcve_frame  Nfuction next_page== %x\n",next_page);
	bnry++;
//	Uart_Printf("\n in rcve_frame bnry+1    %x\n",bnry);
	if (bnry>0x7f)	bnry=0x4c;
	if (bnry!=curr)	
	{
		
		page(0);
		nic_write(NIC_PG0_RSAR1,bnry);
	//Uart_Printf("\n in rcve_frame  NIC_PR0_RSAR1== %x\n",bnry);
 		//reg09=bnry;		//read page address high
		nic_write(NIC_PG0_RSAR0,0x00);
		//reg08=0x00; 	//read page address low
		nic_write(NIC_PG0_RBCR1,0x00);
		//reg0b=0x00;		//read count high
		nic_write(NIC_PG0_RBCR0,0x04);
		//reg0a=4;		//read count low;
		nic_write(NIC_CR, 0x0a);
		//reg00=0x0a;		//read dma
		temp=nic_read(NIC_IOPORT);
//	Uart_Printf("\n in one next temp==    %x\n",temp);		
		temp=nic_read(NIC_IOPORT);
//	Uart_Printf("\n in two next temp==    %x\n",temp);
		//temp = reg10;		temp = reg10;
		
		next_page = temp-1;		//next page start-1
//	Uart_Printf("\n in one next next_page-1=    %x\n",next_page);	
		len=nic_read(NIC_IOPORT);
//	Uart_Printf("\n in two len low address==    %x\n",len);	
		temp=nic_read(NIC_IOPORT);
//	Uart_Printf("\n in two len  higa address==    %x\n",temp);		
		//	len = reg10;		temp = reg10;
		len += temp<<8;
//	Uart_Printf("\n in inter  len  address==    %x\n",len);
	 	nic_write(NIC_PG0_RBCR1, 0x00);
	nic_write(NIC_PG0_RBCR0, 0x00);
	nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
	 //	reg0b=0x00; reg0a=0x00;  reg00=0x22;//complete dma page 0

   		// Allocate enough memory to hold the incoming frame
		buf = (unsigned char  *)malloc(len);
		if (buf == NULL)
		{
			// out of RAM
			// Tell 8019 to skip the frame
			page(1);
			curr=nic_read(NIC_PG1_CURR);
			//curr=reg07; 	//page1
			page(0);		
	        bnry = curr -1;
	        if	(bnry < 0x4c) bnry =0x7f;
	        nic_write(NIC_PG0_BNRY,bnry);
	        
	       // reg03=bnry; 	//write to bnry   
			nic_write(NIC_PG0_ISR,0xff);
		//	reg07=0xff;		
			return NULL;
		}
		// This flag keeps track of allocated rcve memory
		rcve_buf_allocated = TRUE;
		// Call the assembler function to get the incoming frame
		
		 nic_write(NIC_PG0_RSAR1, bnry);
		//reg09=bnry;	//read page address high
		nic_write(NIC_PG0_RSAR0, 0x04);
		//reg08=4; 	//read page address low
		
		nic_write(NIC_PG0_RBCR1, ((len >> 8) & 0xff));
		nic_write(NIC_PG0_RBCR0, ((len) & 0xff));

			//reg0b=len>>8;	//read count high
		//reg0a=len&0xff;	//read count low;
		nic_write(NIC_CR, 0x0a);
		//reg00=0x0a;	//read dma
		buf=net_in_data;
	//	len=len-4;
        for(ii=0;ii<len;ii++)
        {
	    	//buf[ii]=reg10;
	    	buf[ii]=nic_read(NIC_IOPORT);
    	//	Uart_Printf("\n %x ",buf[ii]);		
        //	Uart_Printf("\n  buf[ii]======   %x ",buf[ii]);
        //	Uart_Printf("\n  ii======   %x\n ",ii);	
        }
        	nic_write(NIC_PG0_RBCR1, 0x00);
			nic_write(NIC_PG0_RBCR0, 0x00);
			nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2);
        
			//reg0b=0x00;	reg0a=0x00; reg00=0x22;	//dma complete  page0     
	   		// Return pointer to start of buffer
			bnry=next_page;
		if (bnry<0x4c)  bnry=0x7f;
		 nic_write(NIC_PG0_BNRY,bnry);
		//reg03=bnry; 	//write to bnry    
		nic_write(NIC_PG0_ISR,0xff);
 //       reg07=0xff;
		return (buf);	
//		printf("ETH:read  frame.\n");
	}
	return NULL;
}




void eth_send(unsigned char * outbuf, unsigned char * hwaddr, unsigned short ptype, unsigned short len)
{
	struct ETH_HEADER * eth;
   
   	eth = (struct ETH_HEADER  *)outbuf;
	  
	// Add 14 byte Ethernet header
		memcpy(eth->dest_hwaddr, hwaddr, 6);
		memcpy(eth->source_hwaddr, my_hwaddr, 6); 
  	 eth->frame_type = ntohs(ptype);

   // We just added 14 bytes to length
 //  EtherOutput(outbuf, len+14);
   send_frame(outbuf, len + 14);
 //  send_frame(outbuf,len+33);
}


//------------------------------------------------------------------------
// This is the handler for incoming Ethernet frames
//	This is designed to handle standard Ethernet (RFC 893) frames
// See "TCP/IP Illustrated, Volume 1" Sect 2.2
//------------------------------------------------------------------------
void eth_rcve(unsigned  char  * inbuf)
{
    struct ETH_HEADER  * eth;
   
   eth = (struct ETH_HEADER  *)inbuf;
   emtp=ntohs(eth->frame_type);
 //  	Uart_Printf("\n in eth_rvce  emtp==    %x\n",emtp);
   //	Uart_Printf("\n in eth_rvce  H==%x\n",(emtp>>8)&0xff);
   //	Uart_Printf("\n in eth_rvce L==%x\n",emtp&0xff);
   // Reject frames in IEEE 802 format where Eth type field
   // is used for length.  Todo: Make it handle this format
   if (emtp < 1520)
   {
 //  	Uart_Printf("\n is error data L==\n");
      return;      
   }

   // Figure out what type of frame it is from Eth header
   // Call appropriate handler and supply address of buffer
   switch (emtp)
   {
	   case ARP_PACKET:
	   Uart_Printf("\n is ARP_PACKET ARRIVER \n");
	   arp_rcve(inbuf);
	   break;
		      
	   case IP_PACKET:
	 //  Uart_Printf("\n is IP_PACKET ARRIVER \n");
	   ip_rcve(inbuf);
      break;

      default:
//		if (debug) printf("Error: Unknown pkt rcvd\n");
      break;
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -