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

📄 sdla_chdlc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(skb == NULL) {		/* If we get here, some higher layer thinks we've missed an		 * tx-done interrupt.		 */		printk(KERN_INFO "%s: interface %s got kicked!\n",			card->devname, dev->name);		netif_wake_queue(dev);		return 0;	}   	if(ntohs(skb->protocol) != 0x16) {		/* check the udp packet type */		udp_type = udp_pkt_type(skb, card);		if(udp_type == UDP_CPIPE_TYPE) {                        if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,                                chdlc_priv_area))	                	chdlc_int->interrupt_permission |=					APP_INT_ON_TIMER;			return 0;		}		/* check to see if the source IP address is a broadcast or */		/* multicast IP address */                if(chk_bcast_mcast_addr(card, dev, skb))                        return 0;        }	/* Lock the 508 Card: SMP is supported */      	if(card->hw.type != SDLA_S514){		s508_lock(card,&smp_flags);	}     	if(test_and_set_bit(0, (void*)&card->wandev.critical)) {			printk(KERN_INFO "%s: Critical in if_send: %x\n",					card->wandev.name,card->wandev.critical);                ++card->wandev.stats.tx_dropped;#ifdef LINUX_2_1    		dev_kfree_skb(skb);#else                dev_kfree_skb(skb, FREE_WRITE);#endif			if(card->hw.type != SDLA_S514){			s508_unlock(card,&smp_flags);		}		return 0;	}	if(card->u.c.state != WAN_CONNECTED)       		++card->wandev.stats.tx_dropped;	else if(!skb->protocol)        	++card->wandev.stats.tx_errors;	else {		void* data = skb->data;		unsigned len = skb->len;		unsigned char attr;		/* If it's an API packet pull off the API		 * header. Also check that the packet size		 * is larger than the API header	         */		if (card->u.c.usedby == API){			api_tx_hdr_t* api_tx_hdr;			if (len <= sizeof(api_tx_hdr_t)){#ifdef LINUX_2_1 		               	dev_kfree_skb(skb);#else                		dev_kfree_skb(skb, FREE_WRITE);#endif				++card->wandev.stats.tx_dropped;				clear_bit(0, (void*)&card->wandev.critical);				if(card->hw.type != SDLA_S514){					s508_unlock(card,&smp_flags);				}                		return 0;			}							api_tx_hdr = (api_tx_hdr_t *)data;			attr = api_tx_hdr->attr;			data += sizeof(api_tx_hdr_t);			len -= sizeof(api_tx_hdr_t);		}		if(chdlc_send(card, data, len)) {			netif_stop_queue(dev);			chdlc_priv_area->tick_counter = jiffies;			chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;		}		else {			++card->wandev.stats.tx_packets;                        card->wandev.stats.tx_bytes += len;		}		}	if (!netif_queue_stopped(dev))		dev_kfree_skb(skb);	clear_bit(0, (void*)&card->wandev.critical);	if(card->hw.type != SDLA_S514){		s508_unlock(card,&smp_flags);	}	return netif_queue_stopped(dev);}/*============================================================================ * 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, struct net_device* dev,				struct sk_buff *skb){	u32 src_ip_addr;        u32 broadcast_ip_addr = 0;#ifdef LINUX_2_1        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 */#ifdef LINUX_2_1        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);#ifdef LINUX_2_1                dev_kfree_skb(skb);#else                dev_kfree_skb(skb, FREE_WRITE);#endif                ++card->wandev.stats.tx_dropped;                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);#ifdef LINUX_2_1                dev_kfree_skb(skb);#else                dev_kfree_skb(skb, FREE_WRITE);#endif                ++card->wandev.stats.tx_dropped;                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 net_device_stats. */#ifdef LINUX_2_1static struct net_device_stats* if_stats (struct net_device* dev){	sdla_t *my_card;	chdlc_private_area_t* chdlc_priv_area = dev->priv;	my_card = chdlc_priv_area->card;	return &my_card->wandev.stats; }#elsestatic struct net_device_stats* if_stats (struct net_device* dev){        sdla_t *my_card;        chdlc_private_area_t* chdlc_priv_area = dev->priv;        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);	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);	mb->command = SET_MODEM_STATUS;	mb->buffer_length = 1;	mb->data[0] = 0;	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;

⌨️ 快捷键说明

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