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

📄 wanpipe_multppp.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
					card->wandev.name,card->wandev.critical);                ++card->wandev.stats.tx_dropped;		start_net_queue(dev);		goto if_send_crit_exit;	}	if (card->wandev.state != WAN_CONNECTED){		++card->wandev.stats.tx_dropped;		start_net_queue(dev);		goto if_send_crit_exit;	}		if (chdlc_send(card, skb->data, skb->len)){		stop_net_queue(dev);	}else{		++card->wandev.stats.tx_packets;#if defined(LINUX_2_1) || defined(LINUX_2_4)       		card->wandev.stats.tx_bytes += skb->len;#endif#ifdef LINUX_2_4		dev->trans_start = jiffies;#endif		start_net_queue(dev);	}	if_send_crit_exit:	if (!(err=is_queue_stopped(dev))){                wan_dev_kfree_skb(skb, FREE_WRITE);	}else{		chdlc_priv_area->tick_counter = jiffies;		chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;	}	clear_bit(SEND_CRIT, (void*)&card->wandev.critical);	if(card->hw.type != SDLA_S514){		s508_unlock(card,&smp_flags);	}	return err;}/*============================================================================ * 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;  	chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;	 	/* Set length of packet */	len = sizeof(ip_pkt_t)+ 	      sizeof(udp_pkt_t)+	      sizeof(wp_mgmt_t)+	      sizeof(cblock_t)+	      sizeof(trace_info_t)+ 	      mbox_len;	/* fill in UDP reply */	c_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)+	             sizeof(trace_info_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);	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. */#if defined(LINUX_2_1) || defined(LINUX_2_4)static struct net_device_stats* if_stats (netdevice_t* 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; }#elsestatic struct enet_statistics* if_stats (netdevice_t* dev){        sdla_t *my_card;        chdlc_private_area_t* chdlc_priv_area = dev->priv;	/* 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;}#endif/****** 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){	netdevice_t* 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;

⌨️ 快捷键说明

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