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

📄 sdla_chdlc.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		if(chdlc_send(card, data, 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 += len;#endif						start_net_queue(dev);			#ifdef LINUX_2_4		 	dev->trans_start = jiffies;#endif		}		}if_send_exit_crit:		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;}/*============================================================================ * Check to see if the packet to be transmitted contains a broadcast or * multicast source IP address. */static int chk_bcast_mcast_addr(sdla_t *card, netdevice_t* dev,				struct sk_buff *skb){	u32 src_ip_addr;        u32 broadcast_ip_addr = 0;#if defined(LINUX_2_1) || defined(LINUX_2_4)        struct in_device *in_dev;#endif        /* read the IP source address from the outgoing packet */        src_ip_addr = *(u32 *)(skb->data + 12);	/* read the IP broadcast address for the device */#if defined(LINUX_2_1) || defined(LINUX_2_4)        in_dev = dev->ip_ptr;        if(in_dev != NULL) {                struct in_ifaddr *ifa= in_dev->ifa_list;                if(ifa != NULL)                        broadcast_ip_addr = ifa->ifa_broadcast;                else                        return 0;        }#else        broadcast_ip_addr = dev->pa_brdaddr;#endif         /* check if the IP Source Address is a Broadcast address */        if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {                printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n",				card->devname);                return 1;        }         /* check if the IP Source Address is a Multicast address */        if((ntohl(src_ip_addr) >= 0xE0000001) &&		(ntohl(src_ip_addr) <= 0xFFFFFFFE)) {                printk(KERN_INFO "%s: Multicast Source Address silently discarded\n",				card->devname);                return 1;        }        return 0;}/*============================================================================ * 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;	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;	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;}/*=========================================================== * chdlc_disable_comm_shutdown * * Shutdown() disables the communications. We must * have a sparate functions, because we must not * call chdlc_error() hander since the private * area has already been replaced */static int chdlc_disable_comm_shutdown (sdla_t *card){	CHDLC_MAILBOX_STRUCT* mb = card->mbox;	CHDLC_INT_TRIGGERS_STRUCT* int_data =		 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;	int err;	/* Disable Interrutps */	int_data->CHDLC_interrupt_triggers 	= 0;	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;	/* Disable Communications */	if (card->u.c.async_mode) {		mb->command = DISABLE_ASY_COMMUNICATIONS;	}else{		mb->command = DISABLE_CHDLC_COMMUNICATIONS;	}		mb->buffer_length = 0;	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;		card->u.c.comm_enabled = 0;		return 0;}/*============================================================================ * 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;}/*============================================================================ * 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){

⌨️ 快捷键说明

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