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

📄 sdla_ppp.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		ppp_error(card, err, mb);		return err;}/*============================================================================ * Disable communications. */static int ppp_comm_disable(sdla_t *card){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_COMM_DISABLE;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK) 		ppp_error(card, err, mb);	return err;}/*============================================================================ * Get communications error statistics. */static int ppp_get_err_stats(sdla_t *card){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_READ_ERROR_STATS;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;		if (err == CMD_OK) {				ppp_err_stats_t* stats = (void*)mb->data;		card->wandev.stats.rx_over_errors    = stats->rx_overrun;		card->wandev.stats.rx_crc_errors     = stats->rx_bad_crc;		card->wandev.stats.rx_missed_errors  = stats->rx_abort;		card->wandev.stats.rx_length_errors  = stats->rx_lost;		card->wandev.stats.tx_aborted_errors = stats->tx_abort;		} else 		ppp_error(card, err, mb);		return err;}/*============================================================================ * Send packet. *	Return:	0 - o.k. *		1 - no transmit buffers available */static int ppp_send (sdla_t *card, void *data, unsigned len, unsigned proto){	ppp_buf_ctl_t *txbuf = card->u.p.txbuf;	if (txbuf->flag)                return 1;		sdla_poke(&card->hw, txbuf->buf.ptr, data, len);	txbuf->length = len;		/* frame length */		if (proto == htons(ETH_P_IPX))		txbuf->proto = 0x01;	/* protocol ID */	else		txbuf->proto = 0x00;	/* protocol ID */		txbuf->flag = 1;		/* start transmission */	/* Update transmit buffer control fields */	card->u.p.txbuf = ++txbuf;	if ((void*)txbuf > card->u.p.txbuf_last)		card->u.p.txbuf = card->u.p.txbuf_base;	return 0;}/****** Firmware Error Handler **********************************************//*============================================================================ * Firmware error handler. *	This routine is called whenever firmware command returns non-zero *	return code. * * Return zero if previous command has to be cancelled. */static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb){	unsigned cmd = mb->cmd.command;	switch (err) {		case CMD_TIMEOUT:			printk(KERN_ERR "%s: command 0x%02X timed out!\n",				card->devname, cmd);			break;		default:			printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"				, card->devname, cmd, err);	}	return 0;}/****** Interrupt Handlers **************************************************//*============================================================================ * PPP interrupt service routine. */STATIC void wpp_isr(sdla_t *card){	ppp_flags_t *flags = card->flags;	char *ptr = &flags->iflag;	struct net_device *dev = card->wandev.dev;	int i;	card->in_isr = 1;		++card->statistics.isr_entry;	//FIXME: Do we need this	card->force_enable_irq = 0;	if(card->hw.type != SDLA_S514){		if (test_and_set_bit(0, (void*)&card->wandev.critical)) {        				++card->statistics.isr_already_critical;			printk (KERN_INFO "%s: Critical while in ISR!\n",					card->devname);			card->in_isr = 0;			return;			}	}	card->buff_int_mode_unbusy = 0;	switch (flags->iflag) {		case PPP_INTR_RXRDY:	/* receive interrupt  0x01  (bit 0)*/			++card->statistics.isr_rx;			rx_intr(card);			break;		case PPP_INTR_TXRDY:	/* transmit interrupt  0x02 (bit 1)*/			++card->statistics.isr_tx;			flags->imask &= ~PPP_INTR_TXRDY;			netif_wake_queue (dev);			card->buff_int_mode_unbusy = 1;			break;		case PPP_INTR_CMD:      /* interface command completed */			++Intr_test_counter;			++card->statistics.isr_intr_test;			break;		case PPP_INTR_MODEM:    /* modem status change (DCD, CTS) 0x04 (bit 2)*/		case PPP_INTR_DISC:  	/* Data link disconnected 0x10  (bit 4)*/			case PPP_INTR_OPEN:   	/* Data link open 0x20  (bit 5)*/		case PPP_INTR_DROP_DTR:	/* DTR drop timeout expired  0x40 bit 6 */			event_intr(card);			break;			case PPP_INTR_TIMER:			timer_intr(card);			break;	 		default:	/* unexpected interrupt */			++card->statistics.isr_spurious;			printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", 				card->devname, flags->iflag);			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->in_isr = 0;	flags->iflag = 0;	card->wandev.critical = 0;	if(card->buff_int_mode_unbusy)		netif_wake_queue(dev);}/*============================================================================ * Receive interrupt handler. */static void rx_intr(sdla_t *card){	ppp_buf_ctl_t *rxbuf = card->rxmb;	struct net_device *dev = card->wandev.dev;	ppp_private_area_t *ppp_priv_area;	struct sk_buff *skb;	unsigned len;	void *buf;	int i;        ppp_flags_t *flags = card->flags;        char *ptr = &flags->iflag;	int udp_type;		if (rxbuf->flag != 0x01) {		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;		return;	}	if (dev && netif_running(dev)) {			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) {					ppp_send(card, skb->data, skb->len, htons(ETH_P_IPX));                        		dev_kfree_skb(skb);				} 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;				card->wandev.stats.rx_bytes += skb->len;		    		++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack;					netif_rx(skb);			}		} else {					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;			               		dev_kfree_skb(skb);		}	} 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){ 	struct net_device* 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)*/			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) { 					Read_connection_info = 1;					remove_route (card);				}				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;			}			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                                  */                                card->state_tick = jiffies;				wanpipe_set_state(card, WAN_CONNECTED);				ppp_priv_area->timer_int_enabled |= 						TMR_INT_ENABLED_PPP_EVENT;				flags->imask |= PPP_INTR_TIMER;			}                   	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) { 				Read_connection_info = 1;				remove_route (card);			}			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;			break;				default:			printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname);	}}/* TIMER INTERRUPT */void timer_intr (sdla_t *card){        struct net_device* dev = card->wandev.dev;        ppp_private_area_t* ppp_priv_area = dev->priv;	ppp_flags_t *flags = card->flags;	/* 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){			poll_disconnected(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) && 		  	Read_connection_info){			card->state_tick = jiffies;			if (!read_connection_info (card)){				card->poll = &process_route;			}		}else{			/* If we are using Static IP,no need to poll for			 * an IP address. 		 	 */			NEX_PRINTK(KERN_INFO "Turning off TIMER \n");			ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;		}		}/* End of PPP_EVENT */

⌨️ 快捷键说明

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