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

📄 sdla_fr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE) mode.\n", 					card->devname);		}else if( strcmp(conf->usedby, "BRIDGE_N") == 0 ){						chan->common.usedby = BRIDGE_NODE;					printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", 					card->devname);		}		if (!err){			/* Dynamic interface configuration option.			 * On disconnect, if the options is selected,			 * the interface will be brought down */			if (conf->if_down == WANOPT_YES){ 				set_bit(DYN_OPT_ON,&chan->interface_down);				printk(KERN_INFO 				    "%s: Dynamic interface configuration enabled.\n",					card->devname);			}		}        } else if(strcmp(conf->usedby, "API") == 0){                chan->common.usedby = API;                printk(KERN_INFO "%s: Running in API mode.\n",			wandev->name);        }	if (err) {				kfree(chan);		return err;	}	/* place cir,be,bc and other channel specific information into the	 * chan structure          */	if (conf->cir) {		chan->cir = max_t(unsigned int, 1,				min_t(unsigned int, conf->cir, 512));		chan->cir_status = CIR_ENABLED; 				/* If CIR is enabled, force BC to equal CIR                 * this solves number of potential problems if CIR is                  * set and BC is not 		 */		chan->bc = chan->cir;		if (conf->be){			chan->be = max_t(unsigned int,				       0, min_t(unsigned int, conf->be, 511));		}else{				conf->be = 0;		}		printk (KERN_INFO "%s: CIR enabled for DLCI %i \n",				wandev->name,chan->dlci);		printk (KERN_INFO "%s:     CIR = %i ; BC = %i ; BE = %i\n",				wandev->name,chan->cir,chan->bc,chan->be);	}else{		chan->cir_status = CIR_DISABLED;		printk (KERN_INFO "%s: CIR disabled for DLCI %i\n",				wandev->name,chan->dlci);	}	chan->mc = conf->mc;	if (conf->inarp == WANOPT_YES){		printk(KERN_INFO "%s: Inverse ARP Support Enabled\n",card->devname);		chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE;		chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10;	}else{		printk(KERN_INFO "%s: Inverse ARP Support Disabled\n",card->devname);		chan->inarp = INARP_NONE;		chan->inarp_interval = 10;	}	chan->dlci_configured = DLCI_NOT_CONFIGURED;		/*FIXME: IPX disabled in this WANPIPE version */	if (conf->enable_IPX == WANOPT_YES){		printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n",				card->devname);		kfree(chan);		return -EINVAL;	}else{		chan->enable_IPX = WANOPT_NO;	}		if (conf->network_number){		chan->network_number = conf->network_number;	}else{		chan->network_number = 0xDEADBEEF;	}	chan->route_flag = NO_ROUTE;		init_chan_statistics(chan);	chan->transmit_length = 0;	/* prepare network device data space for registration */	strcpy(dev->name,chan->name);		dev->init = &if_init;	dev->priv = chan;	/* Initialize FR Polling Task Queue         * We need a poll routine for each network         * interface.          */	INIT_WORK(&chan->fr_poll_work, (void *)fr_poll, dev);	init_timer(&chan->fr_arp_timer);	chan->fr_arp_timer.data=(unsigned long)dev;	chan->fr_arp_timer.function = fr_arp;	wandev->new_if_cnt++;	/* Tells us that if this interface is a         * gateway or not */	if ((chan->gateway = conf->gateway) == WANOPT_YES){		printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",			card->devname,dev->name);	}	/* M. Grant Patch Apr 28 2000          * Disallow duplicate dlci configurations. */	if (card->u.f.dlci_to_dev_map[chan->dlci] != NULL) {		kfree(chan);		return -EBUSY;	}	/* Configure this dlci at a later date, when         * the interface comes up. i.e. when if_open()          * executes */	set_bit(0,&chan->config_dlci);		printk(KERN_INFO "\n");	return 0;}/*============================================================================ * Delete logical channel. */static int del_if(struct wan_device* wandev, struct net_device* dev){	fr_channel_t* chan = dev->priv;	unsigned long smp_flags=0;	/* This interface is dead, make sure the 	 * ARP timer is stopped */	del_timer(&chan->fr_arp_timer);		/* If we are a NODE, we must unconfigure this DLCI	 * Trigger an unconfigure command that will	 * be executed in timer interrupt. We must wait	 * for the command to complete. */	trigger_unconfig_fr(dev);	lock_adapter_irq(&wandev->lock, &smp_flags);	wandev->new_if_cnt--;	unlock_adapter_irq(&wandev->lock, &smp_flags);	return 0;}/*===================================================================== * disable_comm * * Description: *	Disable communications. * 	This code runs in shutdown (sdlamain.c) *      under critical flag. Therefore it is not *      necessary to set a critical flag here  * * Usage: * 	Commnunications are disabled only on a card *      shutdown. */static void disable_comm (sdla_t *card){	printk(KERN_INFO "%s: Disabling Communications!\n",			card->devname);	fr_comm_disable(card);}/****** WANPIPE-specific entry points ***************************************//*============================================================================ * Execute adapter interface command. */static int wpf_exec (struct sdla* card, void* u_cmd, void* u_data){	fr_mbox_t* mbox = card->mbox;	int retry = MAX_CMD_RETRY;	int err, len;	fr_cmd_t cmd;	if(copy_from_user((void*)&cmd, u_cmd, sizeof(cmd)))		return -EFAULT;		/* execute command */	do	{		memcpy(&mbox->cmd, &cmd, sizeof(cmd));				if (cmd.length){			if( copy_from_user((void*)&mbox->data, u_data, cmd.length))				return -EFAULT;		}				if (sdla_exec(mbox))			err = mbox->cmd.result;		else return -EIO;		} while (err && retry-- && fr_event(card, err, mbox));	/* return result */	if (copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(fr_cmd_t)))		return -EFAULT;	len = mbox->cmd.length;	if (len && u_data && !copy_to_user(u_data, (void*)&mbox->data, len))		return -EFAULT;	return 0;}/****** Network Device Interface ********************************************//*============================================================================ * Initialize Linux network interface. * * This routine is called only once for each interface, during Linux network * interface registration.  Returning anything but zero will fail interface * registration. */static int if_init(struct net_device* dev){	fr_channel_t* chan = dev->priv;	sdla_t* card = chan->card;	struct wan_device* wandev = &card->wandev;	/* Initialize device driver entry points */	dev->open		= &if_open;	dev->stop		= &if_close;	dev->hard_header	= NULL;	dev->rebuild_header	= &if_rebuild_hdr;	dev->hard_start_xmit	= &if_send;	dev->get_stats		= &if_stats;	dev->tx_timeout		= &if_tx_timeout;	dev->watchdog_timeo	= TX_TIMEOUT;		if (chan->common.usedby == WANPIPE || chan->common.usedby == API){		/* Initialize media-specific parameters */		if (chan->true_if_encoding){			dev->type 		= ARPHRD_DLCI;  /* This breaks tcpdump */		}else{			dev->type		= ARPHRD_PPP; 	/* ARP h/w type */		}				dev->flags		|= IFF_POINTOPOINT;		dev->flags		|= IFF_NOARP;		/* Enable Multicast addressing */		if (chan->mc == WANOPT_YES){			dev->flags 	|= IFF_MULTICAST;		}		dev->mtu		= wandev->mtu - FR_HEADER_LEN;		/* For an API, the maximum number of bytes that the stack will pass		   to the driver is (dev->mtu + dev->hard_header_len). So, adjust the		   mtu so that a frame of maximum size can be transmitted by the API. 		*/		if(chan->common.usedby == API) {			dev->mtu += (sizeof(api_tx_hdr_t) - FR_HEADER_LEN);		}				dev->hard_header_len	= FR_HEADER_LEN;/* media header length */		dev->addr_len		= 2; 		/* hardware address length */		*(unsigned short*)dev->dev_addr = htons(chan->dlci);		/* Set transmit buffer queue length */        	dev->tx_queue_len = 100;	}else{		/* Setup the interface for Bridging */		int hw_addr=0;		ether_setup(dev);				/* Use a random number to generate the MAC address */		memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6);		get_random_bytes(&hw_addr, sizeof(hw_addr));		*(int *)(dev->dev_addr + 2) += hw_addr;	}			/* Initialize hardware parameters (just for reference) */	dev->irq	= wandev->irq;	dev->dma	= wandev->dma;	dev->base_addr	= wandev->ioport;	dev->mem_start	= wandev->maddr;	dev->mem_end	= wandev->maddr + wandev->msize - 1;	SET_MODULE_OWNER(dev);	return 0;}/*============================================================================ * Open network interface. * o if this is the first open, then enable communications and interrupts. * o prevent module from unloading by incrementing use count * * Return 0 if O.k. or errno. */static int if_open(struct net_device* dev){	fr_channel_t* chan = dev->priv;	sdla_t* card = chan->card;	int err = 0;	struct timeval tv;	if (netif_running(dev))		return -EBUSY;		/* Initialize the task queue */	chan->tq_working=0;	INIT_WORK(&chan->common.wanpipe_work, (void *)fr_bh, dev);	/* Allocate and initialize BH circular buffer */	chan->bh_head = kmalloc((sizeof(bh_data_t)*MAX_BH_BUFF),GFP_ATOMIC);	memset(chan->bh_head,0,(sizeof(bh_data_t)*MAX_BH_BUFF));	atomic_set(&chan->bh_buff_used, 0);	netif_start_queue(dev);	wanpipe_open(card);	do_gettimeofday( &tv );	chan->router_start_time = tv.tv_sec;		if (test_bit(0,&chan->config_dlci)){		trigger_config_fr (card);	}else if (chan->inarp == INARP_REQUEST){		trigger_fr_arp(dev);	}		return err;}/*============================================================================ * Close network interface. * o if this is the last open, then disable communications and interrupts. * o reset flags. */static int if_close(struct net_device* dev){	fr_channel_t* chan = dev->priv;	sdla_t* card = chan->card;	if (chan->inarp == INARP_CONFIGURED) {		chan->inarp = INARP_REQUEST;	}	netif_stop_queue(dev);	wanpipe_close(card);	return 0;}/*============================================================================ * Re-build media header. * * Return:	1	physical address resolved. *		0	physical address not resolved */static int if_rebuild_hdr (struct sk_buff* skb){	struct net_device *dev = skb->dev;	fr_channel_t* chan = dev->priv;	sdla_t* card = chan->card;	printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n",		card->devname, dev->name);	return 1;}/*============================================================================ * Handle transmit timeout event from netif watchdog */static void if_tx_timeout(struct net_device *dev){    	fr_channel_t* chan = dev->priv;	sdla_t *card = chan->card;	/* If our device stays busy for at least 5 seconds then we will	 * kick start the device by making dev->tbusy = 0.  We expect	 * that our device never stays busy more than 5 seconds. So this                 	 * is only used as a last resort.	 */	chan->drvstats_if_send.if_send_tbusy++;	++chan->ifstats.collisions;	printk (KERN_INFO "%s: Transmit timed out on %s\n", 			card->devname, dev->name);	chan->drvstats_if_send.if_send_tbusy_timeout++;	netif_wake_queue (dev);}/*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based *   transmit from overlapping. * o set critical flag when accessing board. * o check link state. If link is not up, then drop the packet. * o check channel status. If it's down then initiate a call. * o pass a packet to corresponding WAN device. * o free socket buffer * * Return:	0	complete (socket buffer must be freed)

⌨️ 快捷键说明

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