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

📄 sdla_x25.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************** sdla_x25.c	WANPIPE(tm) Multiprotocol WAN Link Driver.  X.25 module.** Author:	Gene Kozin	<genek@compuserve.com>** Copyright:	(c) 1995-1997 Sangoma Technologies Inc.**		This program is free software; you can redistribute it and/or*		modify it under the terms of the GNU General Public License*		as published by the Free Software Foundation; either version*		2 of the License, or (at your option) any later version.* ============================================================================* Mar 15, 1998  Alan Cox	 o 2.1.x porting* Nov 27, 1997	Jaspreet Singh	 o Added protection against enabling of irqs*				   when they are disabled.* Nov 17, 1997  Farhan Thawar    o Added IPX support*				 o Changed if_send() to now buffer packets when*				   the board is busy*				 o Removed queueing of packets via the polling*				   routing*				 o Changed if_send() critical flags to properly*				   handle race conditions* Nov 06, 1997  Farhan Thawar    o Added support for SVC timeouts*				 o Changed PVC encapsulation to ETH_P_IP* Jul 21, 1997  Jaspreet Singh	 o Fixed freeing up of buffers using kfree()*				   when packets are received.* Mar 11, 1997  Farhan Thawar   Version 3.1.1*                                o added support for V35*                                o changed if_send() to return 0 if*                                  wandev.critical() is true*                                o free socket buffer in if_send() if*                                  returning 0*                                o added support for single '@' address to*                                  accept all incoming calls*                                o fixed bug in set_chan_state() to disconnect* Jan 15, 1997	Gene Kozin	Version 3.1.0*				 o implemented exec() entry point* Jan 07, 1997	Gene Kozin	Initial version.*****************************************************************************/#include <linux/kernel.h>	/* printk(), and other useful stuff */#include <linux/stddef.h>	/* offsetof(), etc. */#include <linux/errno.h>	/* return codes */#include <linux/string.h>	/* inline memset(), etc. */#include <linux/malloc.h>	/* kmalloc(), kfree() */#include <linux/wanrouter.h>	/* WAN router definitions */#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */#include <asm/byteorder.h>	/* htons(), etc. */#include <asm/uaccess.h>#define	_GNUC_#include <linux/sdla_x25.h>	/* X.25 firmware API definitions *//****** Defines & Macros ****************************************************/#define	CMD_OK		0		/* normal firmware return code */#define	CMD_TIMEOUT	0xFF		/* firmware command timed out */#define	MAX_CMD_RETRY	10		/* max number of firmware retries */#define	X25_CHAN_MTU	4096		/* unfragmented logical channel MTU */#define	X25_HRDHDR_SZ	7		/* max encapsulation header size */#define	X25_CONCT_TMOUT	(90*HZ)		/* link connection timeout */#define	X25_RECON_TMOUT	(10*HZ)		/* link connection timeout */#define	CONNECT_TIMEOUT	(90*HZ)		/* link connection timeout */#define	HOLD_DOWN_TIME	(30*HZ)		/* link hold down time *//* For IPXWAN */#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b)))/****** Data Structures *****************************************************//* This is an extention of the 'struct device' we create for each network * interface to keep the rest of X.25 channel-specific data. */typedef struct x25_channel{	char name[WAN_IFNAME_SZ+1];	/* interface name, ASCIIZ */	char addr[WAN_ADDRESS_SZ+1];	/* media address, ASCIIZ */	unsigned lcn;			/* logical channel number */	unsigned tx_pkt_size;	unsigned short protocol;	/* ethertype, 0 - multiplexed */	char svc;			/* 0 - permanent, 1 - switched */	char state;			/* channel state */	char drop_sequence;		/* mark sequence for dropping */	unsigned long state_tick;	/* time of the last state change */	unsigned idle_timeout;		/* sec, before disconnecting */	unsigned long i_timeout_sofar;  /* # of sec's we've been idle */	unsigned hold_timeout;		/* sec, before re-connecting */	unsigned long tick_counter;	/* counter for transmit time out */	char devtint;			/* Weather we should dev_tint() */	struct sk_buff* rx_skb;		/* receive socket buffer */	struct sk_buff* tx_skb;		/* transmit socket buffer */	sdla_t* card;			/* -> owner */	int ch_idx;	struct net_device_stats ifstats;	/* interface statistics */} x25_channel_t;typedef struct x25_call_info{	char dest[17];			/* ASCIIZ destination address */	char src[17];			/* ASCIIZ source address */	char nuser;			/* number of user data bytes */	unsigned char user[127];	/* user data */	char nfacil;			/* number of facilities */	struct	{		unsigned char code;		unsigned char parm;	} facil[64];			/* facilities */} x25_call_info_t;/****** Function Prototypes *************************************************//* WAN link driver entry points. These are called by the WAN router module. */static int update (wan_device_t* wandev);static int new_if (wan_device_t* wandev, struct device* dev,	wanif_conf_t* conf);static int del_if (wan_device_t* wandev, struct device* dev);/* WANPIPE-specific entry points */static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data);/* Network device interface */static int if_init   (struct device* dev);static int if_open   (struct device* dev);static int if_close  (struct device* dev);static int if_header (struct sk_buff* skb, struct device* dev,	unsigned short type, void* daddr, void* saddr, unsigned len);static int if_rebuild_hdr (struct sk_buff* skb);static int if_send (struct sk_buff* skb, struct device* dev);static struct net_device_stats * if_stats (struct device* dev);/* Interrupt handlers */static void wpx_isr	(sdla_t* card);static void rx_intr	(sdla_t* card);static void tx_intr	(sdla_t* card);static void status_intr	(sdla_t* card);static void event_intr	(sdla_t* card);static void spur_intr	(sdla_t* card);/* Background polling routines */static void wpx_poll (sdla_t* card);static void poll_disconnected (sdla_t* card);static void poll_connecting (sdla_t* card);static void poll_active (sdla_t* card);/* X.25 firmware interface functions */static int x25_get_version (sdla_t* card, char* str);static int x25_configure (sdla_t* card, TX25Config* conf);static int x25_get_err_stats (sdla_t* card);static int x25_get_stats (sdla_t* card);static int x25_set_intr_mode (sdla_t* card, int mode);static int x25_close_hdlc (sdla_t* card);static int x25_open_hdlc (sdla_t* card);static int x25_setup_hdlc (sdla_t* card);static int x25_set_dtr (sdla_t* card, int dtr);static int x25_get_chan_conf (sdla_t* card, x25_channel_t* chan);static int x25_place_call (sdla_t* card, x25_channel_t* chan);static int x25_accept_call (sdla_t* card, int lcn, int qdm);static int x25_clear_call (sdla_t* card, int lcn, int cause, int diagn);static int x25_send (sdla_t* card, int lcn, int qdm, int len, void* buf);static int x25_fetch_events (sdla_t* card);static int x25_error (sdla_t* card, int err, int cmd, int lcn);/* X.25 asynchronous event handlers */static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb);static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb);static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb);static int timeout_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb);static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb);/* Miscellaneous functions */static int connect (sdla_t* card);static int disconnect (sdla_t* card);static struct device* get_dev_by_lcn(wan_device_t* wandev, unsigned lcn);static int chan_connect (struct device* dev);static int chan_disc (struct device* dev);static void set_chan_state (struct device* dev, int state);static int chan_send (struct device* dev, struct sk_buff* skb);static unsigned char bps_to_speed_code (unsigned long bps);static unsigned int dec_to_uint (unsigned char* str, int len);static unsigned int hex_to_uint (unsigned char* str, int len);static void parse_call_info (unsigned char* str, x25_call_info_t* info);/* IPX functions */static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming);static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto);extern void disable_irq(unsigned int);extern void enable_irq(unsigned int);/****** Global Data ********************************************************** * Note: All data must be explicitly initialized!!! *//****** Public Functions ****************************************************//*============================================================================ * X.25 Protocol Initialization routine. * * This routine is called by the main WANPIPE module during setup.  At this * point adapter is completely initialized and X.25 firmware is running. *  o read firmware version (to make sure it's alive) *  o configure adapter *  o initialize protocol-specific fields of the adapter data space. * * Return:	0	o.k. *		< 0	failure. */int wpx_init (sdla_t* card, wandev_conf_t* conf){	union	{		char str[80];		TX25Config cfg;	} u;	/* Verify configuration ID */	if (conf->config_id != WANCONFIG_X25)	{		printk(KERN_INFO "%s: invalid configuration ID %u!\n",			card->devname, conf->config_id)		;		return -EINVAL;	}	/* Initialize protocol-specific fields */	card->mbox  = (void*)(card->hw.dpmbase + X25_MBOX_OFFS);	card->rxmb  = (void*)(card->hw.dpmbase + X25_RXMBOX_OFFS);	card->flags = (void*)(card->hw.dpmbase + X25_STATUS_OFFS);	/* Read firmware version.  Note that when adapter initializes, it	 * clears the mailbox, so it may appear that the first command was	 * executed successfully when in fact it was merely erased. To work	 * around this, we execute the first command twice.	 */	if (x25_get_version(card, NULL) || x25_get_version(card, u.str))		return -EIO	;	printk(KERN_INFO "%s: running X.25 firmware v%s\n",		card->devname, u.str)	;	/* Configure adapter. Here we set resonable defaults, then parse	 * device configuration structure and set configuration options.	 * Most configuration options are verified and corrected (if	 * necessary) since we can't rely on the adapter to do so and don't	 * want it to fail either.	 */	memset(&u.cfg, 0, sizeof(u.cfg));	u.cfg.t1		= 3;	u.cfg.n2		= 10;	u.cfg.autoHdlc		= 1;		/* automatic HDLC connection */	u.cfg.hdlcWindow	= 7;	u.cfg.pktWindow		= 2;	u.cfg.station		= 1;		/* DTE */	u.cfg.options		= 0x00B0;	/* disable D-bit pragmatics */	u.cfg.ccittCompat	= 1988;	u.cfg.t10t20		= 30;	u.cfg.t11t21		= 30;	u.cfg.t12t22		= 30;	u.cfg.t13t23		= 30;	u.cfg.t16t26		= 30;	u.cfg.t28		= 30;	u.cfg.r10r20		= 5;	u.cfg.r12r22		= 5;	u.cfg.r13r23		= 5;	u.cfg.responseOpt	= 1;		/* RR's after every packet */	if (conf->clocking != WANOPT_EXTERNAL)		u.cfg.baudRate = bps_to_speed_code(conf->bps)	;	if (conf->station != WANOPT_DTE)	{		u.cfg.station = 0;		/* DCE mode */	}        if (conf->interface != WANOPT_RS232 ) {	        u.cfg.hdlcOptions |= 0x80;      /* V35 mode */	} 	/* adjust MTU */	if (!conf->mtu || (conf->mtu >= 1024))		card->wandev.mtu = 1024	;	else if (conf->mtu >= 512)		card->wandev.mtu = 512	;	else if (conf->mtu >= 256)		card->wandev.mtu = 256	;	else if (conf->mtu >= 128)		card->wandev.mtu = 128	;	else card->wandev.mtu = 64;	u.cfg.defPktSize = u.cfg.pktMTU = card->wandev.mtu;	if (conf->u.x25.hi_pvc)	{		card->u.x.hi_pvc = min(conf->u.x25.hi_pvc, 4095);		card->u.x.lo_pvc = min(conf->u.x25.lo_pvc, card->u.x.hi_pvc);	}	if (conf->u.x25.hi_svc)	{		card->u.x.hi_svc = min(conf->u.x25.hi_svc, 4095);		card->u.x.lo_svc = min(conf->u.x25.lo_svc, card->u.x.hi_svc);	}	u.cfg.loPVC	  = card->u.x.lo_pvc;	u.cfg.hiPVC	  = card->u.x.hi_pvc;	u.cfg.loTwoWaySVC = card->u.x.lo_svc;	u.cfg.hiTwoWaySVC = card->u.x.hi_svc;	if (conf->u.x25.hdlc_window)		u.cfg.hdlcWindow = min(conf->u.x25.hdlc_window, 7)	;	if (conf->u.x25.pkt_window)		u.cfg.pktWindow = min(conf->u.x25.pkt_window, 7)	;	if (conf->u.x25.t1)		u.cfg.t1 = min(conf->u.x25.t1, 30)	;	u.cfg.t2 = min(conf->u.x25.t2, 29);	u.cfg.t4 = min(conf->u.x25.t4, 240);	if (conf->u.x25.n2)		u.cfg.n2 = min(conf->u.x25.n2, 30)	;	if (conf->u.x25.ccitt_compat)		u.cfg.ccittCompat = conf->u.x25.ccitt_compat	;	/* initialize adapter */	if ((x25_configure(card, &u.cfg) != CMD_OK) ||	    (x25_close_hdlc(card) != CMD_OK) ||		/* close HDLC link */	    (x25_set_dtr(card, 0) != CMD_OK))		/* drop DTR */		return -EIO	;	/* Initialize protocol-specific fields of adapter data space */	card->wandev.bps	= conf->bps;	card->wandev.interface	= conf->interface;	card->wandev.clocking	= conf->clocking;	card->wandev.station	= conf->station;	card->isr		= &wpx_isr;	card->poll		= &wpx_poll;	card->exec		= &wpx_exec;	card->wandev.update	= &update;	card->wandev.new_if	= &new_if;	card->wandev.del_if	= &del_if;	card->wandev.state	= WAN_DISCONNECTED;	card->wandev.enable_tx_int = 0;	card->irq_dis_if_send_count = 0;        card->irq_dis_poll_count = 0;	card->wandev.enable_IPX = conf->enable_IPX;		if (conf->network_number)		card->wandev.network_number = conf->network_number;	else		card->wandev.network_number = 0xDEADBEEF;	return 0;}/******* WAN Device Driver Entry Points *************************************//*============================================================================ * Update device status & statistics. */static int update (wan_device_t* wandev){	sdla_t* card;	/* sanity checks */	if ((wandev == NULL) || (wandev->private == NULL))		return -EFAULT;	if (wandev->state == WAN_UNCONFIGURED)		return -ENODEV;	if (test_and_set_bit(0, (void*)&wandev->critical))		return -EAGAIN;	card = wandev->private;	x25_get_err_stats(card);	x25_get_stats(card);	wandev->critical = 0;	return 0;}/*============================================================================ * Create new logical channel. * This routine is called by the router when ROUTER_IFNEW IOCTL is being * handled. * o parse media- and hardware-specific configuration * o make sure that a new channel can be created * o allocate resources, if necessary * o prepare network device structure for registaration. * * Return:	0	o.k. *		< 0	failure (channel will not be created) */static int new_if (wan_device_t* wandev, struct 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;	}	/* allocate and initialize private data */	chan = kmalloc(sizeof(x25_channel_t), GFP_KERNEL);	if (chan == NULL)		return -ENOMEM	;	memset(chan, 0, sizeof(x25_channel_t));	strcpy(chan->name, conf->name);	chan->card = card;	chan->protocol = ETH_P_IP;	chan->tx_skb = chan->rx_skb = NULL;	/* verify media address */	if (conf->addr[0] == '@')		/* SVC */	{		chan->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 (is_digit(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))		{			chan->lcn = 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 (err)	{		kfree(chan);		return err;	}	/* prepare network device data space for registration */	dev->name = chan->name;	dev->init = &if_init;	dev->priv = chan;	return 0;}/*============================================================================ * Delete logical channel.

⌨️ 快捷键说明

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