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

📄 ne2kif_bak.c

📁 前段时间把lwip和ucos移植在44b0平台上,用的是hfrk44b0开发板.已经调试通过,并且在板子上运行正常.
💻 C
📖 第 1 页 / 共 2 页
字号:
 */static err_t low_level_send(struct RTL8019if *rtl8019if,struct pbuf *p){	struct pbuf *q;	u8_t isr;	u8_t chain;	u8_t * tr_ptr;	u16_t tr_len, temp_dw;	u16_t padLength,packetLength;	// Set up to transfer the packet contents to the NIC RAM.	padLength = 0;	packetLength = p->tot_len;	// packetLength muse >=64 (see 802.3)    if ((p->tot_len) < 64)   {       padLength = 64 - (p->tot_len);       packetLength = 64;   }   	 	//don't close nic,just close receive interrupt		NE_CR = ENCR_PAGE2 | ENCR_NODMA | ENCR_START;	isr = NE_IMR;	isr &= ~ENISR_RX;    NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_START;	NE_IMR = isr;		NE_ISR = ENISR_RDC;			    // Amount to send	NE_RBCR0 = packetLength & 0xff;	NE_RBCR1 = packetLength >> 8;    // Address on NIC to store	NE_RSAR0 = 0x00;	NE_RSAR1 = NE_START_PG;	// Write command to start	NE_CR = ENCR_PAGE0 | ENCR_RWRITE | ENCR_START;    	//write packet to ring buffers.	for(q = p, chain = 0; q != NULL; q = q->next) 	{      		if(chain == 1)		{    		if(((q->len-1) & 0x01) && (q->next != NULL))    		{		   		tr_len = q->len - 2;		   		tr_ptr = ((u8_t*)q->payload) + 1;		   						temp_dw = *(((u8_t *)q->payload) + q->len - 1);				temp_dw += *(u8_t *)(q->next->payload) << 8;								chain = 1;			}			else			{				tr_len = q->len - 1;				tr_ptr = ((u8_t*)q->payload) + 1;				chain = 0;			}		}		else		{			if((q->len & 0x01) && (q->next != NULL))			{		   		tr_len = q->len - 1;		   		tr_ptr = (u8_t*)q->payload;		   						temp_dw = *(((u8_t *)q->payload) + q->len - 1);				temp_dw += *(u8_t *)(q->next->payload) << 8;								chain = 1;			}			else			{				tr_len = q->len;				tr_ptr = (u8_t*)q->payload;								chain = 0;			}		}								ne2k_copyout(tr_len, tr_ptr);					if (chain == 1) NE_DATAW = temp_dw;		}	ne2k_outpad(padLength);    	// Wait for remote dma to complete - ISR Bit 6 clear if busy	while((u8_t)(NE_ISR & ENISR_RDC) == 0 );			NE_ISR = ENISR_RDC;     //clear RDC	// Issue the transmit command.(start local dma) 	NE_TPSR = NE_START_PG;	NE_TBCR0 = packetLength & 0xff;	NE_TBCR1 = packetLength >> 8;		// Start transmission (and shut off remote dma)	NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_TRANS | ENCR_START;	// reopen receive interrupt	NE_CR = ENCR_PAGE2 | ENCR_NODMA | ENCR_START;	isr = NE_IMR;	isr |= ENISR_RX;    NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_START;	NE_IMR = isr;		return ERR_OK;}/** * Read a packet into a pbuf chain. */static struct pbuf * low_level_receive(struct RTL8019if *rtl8019if){	u16_t  packetLength,len;	u8_t PDHeader[18];   // Temp storage for ethernet headers	struct pbuf * p;	struct pbuf * q;	u8_t * payload;		NE_ISR = ENISR_RDC;	NE_RBCR1 = 0x0f; 	// See controller manual , use send packet command	NE_CR = ENCR_PAGE0 | ENCR_RREAD | ENCR_RWRITE | ENCR_START;	// get the first 18 bytes from nic 	ne2k_copyin(18,PDHeader);	//  Store real length, set len to packet length - header	packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ));   	// verify if the packet is an IP packet or ARP packet	if((PDHeader[3]>0x06)||(PDHeader[16] != 8)||(PDHeader[17] != 0 && PDHeader[17] != 6))	{		ne2k_discard(packetLength-14);		return NULL;	}      		// We allocate a pbuf chain of pbufs from the pool.	p = pbuf_alloc(PBUF_LINK, packetLength, PBUF_POOL);	if(p != NULL) 	{		// We iterate over the pbuf chain until we have read the entire      	// packet into the pbuf.		// This assumes a minimum pbuf size of 14 ... a good assumption		memcpy(p->payload, PDHeader + 4, 14);			for(q = p; q != NULL; q= q->next)		{     		// Read enough bytes to fill this pbuf in the chain. The         	// avaliable data in the pbuf is given by the q->len variable.      		// read data into(q->payload, q->len);     		// First 14 bytes are already there, skip them     					payload = q->payload;			len = q->len;			if (q == p)			{				payload += 14;				len -=14;			}			ne2k_copyin(len,payload);      				}	} 	else 	{    	// no more PBUF resource, Discard packet in buffer.		ne2k_discard(packetLength-14);  	}	return p;}/*-----------------------------------------------------------------------------------*//* * ethernetif_init(): * * Should be called at the beginning of the program to set up the * network interface. It calls the function low_level_init() to do the * actual setup of the hardware. * *///  WARNING: must close all interrupts during init!!!!/*-----------------------------------------------------------------------------------*/voidne2k_init(struct netif *netif){	struct RTL8019if *rtl8019if;	rtl8019if = mem_malloc(sizeof(struct RTL8019if));	rtl8019if->ethaddr = mem_malloc(sizeof(struct eth_addr));	netif->state = rtl8019if;	netif->name[0] = 'e';	netif->name[1] = 't';	netif->output = ne2k_send_packet;  	low_level_init(netif);	etharp_init();}/** * Send a packet to the RTK8019as from a series of pbuf buffers. */err_t ne2k_send_packet(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr){	struct RTL8019if *rtl8019if;	struct pbuf *q;	struct eth_hdr *ethhdr;	struct eth_addr *dest, mcastaddr;	struct ip_addr *queryaddr;	u8_t i;  	rtl8019if = netif->state;	// Make room for Ethernet header.	if(pbuf_header(p, 14) != 0) 	{    	// The pbuf_header() call shouldn't fail, but we allocate an extra pbuf just in case.    	q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM);    	if(q == NULL) return ERR_MEM;    	pbuf_chain(q, p);    	p = q;	}  	// Construct Ethernet header. Start with looking up deciding which    // MAC address to use as a destination address. Broadcasts and    // multicasts are special, all other addresses are looked up in the    // ARP table.	queryaddr = ipaddr;	if(ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, &(netif->netmask))) 	{    	dest = (struct eth_addr *)&ethbroadcast;	}   	else if(ip_addr_ismulticast(ipaddr)) 	{    	// Hash IP multicast address to MAC address.    	mcastaddr.addr[0] = 0x01;    	mcastaddr.addr[1] = 0x0;    	mcastaddr.addr[2] = 0x5e;    	mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;    	mcastaddr.addr[4] = ip4_addr3(ipaddr);    	mcastaddr.addr[5] = ip4_addr4(ipaddr);    	dest = &mcastaddr;	}	else	{    	if(ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) 		{      		// Use destination IP address if the destination is on          	// the same subnet as we are.      		queryaddr = ipaddr;    	}		else		{      		// Otherwise we use the default router as the address to send         	// the Ethernet frame to. */      		queryaddr = &(netif->gw);    	}    	dest = arp_lookup(queryaddr);	}	// If the arp_lookup() didn't find an address, we send out an ARP	// query for the IP address.	if(dest == NULL)	{    	q = etharp_query(netif, rtl8019if->ethaddr, queryaddr);    	if(q != NULL)		{	  		low_level_send(rtl8019if, q);      		pbuf_free(q);      		return ERR_ARP;    	}    	return ERR_MEM;	}	ethhdr = p->payload;  	for(i = 0; i < 6; i++)	{    	ethhdr->dest.addr[i] = dest->addr[i];    	ethhdr->src.addr[i] = rtl8019if->ethaddr->addr[i];	}  	ethhdr->type = htons(ETHTYPE_IP);  	return low_level_send(rtl8019if, p);	}/** * Read a packet, clearing overflows. */void ne2k_recv_packet(struct netif *netif){	struct eth_hdr *ethhdr;	struct RTL8019if *rtl8019if;	struct pbuf *p;	rtl8019if = netif->state;// 	PRINT("start get a packet in ne2k_receive_packet\n ");	p = low_level_receive(rtl8019if);//	PRINT("got a packet from low_level_receive\n");  	if(p == NULL) return;		ethhdr = p->payload;	switch(htons(ethhdr->type))	{		case ETHTYPE_IP:    		etharp_ip_input(netif, p);			pbuf_header(p, -14);			netif->input(p, netif);			break;		case ETHTYPE_ARP:			p = etharp_arp_input(netif, rtl8019if->ethaddr, p);    		if(p != NULL)			{	 			low_level_send(rtl8019if, p);				pbuf_free(p);    		}    		break;  		default:    		pbuf_free(p);    		break;  	}}

⌨️ 快捷键说明

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