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

📄 sdla_fr.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
	offs = frbuf->offset;	/* Find network interface for this packet */	dev = find_channel(card, dlci);        	if (dev == NULL) {		/* unconfigured DLCI, so discard packet */   		printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n",                                                card->devname, dlci);		++card->statistics.rx_intr_on_orphaned_DLCI;        	} else {		chan = dev->priv;   		skb = dev_alloc_skb(len); 		if (!netif_running(dev) || (skb == NULL)) { 			++chan->ifstats.rx_dropped;					if(netif_running(dev)) {				printk(KERN_INFO 				"%s: no socket buffers available!\n", 				card->devname);	    			chan->drvstats_rx_intr.rx_intr_no_socket ++;                					} else				chan->drvstats_rx_intr.					rx_intr_dev_not_started ++;		} else {			/* Copy data to the socket buffer */			if ((offs + len) > card->u.f.rx_top + 1) {				unsigned tmp = card->u.f.rx_top - offs + 1;				buf = skb_put(skb, tmp);				sdla_peek(&card->hw, offs, buf, tmp);				offs = card->u.f.rx_base;               			len -= tmp;               		}			buf = skb_put(skb, len);			sdla_peek(&card->hw, offs, buf, len);			udp_type = udp_pkt_type( skb, card );                        if(udp_type != UDP_INVALID_TYPE) {                                if(store_udp_mgmt_pkt(udp_type,                                        UDP_PKT_FRM_NETWORK, card, skb, dlci)) {                                        flags->imask |= FR_INTR_TIMER;                                        if (udp_type == UDP_FPIPE_TYPE){                                                chan->drvstats_rx_intr.						    rx_intr_PIPE_request ++;					}				}						}			else if (chan->usedby == API) {				api_rx_hdr_t* api_rx_hdr;				chan->drvstats_rx_intr.                                	rx_intr_bfr_passed_to_stack ++;				chan->ifstats.rx_packets ++;                                card->wandev.stats.rx_packets ++;				chan->ifstats.rx_bytes += skb->len;				card->wandev.stats.rx_bytes += skb->len;				skb_push(skb, sizeof(api_rx_hdr_t));				api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];				api_rx_hdr->attr = frbuf->attr;				api_rx_hdr->time_stamp = frbuf->tmstamp;				skb->protocol = htons(0x16);				skb->pkt_type = PACKET_HOST;                                /* Pass it up the protocol stack */                                skb->dev = dev;                                skb->mac.raw  = skb->data;                                netif_rx(skb);			} else if (handle_IPXWAN(skb->data,chan->name,				chan->enable_IPX, chan->network_number)) {				if (chan->enable_IPX) {                                        fr_send(card, dlci, 0, skb->len,						skb->data);				}				dev_kfree_skb(skb);/*FIXME: Fix the ARPS in next release			} else if (is_arp(skb->data)) {				if (process_ARP((arphdr_1490_t *)skb->data, card, dev)) {					printk (KERN_INFO "%s: Error processing ARP Packet.\n", card->devname);				}				dev_kfree_skb(skb);*/			} else if ( skb->data[0] != 0x03) {				printk(KERN_INFO "%s: Non IETF packet discarded.\n", card->devname);				dev_kfree_skb(skb);			} else {				len_incl_hdr = skb->len;                    		/* Decapsulate packet and pass it up the			   	   protocol stack */				skb->dev = dev;				/* remove hardware header */				buf = skb_pull(skb, 1); 				if (!wanrouter_type_trans(skb, dev)) {										/* can't decapsulate packet */					dev_kfree_skb(skb);					chan->drvstats_rx_intr.					     rx_intr_bfr_not_passed_to_stack ++; 					++ chan->ifstats.rx_errors;		                       	++ card->wandev.stats.rx_errors;									} else {					netif_rx(skb);					chan->drvstats_rx_intr.						rx_intr_bfr_passed_to_stack ++;					++ chan->ifstats.rx_packets;					++ card->wandev.stats.rx_packets;                                        chan->ifstats.rx_bytes += len_incl_hdr;                                        card->wandev.stats.rx_bytes += 						len_incl_hdr;				}                	}            	}       	}       	/* Release buffer element and calculate a pointer to the next one */        	frbuf->flag = 0;	card->rxmb = ++frbuf;	if ((void*)frbuf > card->u.f.rxmb_last)		card->rxmb = card->u.f.rxmb_base;}/*============================================================================ * Transmit interrupt handler. */static void tx_intr(sdla_t *card){        fr508_flags_t* flags = card->flags;        fr_tx_buf_ctl_t* bctl;        struct net_device* dev = card->wandev.dev;        fr_channel_t* chan;        if(card->hw.type == SDLA_S514){                bctl = (void*)(flags->tse_offs + card->hw.dpmbase);        }else{                bctl = (void*)(flags->tse_offs - FR_MB_VECTOR +                        card->hw.dpmbase);	}        /* Find the structure and make it unbusy */        dev = find_channel(card, flags->dlci);        chan = dev->priv;        if(!chan->transmit_length) {                printk(KERN_INFO "%s: tx int error - transmit length zero\n",				card->wandev.name);                return;        }	/* If the 'if_send()' procedure is currently checking the 'tbusy'	   status, then we cannot transmit. Instead, we configure the microcode	   so as to re-issue this transmit interrupt at a later stage. 	*/	if (test_bit(2, (void*)&card->wandev.critical)) {		fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface;		bctl->flag = 0xA0;		dlci_interface->gen_interrupt |= FR_INTR_TXRDY;		printk(KERN_INFO "%s: TX Interrupt Detected busy if_send\n",card->devname); 	} else {        	bctl->dlci = flags->dlci;	        bctl->length = chan->transmit_length;        	sdla_poke(&card->hw, bctl->offset, chan->transmit_buffer,                	chan->transmit_length);	        bctl->flag = 0xC0;		++chan->ifstats.tx_packets;		++card->wandev.stats.tx_packets;		chan->ifstats.tx_bytes += chan->transmit_length;		card->wandev.stats.tx_bytes += chan->transmit_length;        	chan->transmit_length = 0;	        /* if any other interfaces have transmit interrupts pending, */		/* do not disable the global transmit interrupt */		if(!(-- card->u.f.tx_interrupts_pending))        	        flags->imask &= ~FR_INTR_TXRDY;		netif_wake_queue (dev);	}}/*============================================================================ * Timer interrupt handler. FIXME: update comments as we modify the code * The timer interrupt is used for three purposes: *    1) Processing udp calls from 'fpipemon'. *    2) Processing update calls from /proc file system *    2) Reading board-level statistics for updating the proc file system. *    3) Sending inverse ARP request packets. */static void timer_intr(sdla_t *card){	fr508_flags_t* flags = card->flags;        if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UDP) {		if(card->u.f.udp_type == UDP_FPIPE_TYPE) {                    	if(process_udp_mgmt_pkt(card)) {		                card->u.f.timer_int_enabled &=					~TMR_INT_ENABLED_UDP;			}		}        }	if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE) {		fr_get_err_stats(card);		fr_get_stats(card);		card->u.f.update_comms_stats = 0;		card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;	}//FIXME: Fix the dynamic IP addressing/*goto L4;	// Used to send inarp request at given interval 	if (card->wandev.state == WAN_CONNECTED) {        	int num_remaining = 0;		dev = card->wandev.dev;		while (dev) {                	fr_channel_t *chan = dev->priv;                        if (chan->inarp == INARP_REQUEST &&                        	chan->state == WAN_CONNECTED) {                                num_remaining++;                                if ((jiffies - chan->inarp_tick) > (chan->inarp_interval * HZ)) {                                	send_inarp_request(card,dev);                                	chan->inarp_tick = jiffies;                                }			}			dev = chan->slave;		}		if (!num_remaining) {   // no more to process                         flags->imask &= ~FR_INTR_TIMER;		}	}L4:	;*/        if(!card->u.f.timer_int_enabled)                flags->imask &= ~FR_INTR_TIMER;}/*============================================================================ * Spurious interrupt handler. * o print a warning * o  */static void spur_intr (sdla_t* card){	printk(KERN_INFO "%s: spurious interrupt!\n", card->devname);}//FIXME: Fix the IPX in next version/*=========================================================================== *  Return 0 for non-IPXWAN packet *         1 for IPXWAN packet or IPX is not enabled! *  FIXME: Use a IPX structure here not offsets */static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number){	int i;	if( sendpacket[1] == 0x00 &&	    sendpacket[2] == 0x80 &&	    sendpacket[6] == 0x81 &&	    sendpacket[7] == 0x37) { 		/* It's an IPX packet */		if(!enable_IPX) {			/* Return 1 so we don't pass it up the stack. */			//FIXME: Take this out when IPX is fixed			printk (KERN_INFO 				"%s: WARNING: Unsupported IPX packet received and dropped\n",					devname);			return 1;		}	} else {		/* It's not IPX so return and pass it up the stack. */		return 0;	}	if( sendpacket[24] == 0x90 &&	    sendpacket[25] == 0x04)	{		/* It's IPXWAN */		if( sendpacket[10] == 0x02 &&		    sendpacket[42] == 0x00)		{			/* It's a timer request packet */			printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname);			/* Go through the routing options and answer no to every			 * option except Unnumbered RIP/SAP			 */			for(i = 49; sendpacket[i] == 0x00; i += 5)			{				/* 0x02 is the option for Unnumbered RIP/SAP */				if( sendpacket[i + 4] != 0x02)				{					sendpacket[i + 1] = 0;				}			}			/* Skip over the extended Node ID option */			if( sendpacket[i] == 0x04 )			{				i += 8;			}			/* We also want to turn off all header compression opt.			 */			for(; sendpacket[i] == 0x80 ;)			{				sendpacket[i + 1] = 0;				i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;			}			/* Set the packet type to timer response */			sendpacket[42] = 0x01;			printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);		}		else if( sendpacket[42] == 0x02 )		{			/* This is an information request packet */			printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname);			/* Set the packet type to information response */			sendpacket[42] = 0x03;			/* Set the router name */			sendpacket[59] = 'F';			sendpacket[60] = 'P';			sendpacket[61] = 'I';			sendpacket[62] = 'P';			sendpacket[63] = 'E';			sendpacket[64] = '-';			sendpacket[65] = CVHexToAscii(network_number >> 28);			sendpacket[66] = CVHexToAscii((network_number & 0x0F000000)>> 24);			sendpacket[67] = CVHexToAscii((network_number & 0x00F00000)>> 20);			sendpacket[68] = CVHexToAscii((network_number & 0x000F0000)>> 16);			sendpacket[69] = CVHexToAscii((network_number & 0x0000F000)>> 12);			sendpacket[70] = CVHexToAscii((network_number & 0x00000F00)>> 8);			sendpacket[71] = CVHexToAscii((network_number & 0x000000F0)>> 4);			sendpacket[72] = CVHexToAscii(network_number & 0x0000000F);			for(i = 73; i < 107; i+= 1)			{				sendpacket[i] = 0;			}			printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname);		}		else		{			printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);			return 0;		}		/* Set the WNodeID to our network address */		sendpacket[43] = (unsigned char)(network_number >> 24);		sendpacket[44] = (unsigned char)((network_number & 0x00FF0000) >> 16);		sendpacket[45] = (unsigned char)((network_number & 0x0000FF00) >> 8);		sendpacket[46] = (unsigned char)(network_number & 0x000000FF);		return 1;	}	/* If we get here, its an IPX-data packet so it'll get passed up the 	 * stack.	 * switch the network numbers 	 */	switch_net_numbers(sendpacket, network_number ,1);	return 0;}/*============================================================================ * Process Route. * This routine is called as a polling routine to dynamically add/delete routes * negotiated by inverse ARP.  It is in this "task" because we don't want routes * to be added while in interrupt context.*/static void process_route (sdla_t* card){	struct net_device* dev;	struct in_device *in_dev;    	struct rtentry route;        int err = 0;        mm_segment_t fs;	/* Dynamic Route adding/removing */	dev = card->wandev.dev;	while (dev) {		fr_channel_t *chan = dev->priv;		if (chan->route_flag == ADD_ROUTE   ||		    chan->route_flag == REMOVE_ROUTE ) {			fs = get_fs();					in_dev = dev->ip_ptr;			if( in_dev != NULL && in_dev->ifa_list != NULL) {				memset(&route, 0, sizeof(route));				route.rt_dev   = dev->name;				route.rt_flags = 0;				((str

⌨️ 快捷键说明

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