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

📄 sdla_x25.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
}/*=================================================================== * Name:	new_if * * Purpose:	To allocate and initialize resources for a  *              new logical channel.   *  * Rationale:	A new channel can be added dynamically via *              ioctl call. *                 * Description:	Allocate a private channel structure, x25_channel_t. *		Parse the user interface options from wanpipe#.conf  *		configuration file.  *		Bind the private are into the network device private *              area pointer (dev->priv). *		Prepare the network device structure for registration. * * Called by:	ROUTER_IFNEW Ioctl call, from wanrouter_ioctl()  *              (wanmain.c) * * Assumptions: None * * Warnings:	None * * Return: 	0 	Ok *		<0 	Failed (channel will not be created) */static int new_if(struct wan_device* wandev, struct net_device* dev,		  wanif_conf_t* conf){	sdla_t* card = wandev->private;	x25_channel_t* chan;	int err = 0;	if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)){		printk(KERN_INFO "%s: invalid interface name!\n",			card->devname);		return -EINVAL;	}	if(card->wandev.new_if_cnt++ > 0 && card->u.x.LAPB_hdlc) {		printk(KERN_INFO "%s: Error: Running LAPB HDLC Mode !\n",						card->devname);		printk(KERN_INFO 			"%s: Maximum number of network interfaces must be one !\n",						card->devname);		return -EEXIST;	}	/* allocate and initialize private data */	chan = kmalloc(sizeof(x25_channel_t), GFP_ATOMIC);	if (chan == NULL){		return -ENOMEM;	}		memset(chan, 0, sizeof(x25_channel_t));	/* Bug Fix: Seg Err on PVC startup	 * It must be here since bind_lcn_to_dev expects 	 * it bellow */	dev->priv = chan;		strcpy(chan->name, conf->name);	chan->card = card;	chan->dev = dev;	chan->common.sk = NULL;	chan->common.func = NULL;	chan->common.rw_bind = 0;	chan->tx_skb = chan->rx_skb = NULL;	/* verify media address */	if (conf->addr[0] == '@'){		/* SVC */		chan->common.svc = 1;		strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);		/* Set channel timeouts (default if not specified) */		chan->idle_timeout = (conf->idle_timeout) ? 					conf->idle_timeout : 90;		chan->hold_timeout = (conf->hold_timeout) ? 					conf->hold_timeout : 10;	}else if (isdigit(conf->addr[0])){	/* PVC */		int lcn = dec_to_uint(conf->addr, 0);		if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){			bind_lcn_to_dev (card, dev, lcn);		}else{			printk(KERN_ERR				"%s: PVC %u is out of range on interface %s!\n",				wandev->name, lcn, chan->name);			err = -EINVAL;		}	}else{		printk(KERN_ERR			"%s: invalid media address on interface %s!\n",			wandev->name, chan->name);		err = -EINVAL;	}	if(strcmp(conf->usedby, "WANPIPE") == 0){                printk(KERN_INFO "%s: Running in WANPIPE mode %s\n",			wandev->name, chan->name);                chan->common.usedby = WANPIPE;		chan->protocol = htons(ETH_P_IP);        }else if(strcmp(conf->usedby, "API") == 0){		chan->common.usedby = API;                printk(KERN_INFO "%s: Running in API mode %s\n",			wandev->name, chan->name);		chan->protocol = htons(X25_PROT);	}	if (err){		kfree(chan);		dev->priv = NULL;		return err;	}		chan->enable_IPX = conf->enable_IPX;		if (chan->enable_IPX)		chan->protocol = htons(ETH_P_IPX);		if (conf->network_number)		chan->network_number = conf->network_number;	else		chan->network_number = 0xDEADBEEF;	/* prepare network device data space for registration */	strcpy(dev->name,chan->name);	dev->init = &if_init;	init_x25_channel_struct(chan);	return 0;}/*=================================================================== * Name:	del_if(),  Remove a logical channel.	  * * Purpose:	To dynamically remove a logical channel. *  * Rationale:	Each logical channel should be dynamically *              removable. This functin is called by an  *              IOCTL_IFDEL ioctl call or shutdown().  *                 * Description: Do nothing. * * Called by:	IOCTL_IFDEL : wanrouter_ioctl() from wanmain.c *              shutdown() from sdlamain.c * * Assumptions:  * * Warnings: * * Return: 	0 Ok. Void function. *///FIXME Del IF Should be taken out now.static int del_if(struct wan_device* wandev, struct net_device* dev){	return 0;}/*============================================================ * Name:	wpx_exec * * Description:	Execute adapter interface command. * 		This option is currently dissabled. *===========================================================*/static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data){        return 0;}/*============================================================ * Name:	disable_comm	 * * Description:	Disable communications during shutdown. *              Dont check return code because there is  *              nothing we can do about it.   * * Warning:	Dev and private areas are gone at this point. *===========================================================*/static void disable_comm(sdla_t* card){	disable_comm_shutdown(card);	del_timer(&card->u.x.x25_timer);	return;}/*============================================================ *	Network Device Interface  *===========================================================*//*=================================================================== * Name:	if_init(),   Netowrk Interface Initialization 	  * * Purpose:	To initialize a network interface device structure. *  * Rationale:	During network interface startup, the if_init *              is called by the kernel to initialize the *              netowrk device structure.  Thus a driver *              can customze a network device.  *                 * Description:	Initialize the netowrk device call back *              routines.  This is where we tell the kernel *              which function to use when it wants to send *              via our interface.  *		Furthermore, we initialize the device flags,  *              MTU and physical address of the board. * * Called by:	Kernel (/usr/src/linux/net/core/dev.c) * 		(dev->init()) * * Assumptions: None *	 * Warnings:	None * * Return: 	0 	Ok : Void function. */static int if_init(struct net_device* dev){	x25_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	= &if_header;	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;	/* Initialize media-specific parameters */	dev->type		= ARPHRD_PPP;		/* ARP h/w type */	dev->flags		|= IFF_POINTOPOINT;	dev->flags		|= IFF_NOARP;	if (chan->common.usedby == API){		dev->mtu	= X25_CHAN_MTU+sizeof(x25api_hdr_t);	}else{		dev->mtu	= card->wandev.mtu; 		}		dev->hard_header_len	= X25_HRDHDR_SZ; /* media header length */	dev->addr_len		= 2;		/* hardware address length */		if (!chan->common.svc){		*(unsigned short*)dev->dev_addr = htons(chan->common.lcn);	}		/* Initialize hardware parameters (just for reference) */	dev->irq	= wandev->irq;	dev->dma	= wandev->dma;	dev->base_addr	= wandev->ioport;	dev->mem_start	= (unsigned long)wandev->maddr;	dev->mem_end	= wandev->maddr + wandev->msize - 1;        /* Set transmit buffer queue length */        dev->tx_queue_len = 100;	SET_MODULE_OWNER(dev);	/* FIXME Why are we doing this */	set_chan_state(dev, WAN_DISCONNECTED);	return 0;}/*=================================================================== * Name:	if_open(),   Open/Bring up the Netowrk Interface  * * Purpose:	To bring up a network interface. *  * Rationale:	 *                 * Description:	Open network interface. * 		o prevent module from unloading by incrementing use count * 		o if link is disconnected then initiate connection * * Called by:	Kernel (/usr/src/linux/net/core/dev.c) * 		(dev->open()) * * Assumptions: None *	 * Warnings:	None * * Return: 	0 	Ok * 		<0 	Failure: Interface will not come up. */static int if_open(struct net_device* dev){	x25_channel_t* chan = dev->priv;	sdla_t* card = chan->card;	struct timeval tv;	unsigned long smp_flags;		if (netif_running(dev))		return -EBUSY;	chan->tq_working = 0;	/* Initialize the workqueue */	INIT_WORK(&chan->common.wanpipe_work, (void *)x25api_bh, dev);	/* Allocate and initialize BH circular buffer */	/* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */	chan->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC);	if (chan->bh_head == NULL){		printk(KERN_INFO "%s: ERROR, failed to allocate memory ! BH_BUFFERS !\n",				card->devname);		return -ENOBUFS;	}	memset(chan->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1)));	atomic_set(&chan->bh_buff_used, 0);	/* Increment the number of interfaces */	++card->u.x.no_dev;		wanpipe_open(card);	/* LAPB protocol only uses one interface, thus	 * start the protocol after it comes up. */	if (card->u.x.LAPB_hdlc){		if (card->open_cnt == 1){			TX25Status* status = card->flags;			S508_S514_lock(card, &smp_flags);			x25_set_intr_mode(card, INTR_ON_TIMER); 			status->imask &= ~INTR_ON_TIMER;			S508_S514_unlock(card, &smp_flags);		}	}else{		/* X25 can have multiple interfaces thus, start the 		 * protocol once all interfaces are up */		//FIXME: There is a bug here. If interface is		//brought down and up, it will try to enable comm.		if (card->open_cnt == card->u.x.num_of_ch){			S508_S514_lock(card, &smp_flags);			connect(card);			S508_S514_unlock(card, &smp_flags);			mod_timer(&card->u.x.x25_timer, jiffies + HZ);		}	}	/* Device is not up until the we are in connected state */	do_gettimeofday( &tv );	chan->router_start_time = tv.tv_sec;	netif_start_queue(dev);	return 0;}/*=================================================================== * Name:	if_close(),   Close/Bring down the Netowrk Interface  * * Purpose:	To bring down a network interface. *  * Rationale:	 *                 * Description:	Close network interface. * 		o decrement use module use count * * Called by:	Kernel (/usr/src/linux/net/core/dev.c) * 		(dev->close()) *		ifconfig <name> down: will trigger the kernel *              which will call this function. * * Assumptions: None *	 * Warnings:	None * * Return: 	0 	Ok * 		<0 	Failure: Interface will not exit properly. */static int if_close(struct net_device* dev){	x25_channel_t* chan = dev->priv;	sdla_t* card = chan->card;	unsigned long smp_flags;		netif_stop_queue(dev);	if ((chan->common.state == WAN_CONNECTED) || 	    (chan->common.state == WAN_CONNECTING)){		S508_S514_lock(card, &smp_flags);		chan_disc(dev);		S508_S514_unlock(card, &smp_flags);	}	wanpipe_close(card);	S508_S514_lock(card, &smp_flags);	if (chan->bh_head){		int i;		struct sk_buff *skb;			for (i=0; i<(MAX_BH_BUFF+1); i++){			skb = ((bh_data_t *)&chan->bh_head[i])->skb;			if (skb != NULL){                		dev_kfree_skb_any(skb);			}		}		kfree(chan->bh_head);		chan->bh_head=NULL;	}	S508_S514_unlock(card, &smp_flags);	/* If this is the last close, disconnect physical link */	if (!card->open_cnt){		S508_S514_lock(card, &smp_flags);		disconnect(card);		x25_set_intr_mode(card, 0);		S508_S514_unlock(card, &smp_flags);	}		/* Decrement the number of interfaces */	--card->u.x.no_dev;	return 0;}

⌨️ 快捷键说明

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