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

📄 wanpipe_multppp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		udp_length += 1;		len += 1;		even_bound = 1;	}  	temp = (udp_length<<8)|(udp_length>>8);	c_udp_pkt->udp_pkt.udp_length = temp;		 	/* swap UDP ports */	temp = c_udp_pkt->udp_pkt.udp_src_port;	c_udp_pkt->udp_pkt.udp_src_port = 			c_udp_pkt->udp_pkt.udp_dst_port; 	c_udp_pkt->udp_pkt.udp_dst_port = temp;	/* add UDP pseudo header */	temp = 0x1100;	*((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;		temp = (udp_length<<8)|(udp_length>>8);	*((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;		 	/* calculate UDP checksum */	c_udp_pkt->udp_pkt.udp_checksum = 0;	c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);	/* fill in IP length */	ip_length = len;	temp = (ip_length<<8)|(ip_length>>8);	c_udp_pkt->ip_pkt.total_length = temp;  	/* swap IP addresses */	ip_temp = c_udp_pkt->ip_pkt.ip_src_address;	c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;	c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;	/* fill in IP checksum */	c_udp_pkt->ip_pkt.hdr_checksum = 0;	c_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;	}/*============================================================================ * Get ethernet-style interface statistics. * Return a pointer to struct enet_statistics. */static struct net_device_stats* if_stats(struct net_device* dev){	sdla_t *my_card;	chdlc_private_area_t* chdlc_priv_area;	/* Shutdown bug fix. In del_if() we kill         * dev->priv pointer. This function, gets         * called after del_if(), thus check         * if pointer has been deleted */	if ((chdlc_priv_area=dev->priv) == NULL)		return NULL;	my_card = chdlc_priv_area->card;	return &my_card->wandev.stats; }/****** Cisco HDLC Firmware Interface Functions *******************************//*============================================================================ * Read firmware code version. *	Put code version as ASCII string in str.  */static int chdlc_read_version (sdla_t* card, char* str){	CHDLC_MAILBOX_STRUCT* mb = card->mbox;	int len;	char err;	mb->buffer_length = 0;	mb->command = READ_CHDLC_CODE_VERSION;	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;	if(err != COMMAND_OK) {		chdlc_error(card,err,mb);	}	else if (str) {  /* is not null */		len = mb->buffer_length;		memcpy(str, mb->data, len);		str[len] = '\0';	}	return (err);}/*----------------------------------------------------------------------------- *  Configure CHDLC firmware. */static int chdlc_configure (sdla_t* card, void* data){	int err;	CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;	int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);		mailbox->buffer_length = data_length;  	memcpy(mailbox->data, data, data_length);	mailbox->command = SET_CHDLC_CONFIGURATION;	err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;		if (err != COMMAND_OK) chdlc_error (card, err, mailbox);                           	return err;}/*============================================================================ * Set interrupt mode -- HDLC Version. */static int chdlc_set_intr_mode (sdla_t* card, unsigned mode){	CHDLC_MAILBOX_STRUCT* mb = card->mbox;	CHDLC_INT_TRIGGERS_STRUCT* int_data =		 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;	int err;	int_data->CHDLC_interrupt_triggers 	= mode;	int_data->IRQ				= card->hw.irq;	int_data->interrupt_timer               = 1;   	mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);	mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;	if (err != COMMAND_OK)		chdlc_error (card, err, mb);	return err;}/*============================================================================ * Enable communications. */static int chdlc_comm_enable (sdla_t* card){	int err;	CHDLC_MAILBOX_STRUCT* mb = card->mbox;	mb->buffer_length = 0;	mb->command = ENABLE_CHDLC_COMMUNICATIONS;	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;	if (err != COMMAND_OK)		chdlc_error(card, err, mb);	else		card->u.c.comm_enabled=1;	return err;}/*============================================================================ * Disable communications and Drop the Modem lines (DCD and RTS). */static int chdlc_comm_disable (sdla_t* card){	int err;	CHDLC_MAILBOX_STRUCT* mb = card->mbox;	mb->buffer_length = 0;	mb->command = DISABLE_CHDLC_COMMUNICATIONS;	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;	if (err != COMMAND_OK)		chdlc_error(card,err,mb);	return err;}/*============================================================================ * Read communication error statistics. */static int chdlc_read_comm_err_stats (sdla_t* card){        int err;        CHDLC_MAILBOX_STRUCT* mb = card->mbox;        mb->buffer_length = 0;        mb->command = READ_COMMS_ERROR_STATS;        err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;        if (err != COMMAND_OK)                chdlc_error(card,err,mb);        return err;}/*============================================================================ * Read CHDLC operational statistics. */static int chdlc_read_op_stats (sdla_t* card){        int err;        CHDLC_MAILBOX_STRUCT* mb = card->mbox;        mb->buffer_length = 0;        mb->command = READ_CHDLC_OPERATIONAL_STATS;        err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;        if (err != COMMAND_OK)                chdlc_error(card,err,mb);        return err;}/*============================================================================ * Update communications error and general packet statistics. */static int update_comms_stats(sdla_t* card,	chdlc_private_area_t* chdlc_priv_area){        CHDLC_MAILBOX_STRUCT* mb = card->mbox;  	COMMS_ERROR_STATS_STRUCT* err_stats;        CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;	/* on the first timer interrupt, read the comms error statistics */	if(chdlc_priv_area->update_comms_stats == 2) {		if(chdlc_read_comm_err_stats(card))			return 1;		err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;		card->wandev.stats.rx_over_errors = 				err_stats->Rx_overrun_err_count;		card->wandev.stats.rx_crc_errors = 				err_stats->CRC_err_count;		card->wandev.stats.rx_frame_errors = 				err_stats->Rx_abort_count;		card->wandev.stats.rx_fifo_errors = 				err_stats->Rx_dis_pri_bfrs_full_count; 		card->wandev.stats.rx_missed_errors =				card->wandev.stats.rx_fifo_errors;		card->wandev.stats.tx_aborted_errors =				err_stats->sec_Tx_abort_count;	}        /* on the second timer interrupt, read the operational statistics */	else {        	if(chdlc_read_op_stats(card))                	return 1;		op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;		card->wandev.stats.rx_length_errors =			(op_stats->Rx_Data_discard_short_count +			op_stats->Rx_Data_discard_long_count);	}	return 0;}/*============================================================================ * Send packet. *	Return:	0 - o.k. *		1 - no transmit buffers available */static int chdlc_send (sdla_t* card, void* data, unsigned len){	CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;	if (txbuf->opp_flag)		return 1;		sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);	txbuf->frame_length = len;	txbuf->opp_flag = 1;		/* start transmission */		/* Update transmit buffer control fields */	card->u.c.txbuf = ++txbuf;	if ((void*)txbuf > card->u.c.txbuf_last)		card->u.c.txbuf = card->u.c.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 chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb){	unsigned cmd = mb->command;	switch (err) {	case CMD_TIMEOUT:		printk(KERN_ERR "%s: command 0x%02X timed out!\n",			card->devname, cmd);		break;	case S514_BOTH_PORTS_SAME_CLK_MODE:		if(cmd == SET_CHDLC_CONFIGURATION) {			printk(KERN_INFO			 "%s: Configure both ports for the same clock source\n",				card->devname);			break;		}	default:		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",			card->devname, cmd, err);	}	return 0;}/****** Interrupt Handlers **************************************************//*============================================================================ * Cisco HDLC interrupt service routine. */STATIC void wsppp_isr (sdla_t* card){	struct net_device* dev;	SHARED_MEMORY_INFO_STRUCT* flags = NULL;	int i;	sdla_t *my_card;	/* Check for which port the interrupt has been generated	 * Since Secondary Port is piggybacking on the Primary         * the check must be done here. 	 */	flags = card->u.c.flags;	if (!flags->interrupt_info_struct.interrupt_type){		/* Check for a second port (piggybacking) */		if((my_card = card->next)){			flags = my_card->u.c.flags;			if (flags->interrupt_info_struct.interrupt_type){				card = my_card;				card->isr(card);				return;			}		}	}	dev = card->wandev.dev;	card->in_isr = 1;	flags = card->u.c.flags;			/* If we get an interrupt with no network device, stop the interrupts	 * and issue an error */	if ((!dev || !dev->priv) && flags->interrupt_info_struct.interrupt_type != 	    	COMMAND_COMPLETE_APP_INT_PEND){		goto isr_done;	}		/* if critical due to peripheral operations	 * ie. update() or getstats() then reset the interrupt and	 * wait for the board to retrigger.	 */	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {		flags->interrupt_info_struct.					interrupt_type = 0;		goto isr_done;	}	/* On a 508 Card, if critical due to if_send          * Major Error !!!	 */	if(card->hw.type != SDLA_S514) {		if(test_bit(0, (void*)&card->wandev.critical)) {			printk(KERN_INFO "%s: Critical while in ISR: %lx\n",				card->devname, card->wandev.critical);			goto isr_done;		}	}	switch(flags->interrupt_info_struct.interrupt_type) {		case RX_APP_INT_PEND:	/* 0x01: receive interrupt */			rx_intr(card);			break;		case TX_APP_INT_PEND:	/* 0x02: transmit interrupt */			flags->interrupt_info_struct.interrupt_permission &=				 ~APP_INT_ON_TX_FRAME;			netif_wake_queue(dev);			break;		case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */			++ Intr_test_counter;			break;		case CHDLC_EXCEP_COND_APP_INT_PEND:	/* 0x20 */			process_chdlc_exception(card);			break;		case GLOBAL_EXCEP_COND_APP_INT_PEND:			process_global_exception(card);			break;		case TIMER_APP_INT_PEND:			timer_intr(card);			break;		default:			printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", 				card->devname,				flags->interrupt_info_struct.interrupt_type);			printk(KERN_INFO "Code name: ");			for(i = 0; i < 4; i ++)				printk(KERN_INFO "%c",					flags->global_info_struct.codename[i]); 			printk(KERN_INFO "\nCode version: ");			for(i = 0; i < 4; i ++)				printk(KERN_INFO "%c", 					flags->global_info_struct.codeversion[i]); 			printk(KERN_INFO "\n");				break;	}isr_done:	card->in_isr = 0;	flags->interrupt_info_struct.interrupt_type = 0;}/*============================================================================ * Receive interrupt handler. */

⌨️ 快捷键说明

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