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

📄 nic.c

📁 在ucos_ii基础上加上网络功能
💻 C
字号:
/* 
 * $Id: NIC.C,v 1.7 2002/02/21 08:25:00 linfusheng Exp $
 */
#include "includes.h"
#include "pci.h"
#include "pci_ids.h"
#include "ether.h"
#include "nic.h"
#include "sockios.h"
#include "br.h"






#define RX_RING_SIZE	16

struct nbuf rx_ring[RX_RING_SIZE];

unsigned char in_read_index = 0,in_write_index = 0;



//#define NIC_DEBUG


#define N_NET_DEVICE	8

struct nic net_device[N_NET_DEVICE];
int net_device_found = 0;


struct devprobe
{
	int (*probe)(struct nic *dev);
	int status;	/* non-zero if autoprobe has failed */
};

struct devprobe nic_probes[] = {
#ifdef INCLUDE_RTL8139
	{rtl8139_probe,0},
#endif
	{NULL, 0}
};




/*
 * probe_list walks a list of probe functions and calls each so long
 * as a non-zero ioaddr is given, or as long as it hasn't already failed 
 * to find a card in the past (as recorded by "status") when asked to
 * autoprobe (i.e. a probe that fails to find a card when autoprobing
 * will not be asked to autoprobe again).  It exits when a card is found.
 */
static int  nic_probe(struct devprobe *plist)
{
	int i;
	struct devprobe *p = plist;
	struct nic *dev = &net_device[0];
	// we sugguest that size of net_device is enought 
	while (p->probe != NULL) {
		if (p->status == 0) {		/* has autoprobe failed yet? */
			p->status = p->probe(dev);	/* no, try autoprobe */
			if (p->status > 0) {
				for( i = 0 ; i < p->status ; i ++) {	
					sprintf(dev->name,"eth%d",net_device_found);	
					debug_print("found ether interface %s \r\n",dev->name);
					dev->index = net_device_found + 1;
					br_register_port(dev);
					dev ++;
					net_device_found ++;


				}
			}
		}
		p++;
	}
	return -1;
}

void netif_rx(unsigned char *packet,int packet_len,struct nic *nic)
{
	if((in_write_index + 1) % RX_RING_SIZE != in_read_index) {
		memcpy(rx_ring[in_write_index].packet,packet,packet_len);
		rx_ring[in_write_index].packetlen = packet_len;
		rx_ring[in_write_index].nic = nic;
		in_write_index ++;
		in_write_index %= RX_RING_SIZE;

		OSTaskResume(NET_PRIO);	//唤醒网络处理任务
	}
	else 
		debug_print("net buffer have fulled .... \r\n");
}


void netif_bh(void)
{

	struct ethhdr *eth_hdr = NULL;
	struct nbuf *nbuf;
	unsigned short type = 0;

	
	if (  in_read_index == in_write_index) {
		OSTaskSuspend(NET_PRIO); //挂起网络处理任务	
		return;
	}

	nbuf = &rx_ring[in_read_index];
#if 0
	br_recv(rx_ring[in_read_index].nic,
		 rx_ring[in_read_index].packet,
		 rx_ring[in_read_index].packetlen);
#else
	nbuf->data = nbuf->packet;
	nbuf->len = nbuf->packetlen;

	nbuf->lh.raw = nbuf->data;

	eth_hdr = nbuf->lh.ethernet;
	type = ntohs(eth_hdr->ether_type);


	nbuf->nh.raw = nbuf->lh.raw + ETH_HLEN;
	nbuf->data += ETH_HLEN;
	nbuf->len -= ETH_HLEN;

	switch(type) {
	case ETHERTYPE_IP:

		iprecv(nbuf);
		break;
	case ETHERTYPE_ARP:

		arprecv(nbuf);
		break;
	default:
		break;
	}

#endif
	in_read_index++ ;
	in_read_index %= RX_RING_SIZE;
	return;
}


struct nic *netif_lookup_by_name(char *name)
{
	int i;
	for( i = 0 ;i  < net_device_found ; i ++) {
		if(strncmp(net_device[i].name,name,IFNAMESIZ) == 0)
			return &net_device[i];	
	}
 	return NULL;
}

 

int
netif_ioctl(u_long cmd,caddr_t data)
{
	struct nic *dev;
	struct ifreq *ifr = (struct ifreq *)data;
	if((dev = netif_lookup_by_name(ifr->ifr_name)) == NULL)
		return -1;
	switch(cmd) {
	case 1:
		debug_print("get command code 1 \r\n");
		dev->ip_addr = ifr->ifr_addr;
		break;
	default:
		break;
	}
	return 0;
}


void netif_slowtimo(void *arg)
{
	int i;
	for( i = 0 ;i  < net_device_found ; i ++) {
		if(net_device[i].timeout == 0 )
			continue;
		if(net_device[i].timeout > 0 ) {
			net_device[i].timeout --;
		}
		if(net_device[i].timeout == 0 && net_device[i].watchdog) {
			(*net_device[i].watchdog)(&net_device[i]);
		}
	}
}

void netif_init(void)
{
	nic_probe(nic_probes);
}

/* 
 * $Log: NIC.C,v $
 * Revision 1.7  2002/02/21 08:25:00  linfusheng
 * update
 *
 * Revision 1.6  2002/02/07 01:08:53  linfusheng
 * update
 *
 * Revision 1.5  2002/02/06 02:16:25  linfusheng
 * update
 *
 * Revision 1.4  2002/02/05 05:26:03  linfusheng
 * update
 *
 * Revision 1.3  2002/01/28 01:13:52  linfusheng
 * update
 *
 * Revision 1.2  2002/01/28 00:46:25  linfusheng
 * update
 *
 */

⌨️ 快捷键说明

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