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

📄 sdla_ppp.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		printk(KERN_INFO 			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", 			card->devname, (unsigned)rxbuf, rxbuf->flag);			printk(KERN_INFO "%s: ID Bytes = ",card->devname);	 			for(i = 0; i < 8; i ++)			printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));		printk(KERN_INFO "\n");					++card->statistics.rx_intr_corrupt_rx_bfr;		/* Bug Fix: Mar 6 2000                 * If we get a corrupted mailbox, it means that driver                  * is out of sync with the firmware. There is no recovery.                 * If we don't turn off all interrupts for this card                 * the machine will crash.                  */		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);		printk(KERN_INFO "Please contact Sangoma Technologies !\n");		ppp_set_intr_mode(card,0);		return;	}      	if (dev && is_dev_running(dev) && dev->priv){			len  = rxbuf->length;		ppp_priv_area = dev->priv;		/* Allocate socket buffer */		skb = dev_alloc_skb(len);		if (skb != NULL) {					/* Copy data to the socket buffer */			unsigned addr = rxbuf->buf.ptr;			if ((addr + len) > card->u.p.rx_top + 1) {							unsigned tmp = card->u.p.rx_top - addr + 1;				buf = skb_put(skb, tmp);				sdla_peek(&card->hw, addr, buf, tmp);				addr = card->u.p.rx_base;				len -= tmp;			}			buf = skb_put(skb, len);			sdla_peek(&card->hw, addr, buf, len);			/* Decapsulate packet */        		switch (rxbuf->proto) {					case 0x00:					skb->protocol = htons(ETH_P_IP);					break;				case 0x01:					skb->protocol = htons(ETH_P_IPX);					break;			}			udp_type = udp_pkt_type( skb, card );			if (udp_type == UDP_PTPIPE_TYPE){				/* Handle a UDP Request in Timer Interrupt */				if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb, dev,                	              			ppp_priv_area)){	               			flags->imask |= PPP_INTR_TIMER;				}				++ppp_priv_area->rx_intr_stat.rx_intr_PIPE_request;			} else if (handle_IPXWAN(skb->data,card->devname, 						 ppp_priv_area->enable_IPX, 						 ppp_priv_area->network_number, 						 skb->protocol)) {							/* Handle an IPXWAN packet */				if( ppp_priv_area->enable_IPX) {										/* Make sure we are not already sending */					if (!test_bit(SEND_CRIT, &card->wandev.critical)){					 	ppp_send(card, skb->data, skb->len, htons(ETH_P_IPX));					}					wan_dev_kfree_skb(skb,FREE_READ);				} else {					++card->wandev.stats.rx_dropped;				}			} else {				/* Pass data up the protocol stack */	    			skb->dev = dev;				skb->mac.raw  = skb->data;			    	++card->wandev.stats.rx_packets;#if defined(LINUX_2_1) || defined(LINUX_2_4)				card->wandev.stats.rx_bytes += skb->len;#endif		    		++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack;					netif_rx(skb);			}		} else {				if (net_ratelimit()){				printk(KERN_INFO "%s: no socket buffers available!\n",					card->devname);			}			++card->wandev.stats.rx_dropped;			++ppp_priv_area->rx_intr_stat.rx_intr_no_socket;		}	} else {		++card->statistics.rx_intr_dev_not_started;	}	/* Release buffer element and calculate a pointer to the next one */	rxbuf->flag = 0x00;	card->rxmb = ++rxbuf;	if ((void*)rxbuf > card->u.p.rxbuf_last)		card->rxmb = card->u.p.rxbuf_base;}void event_intr (sdla_t *card){ 	netdevice_t* dev = card->wandev.dev;        ppp_private_area_t* ppp_priv_area = dev->priv;	volatile ppp_flags_t *flags = card->flags;	switch (flags->iflag){		case PPP_INTR_MODEM:    /* modem status change (DCD, CTS) 0x04  (bit 2)*/			if (net_ratelimit()){				printk (KERN_INFO "%s: Modem status: DCD=%s CTS=%s\n",					card->devname, DCD(flags->mstatus), CTS(flags->mstatus));			}			break;		case PPP_INTR_DISC:  	/* Data link disconnected 0x10  (bit 4)*/				NEX_PRINTK (KERN_INFO "Data link disconnected intr Cause %X\n",					       flags->disc_cause);			if (flags->disc_cause &				(PPP_LOCAL_TERMINATION | PPP_DCD_CTS_DROP |				PPP_REMOTE_TERMINATION)) {				if (card->u.p.ip_mode == WANOPT_PPP_PEER) { 					set_bit(0,&Read_connection_info);				}				wanpipe_set_state(card, WAN_DISCONNECTED);				show_disc_cause(card, flags->disc_cause);				ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;				flags->imask |= PPP_INTR_TIMER;				trigger_ppp_poll(dev);			}			break;		case PPP_INTR_OPEN:   	/* Data link open 0x20  (bit 5)*/			NEX_PRINTK (KERN_INFO "%s: PPP Link Open, LCP=%s IP=%s\n",					card->devname,LCP(flags->lcp_state),					IP(flags->ip_state));			if (flags->lcp_state == 0x09 &&                            (flags->ip_state == 0x09 || flags->ipx_state == 0x09)){                                /* Initialize the polling timer and set the state                                 * to WAN_CONNNECTED */				/* BUG FIX: When the protocol restarts, during heavy                                  * traffic, board tx buffers and driver tx buffers                                 * can go out of sync.  This checks the condition                                 * and if the tx buffers are out of sync, the                                  * protocols are restarted.                                  * I don't know why the board tx buffer is out                                 * of sync. It could be that a packets is tx                                 * while the link is down, but that is not                                  * possible. The other possiblility is that the                                 * firmware doesn't reinitialize properly.                                 * FIXME: A better fix should be found.                                 */ 				if (detect_and_fix_tx_bug(card)){					ppp_comm_disable(card);					wanpipe_set_state(card, WAN_DISCONNECTED);					ppp_priv_area->timer_int_enabled |= 						TMR_INT_ENABLED_PPP_EVENT;					flags->imask |= PPP_INTR_TIMER;					break;					}				card->state_tick = jiffies;				wanpipe_set_state(card, WAN_CONNECTED);				NEX_PRINTK(KERN_INFO "CON: L Tx: %lx  B Tx: %lx || L Rx %lx B Rx %lx\n",					(unsigned long)card->u.p.txbuf, *card->u.p.txbuf_next,					(unsigned long)card->rxmb, *card->u.p.rxbuf_next);				/* Tell timer interrupt that PPP event occured */				ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;				flags->imask |= PPP_INTR_TIMER;				/* If we are in PEER mode, we must first obtain the				 * IP information and then go into the poll routine */				if (card->u.p.ip_mode != WANOPT_PPP_PEER){						trigger_ppp_poll(dev);				}			}                   	break;		case PPP_INTR_DROP_DTR:		/* DTR drop timeout expired  0x40 bit 6 */			NEX_PRINTK(KERN_INFO "DTR Drop Timeout Interrrupt \n"); 			if (card->u.p.ip_mode == WANOPT_PPP_PEER) { 				set_bit(0,&Read_connection_info);			}					wanpipe_set_state(card, WAN_DISCONNECTED);			show_disc_cause(card, flags->disc_cause);			ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;			flags->imask |= PPP_INTR_TIMER;			trigger_ppp_poll(dev);			break;				default:			printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname);	}}/* TIMER INTERRUPT */void timer_intr (sdla_t *card){        netdevice_t* dev = card->wandev.dev;        ppp_private_area_t* ppp_priv_area = dev->priv;	ppp_flags_t *flags = card->flags;	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG){		if (!config_ppp(card)){			ppp_priv_area->timer_int_enabled &= 					~TMR_INT_ENABLED_CONFIG;			}	}	/* Update statistics */	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE){		ppp_get_err_stats(card);                if(!(--ppp_priv_area->update_comms_stats)){			ppp_priv_area->timer_int_enabled &= 				~TMR_INT_ENABLED_UPDATE;		}	}	/* PPIPEMON UDP request */	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP){		process_udp_mgmt_pkt(card,dev, ppp_priv_area);		ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;	}	/* PPP Event */	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_PPP_EVENT){		if (card->wandev.state == WAN_DISCONNECTED){			retrigger_comm(card);		}		/* If the state is CONNECTING, it means that communicatins were	 	 * enabled. When the remote side enables its comminication we	 	 * should get an interrupt PPP_INTR_OPEN, thus turn off polling 		 */		else if (card->wandev.state == WAN_CONNECTING){			/* Turn off the timer interrupt */			ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;		}		/* If state is connected and we are in PEER mode 	 	 * poll for an IP address which will be provided by remote end.	 	 */		else if ((card->wandev.state == WAN_CONNECTED && 		  	  card->u.p.ip_mode == WANOPT_PPP_PEER) && 		  	  test_bit(0,&Read_connection_info)){			card->state_tick = jiffies;			if (read_connection_info (card)){				printk(KERN_INFO "%s: Failed to read PEER IP Addresses\n",					card->devname);			}else{				clear_bit(0,&Read_connection_info);				set_bit(1,&Read_connection_info);				trigger_ppp_poll(dev);			}		}else{			//FIXME Put the comment back int			ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;		}	}/* End of PPP_EVENT */	/* Only disable the timer interrupt if there are no udp, statistic */	/* updates or events pending */        if(!ppp_priv_area->timer_int_enabled) {                flags->imask &= ~PPP_INTR_TIMER;        }}static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto){	int i;	if( proto == htons(ETH_P_IPX) ) {		//It's an IPX packet		if(!enable_IPX) {			//Return 1 so we don't pass it up the stack.			return 1;		}	} else {		//It's not IPX so pass it up the stack.		return 0;	}	if( sendpacket[16] == 0x90 &&	    sendpacket[17] == 0x04)	{		//It's IPXWAN		if( sendpacket[2] == 0x02 &&		    sendpacket[34] == 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 = 41; 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[34] = 0x01;			printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);		}		else if( sendpacket[34] == 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[34] = 0x03;			//Set the router name			sendpacket[51] = 'P';			sendpacket[52] = 'T';			sendpacket[53] = 'P';			sendpacket[54] = 'I';			sendpacket[55] = 'P';			sendpacket[56] = 'E';			sendpacket[57] = '-';			sendpacket[58] = CVHexToAscii(network_number >> 28);			sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24);			sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20);			sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16);			sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12);			sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8);			sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4);			sendpacket[65] = CVHexToAscii(network_number & 0x0000000F);			for(i = 66; i < 99; 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[35] = (unsigned char)(network_number >> 24);		sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16);		sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8);		sendpacket[38] = (unsigned char)(network_number & 0x000000FF);		return 1;	} else {		//If we get here's 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;	}}/****** Background Polling Routines  ****************************************//* All polling functions are invoked by the TIMER interrupt in the wpp_isr  * routine.   *//*============================================================================ * Monitor active link phase. */static void process_route (sdla_t *card){	ppp_flags_t *flags = card->flags;	netdevice_t *dev = card->wandev.dev;	ppp_private_area_t *ppp_priv_area = dev->priv;	#if defined(LINUX_2_1) || defined(LINUX_2_4)	if ((card->u.p

⌨️ 快捷键说明

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