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

📄 sdla_ppp.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#if defined(LINUX_2_1) || defined(LINUX_2_4)static int if_rebuild_hdr (struct sk_buff *skb){	netdevice_t *dev = skb->dev;	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n",		card->devname, dev->name);	return 1;}#elsestatic int if_rebuild_hdr (void* hdr, netdevice_t* dev, unsigned long raddr,                           struct sk_buff* skb){	return 1;}#endif#ifdef LINUX_2_4/*============================================================================ * Handle transmit timeout event from netif watchdog */static void if_tx_timeout (netdevice_t *dev){    	ppp_private_area_t* chan = dev->priv;	sdla_t *card = chan->card;		/* If our device stays busy for at least 5 seconds then we will	 * kick start the device by making dev->tbusy = 0.  We expect	 * that our device never stays busy more than 5 seconds. So this                 	 * is only used as a last resort.	 */	++ chan->if_send_stat.if_send_tbusy;	++card->wandev.stats.collisions;	printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);	++chan->if_send_stat.if_send_tbusy_timeout;	netif_wake_queue (dev);}#endif/*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based *   transmit from overlapping. * o check link state. If link is not up, then drop the packet. * o execute adapter send command. * o free socket buffer * * Return:	0	complete (socket buffer must be freed) *		non-0	packet may be re-transmitted (tbusy must be set) * * Notes: * 1. This routine is called either by the protocol stack or by the "net *    bottom half" (with interrupts enabled). * 2. Setting tbusy flag will inhibit further transmit requests from the *    protocol stack and can be used for flow control with protocol layer. */static int if_send (struct sk_buff *skb, netdevice_t *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t *card = ppp_priv_area->card;	unsigned char *sendpacket;	unsigned long smp_flags;	ppp_flags_t *flags = card->flags;	int udp_type;	int err=0;		++ppp_priv_area->if_send_stat.if_send_entry;#ifdef LINUX_2_4	netif_stop_queue(dev);#endif		if (skb == NULL) {		/* If we get here, some higher layer thinks we've missed an		 * tx-done interrupt.		 */		printk(KERN_INFO "%s: interface %s got kicked!\n",			card->devname, dev->name);				++ppp_priv_area->if_send_stat.if_send_skb_null;			wake_net_dev(dev);		return 0;	}#ifndef LINUX_2_4	if (dev->tbusy) {		/* If our device stays busy for at least 5 seconds then we will		 * kick start the device by making dev->tbusy = 0.  We expect 		 * that our device never stays busy more than 5 seconds. So this		 * is only used as a last resort. 		 */              		++ppp_priv_area->if_send_stat.if_send_tbusy;        	++card->wandev.stats.collisions;		if ((jiffies - ppp_priv_area->tick_counter) < (5*HZ)) {			return 1;		}		printk (KERN_INFO "%s: Transmit times out on %s\n",card->devname,dev->name);			++ppp_priv_area->if_send_stat.if_send_tbusy_timeout;		++card->wandev.stats.collisions;		/* unbusy the card (because only one interface per card)*/		dev->tbusy = 0;	}	#endif		sendpacket = skb->data;	udp_type = udp_pkt_type( skb, card );	if (udp_type == UDP_PTPIPE_TYPE){		if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,                	              ppp_priv_area)){	               	flags->imask |= PPP_INTR_TIMER;		}		++ppp_priv_area->if_send_stat.if_send_PIPE_request;		start_net_queue(dev);		return 0;	}	/* Check for broadcast and multicast addresses 	 * If found, drop (deallocate) a packet and return.	 */	if(chk_bcast_mcast_addr(card, dev, skb)){		++card->wandev.stats.tx_dropped;		wan_dev_kfree_skb(skb,FREE_WRITE);		start_net_queue(dev);		return 0;	} 	if(card->hw.type != SDLA_S514){		s508_lock(card,&smp_flags);	}    	if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {		printk(KERN_INFO "%s: Critical in if_send: %lx\n",				card->wandev.name,card->wandev.critical);				++card->wandev.stats.tx_dropped;		++ppp_priv_area->if_send_stat.if_send_critical_non_ISR;		start_net_queue(dev);		goto if_send_exit_crit;	}	if (card->wandev.state != WAN_CONNECTED) {		++ppp_priv_area->if_send_stat.if_send_wan_disconnected;        	++card->wandev.stats.tx_dropped;		start_net_queue(dev);		     	} else if (!skb->protocol) {		++ppp_priv_area->if_send_stat.if_send_protocol_error;        	++card->wandev.stats.tx_errors;		start_net_queue(dev);			} else {		/*If it's IPX change the network numbers to 0 if they're ours.*/		if( skb->protocol == htons(ETH_P_IPX) ) {			if(ppp_priv_area->enable_IPX) {				switch_net_numbers( skb->data, 					ppp_priv_area->network_number, 0);			} else {				++card->wandev.stats.tx_dropped;				start_net_queue(dev);				goto if_send_exit_crit;			}		}		if (ppp_send(card, skb->data, skb->len, skb->protocol)) {			stop_net_queue(dev);			++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full;			++ppp_priv_area->if_send_stat.if_send_tx_int_enabled;		} else {			++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr;			++card->wandev.stats.tx_packets;#if defined(LINUX_2_1) || defined(LINUX_2_4)			card->wandev.stats.tx_bytes += skb->len;#endif			start_net_queue(dev);#ifdef LINUX_2_4			dev->trans_start = jiffies;#endif		}    	}	if_send_exit_crit:		if (!(err=is_queue_stopped(dev))){      		wan_dev_kfree_skb(skb, FREE_WRITE);	}else{		ppp_priv_area->tick_counter = jiffies;		flags->imask |= PPP_INTR_TXRDY;	/* unmask Tx interrupts */	}		clear_bit(SEND_CRIT,&card->wandev.critical);	if(card->hw.type != SDLA_S514){			s508_unlock(card,&smp_flags);	}	return err;}/*============================================================================= * Store a UDP management packet for later processing. */static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,                                struct sk_buff *skb, netdevice_t* dev,                                ppp_private_area_t* ppp_priv_area ){	int udp_pkt_stored = 0;	if(!ppp_priv_area->udp_pkt_lgth && (skb->len<=MAX_LGTH_UDP_MGNT_PKT)){        	ppp_priv_area->udp_pkt_lgth = skb->len;		ppp_priv_area->udp_pkt_src = udp_pkt_src;       		memcpy(ppp_priv_area->udp_pkt_data, skb->data, skb->len);		ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UDP;		ppp_priv_area->protocol = skb->protocol;		udp_pkt_stored = 1;	}else{		if (skb->len > MAX_LGTH_UDP_MGNT_PKT){#if defined(LINUX_2_1) || defined(LINUX_2_4)			printk(KERN_INFO "%s: PIPEMON UDP request too long : %i\n",				card->devname, skb->len);#else			printk(KERN_INFO "%s: PIPEMON UDP request too long : %li\n",				card->devname, skb->len);#endif		}else{			printk(KERN_INFO "%s: PIPEMON UPD request already pending\n",				card->devname);		}		ppp_priv_area->udp_pkt_lgth = 0;	}	if(udp_pkt_src == UDP_PKT_FRM_STACK){		wan_dev_kfree_skb(skb, FREE_WRITE);	}else{                wan_dev_kfree_skb(skb, FREE_READ);	}	return(udp_pkt_stored);}/*============================================================================ * Reply to UDP Management system. * Return length of reply. */static int reply_udp( unsigned char *data, unsigned int mbox_len ) {	unsigned short len, udp_length, temp, ip_length;	unsigned long ip_temp;	int even_bound = 0;	ppp_udp_pkt_t *p_udp_pkt = (ppp_udp_pkt_t *)data; 	/* Set length of packet */	len = sizeof(ip_pkt_t)+ 	      sizeof(udp_pkt_t)+	      sizeof(wp_mgmt_t)+	      sizeof(cblock_t)+	      mbox_len;	/* fill in UDP reply */  	p_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; 	/* fill in UDP length */	udp_length = sizeof(udp_pkt_t)+ 		     sizeof(wp_mgmt_t)+		     sizeof(cblock_t)+		     mbox_len;    	/* put it on an even boundary */	if ( udp_length & 0x0001 ) {		udp_length += 1;		len += 1;		even_bound=1;	} 		temp = (udp_length<<8)|(udp_length>>8);	p_udp_pkt->udp_pkt.udp_length = temp;		 	/* swap UDP ports */	temp = p_udp_pkt->udp_pkt.udp_src_port;	p_udp_pkt->udp_pkt.udp_src_port = 			p_udp_pkt->udp_pkt.udp_dst_port; 	p_udp_pkt->udp_pkt.udp_dst_port = temp;	/* add UDP pseudo header */	temp = 0x1100;	*((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound)) = temp;	temp = (udp_length<<8)|(udp_length>>8);	*((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound+2)) = temp; 	/* calculate UDP checksum */	p_udp_pkt->udp_pkt.udp_checksum = 0;	p_udp_pkt->udp_pkt.udp_checksum = 		calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);	/* fill in IP length */	ip_length = udp_length + sizeof(ip_pkt_t);	temp = (ip_length<<8)|(ip_length>>8);  	p_udp_pkt->ip_pkt.total_length = temp; 	/* swap IP addresses */	ip_temp = p_udp_pkt->ip_pkt.ip_src_address;	p_udp_pkt->ip_pkt.ip_src_address = p_udp_pkt->ip_pkt.ip_dst_address;	p_udp_pkt->ip_pkt.ip_dst_address = ip_temp;	/* fill in IP checksum */	p_udp_pkt->ip_pkt.hdr_checksum = 0;	p_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));	return len;} /* reply_udp */unsigned short calc_checksum (char *data, int len){	unsigned short temp; 	unsigned long sum=0;	int i;	for( i = 0; i <len; i+=2 ) {		memcpy(&temp,&data[i],2);		sum += (unsigned long)temp;	}	while (sum >> 16 ) {		sum = (sum & 0xffffUL) + (sum >> 16);	}	temp = (unsigned short)sum;	temp = ~temp;	if( temp == 0 ) 		temp = 0xffff;	return temp;	}/*   If incoming is 0 (outgoing)- if the net numbers is ours make it 0   if incoming is 1 - if the net number is 0 make it ours */static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming){	unsigned long pnetwork_number;	pnetwork_number = (unsigned long)((sendpacket[6] << 24) + 			  (sendpacket[7] << 16) + (sendpacket[8] << 8) + 			  sendpacket[9]);	if (!incoming) {		//If the destination network number is ours, make it 0		if( pnetwork_number == network_number) {			sendpacket[6] = sendpacket[7] = sendpacket[8] = 					 sendpacket[9] = 0x00;		}	} else {		//If the incoming network is 0, make it ours		if( pnetwork_number == 0) {			sendpacket[6] = (unsigned char)(network_number >> 24);			sendpacket[7] = (unsigned char)((network_number & 					 0x00FF0000) >> 16);			sendpacket[8] = (unsigned char)((network_number & 					 0x0000FF00) >> 8);			sendpacket[9] = (unsigned char)(network_number & 					 0x000000FF);		}	}	pnetwork_number = (unsigned long)((sendpacket[18] << 24) + 			  (sendpacket[19] << 16) + (sendpacket[20] << 8) + 			  sendpacket[21]);	if( !incoming ) {		//If the source network is ours, make it 0		if( pnetwork_number == network_number) {			sendpacket[18] = sendpacket[19] = sendpacket[20] = 					 sendpacket[21] = 0x00;		}	} else {		//If the source network is 0, make it ours		if( pnetwork_number == 0 ) {			sendpacket[18] = (unsigned char)(network_number >> 24);			sendpacket[19] = (unsigned char)((network_number & 					 0x00FF0000) >> 16);			sendpacket[20] = (unsigned char)((network_number & 					 0x0000FF00) >> 8);			sendpacket[21] = (unsigned char)(network_number & 					 0x000000FF);		}	}} /* switch_net_numbers *//*============================================================================ * Get ethernet-style interface statistics. * Return a pointer to struct net_device_stats. */#if defined(LINUX_2_1) || defined(LINUX_2_4)static struct net_device_stats *if_stats(netdevice_t *dev)#elsestatic struct enet_statistics *if_stats(netdevice_t *dev)#endif{	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t* card;		if( ppp_priv_area == NULL )		return NULL;	card = ppp_priv_area->card;	return &card->wandev.stats;}/****** PPP Firmware Interface Functions ************************************//*============================================================================ * Read firmware code version. *	Put code version as ASCII string in str.  */static int ppp_read_version(sdla_t *card, char *str){	ppp_mbox_t *mb = card->mbox;

⌨️ 快捷键说明

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