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

📄 sdla_ppp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
        tokens[0] = strsep(&str, "/");        while (tokens[cnt] && (cnt < 32 - 1))        {                tokens[cnt] = strstrip(tokens[cnt], " \t");                tokens[++cnt] = strsep(&str, "/");        }	return cnt;}/*============================================================================ * Strip leading and trailing spaces off the string str. */static char* strstrip (char *str, char* s){        char *eos = str + strlen(str);          /* -> end of string */        while (*str && strchr(s, *str))                ++str                           /* strip leading spaces */        ;        while ((eos > str) && strchr(s, *(eos - 1)))                --eos                           /* strip trailing spaces */        ;        *eos = '\0';        return str;}/*============================================================================ * Configure PPP firmware. */static int ppp_configure(sdla_t *card, void *data){	ppp_mbox_t *mb = card->mbox;	int data_len = sizeof(ppp508_conf_t); 	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	memcpy(mb->data, data, data_len);	mb->cmd.length  = data_len;	mb->cmd.command = PPP_SET_CONFIG;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK) 		ppp_error(card, err, mb);		return err;}/*============================================================================ * Set interrupt mode. */static int ppp_set_intr_mode(sdla_t *card, unsigned char mode){	ppp_mbox_t *mb = card->mbox;        ppp_intr_info_t *ppp_intr_data = (ppp_intr_info_t *) &mb->data[0];	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	ppp_intr_data->i_enable = mode;	ppp_intr_data->irq = card->hw.irq;	mb->cmd.length = 2;       /* If timer has been enabled, set the timer delay to 1sec */       if (mode & 0x80){       		ppp_intr_data->timer_len = 250; //5;//100; //250;                mb->cmd.length = 4;        }		mb->cmd.command = PPP_SET_INTR_FLAGS;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;		if (err != CMD_OK) 		ppp_error(card, err, mb); 			return err;}/*============================================================================ * Enable communications. */static int ppp_comm_enable(sdla_t *card){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_COMM_ENABLE;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;		if (err != CMD_OK) 		ppp_error(card, err, mb);	else			card->u.p.comm_enabled = 1;		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);	else		card->u.p.comm_enabled = 0;	return err;}static int ppp_comm_disable_shutdown(sdla_t *card){	ppp_mbox_t *mb = card->mbox;	ppp_intr_info_t *ppp_intr_data;	int err;	if (!mb){		return 1;	}		ppp_intr_data = (ppp_intr_info_t *) &mb->data[0];		/* Disable all interrupts */	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	ppp_intr_data->i_enable = 0;	ppp_intr_data->irq = card->hw.irq;	mb->cmd.length = 2;	mb->cmd.command = PPP_SET_INTR_FLAGS;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	/* Disable communicatinons */	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_COMM_DISABLE;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	card->u.p.comm_enabled = 0;	return 0;}/*============================================================================ * 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;	if (!dev && flags->iflag != PPP_INTR_CMD){		card->in_isr = 0;		flags->iflag = 0;		return;	}		if (test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {		card->in_isr = 0;		flags->iflag = 0;		return;	}			if(card->hw.type != SDLA_S514){		if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {			++card->statistics.isr_already_critical;			printk (KERN_INFO "%s: Critical while in ISR!\n",					card->devname);			card->in_isr = 0;			flags->iflag = 0;			return;		}	}	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);			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;	return;}/*============================================================================ * 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;		/* 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 && netif_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));					}					dev_kfree_skb_any(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);				dev->last_rx = jiffies;			}

⌨️ 快捷键说明

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